) {
return (
-
-
+
+
Available checks
{lints.map((lint) => (
@@ -58,12 +65,12 @@ export default function DatabaseAdvisorDocs({
label={capitalize(getBasename(lint.path).replace(/_/g, ' '))}
>
))}
-
+
)
}
@@ -101,42 +108,11 @@ const urlTransform: (lints: Array<{ path: string }>) => UrlTransformFunction = (
}
}
-const transformMarkdown = async (
- rawContent: string,
- { replacementLinks = [] }: { replacementLinks?: Array<{ path: string }> } = {}
-) => {
- const codeHikeOptions: CodeHikeConfig = {
- theme: codeHikeTheme,
- lineNumbers: true,
- showCopyButton: true,
- skipLanguages: [],
- autoImport: false,
- }
-
- const content = await serialize(rawContent, {
- scope: {
- chCodeConfig: codeHikeOptions,
- },
- mdxOptions: {
- remarkPlugins: [
- remarkGfm,
- remarkMkDocsAdmonition,
- remarkPyMdownTabs,
- [removeTitle, meta.title],
- [remarkCodeHike, codeHikeOptions],
- ],
- rehypePlugins: [[linkTransform, urlTransform(replacementLinks)], rehypeSlug],
- },
- })
-
- return content
-}
-
/**
- * Fetch markdown from external repo and transform links
+ * Fetch lint remediation Markdown from external repo
*/
-export const getStaticProps = (async () => {
- const octokit = new Octokit()
+const getLints = async () => {
+ const octokit = new Octokit({ request: { fetch: fetchRevalidatePerDay } })
const response = await octokit.request('GET /repos/{owner}/{repo}/contents/{path}', {
owner: org,
@@ -154,37 +130,33 @@ export const getStaticProps = (async () => {
if (!Array.isArray(response.data)) {
throw Error(
- `Reading a directory, not a file. Should not reach this, solely to appease Typescript.`
+ 'Reading a directory, not a file. Should not reach this, solely to appease Typescript.'
)
}
- const [intro, ...lints] = await Promise.all([
- await transformMarkdown(markdownIntro),
- ...response.data
- .filter(({ path }) => /docs\/\d+.+\.md$/.test(path))
- .map(async ({ path }, _, data) => {
- const fileResponse = await fetch(
- `https://raw.githubusercontent.com/${org}/${repo}/${branch}/${path}`
- )
+ const lintsList = response.data.filter(({ path }) => /docs\/\d+.+\.md$/.test(path))
- if (fileResponse.status >= 400) {
- throw Error(`Could not get contents of file ${org}/${repo}/${path}`)
- }
+ const lints = await Promise.all(
+ lintsList.map(async ({ path }) => {
+ const fileResponse = await fetchRevalidatePerDay(
+ `https://raw.githubusercontent.com/${org}/${repo}/${branch}/${path}`
+ )
- const rawContent = await fileResponse.text()
- const content = await transformMarkdown(rawContent, { replacementLinks: data })
+ if (fileResponse.status >= 400) {
+ throw Error(`Could not get contents of file ${org}/${repo}/${path}`)
+ }
- return {
- path: getBasename(path),
- content,
- }
- }),
- ])
+ const content = await fileResponse.text()
- return {
- props: {
- intro,
- lints,
- },
- }
-}) satisfies GetStaticProps
+ return {
+ path: getBasename(path),
+ content,
+ }
+ })
+ )
+
+ return { lints, lintsList }
+}
+
+export default DatabaseAdvisorDocs
+export { generateMetadata }
diff --git a/apps/docs/app/guides/database/extensions/wrappers/[[...slug]]/page.tsx b/apps/docs/app/guides/database/extensions/wrappers/[[...slug]]/page.tsx
new file mode 100644
index 00000000000..836657bce71
--- /dev/null
+++ b/apps/docs/app/guides/database/extensions/wrappers/[[...slug]]/page.tsx
@@ -0,0 +1,222 @@
+import matter from 'gray-matter'
+import { type SerializeOptions } from 'next-mdx-remote/dist/types'
+import { readFile } from 'node:fs/promises'
+import { join, relative } from 'node:path'
+import rehypeSlug from 'rehype-slug'
+import emoji from 'remark-emoji'
+
+import { genGuideMeta, genGuidesStaticParams } from '~/features/docs/GuidesMdx.utils'
+import { GuideTemplate, newEditLink } from '~/features/docs/GuidesMdx.template'
+import { fetchRevalidatePerDay } from '~/features/helpers.fetch'
+import { GUIDES_DIRECTORY, isValidGuideFrontmatter } from '~/lib/docs'
+import { UrlTransformFunction, linkTransform } from '~/lib/mdx/plugins/rehypeLinkTransform'
+import remarkMkDocsAdmonition from '~/lib/mdx/plugins/remarkAdmonition'
+import { removeTitle } from '~/lib/mdx/plugins/remarkRemoveTitle'
+import remarkPyMdownTabs from '~/lib/mdx/plugins/remarkTabs'
+
+// We fetch these docs at build time from an external repo
+const org = 'supabase'
+const repo = 'wrappers'
+const branch = 'main'
+const docsDir = 'docs'
+const externalSite = 'https://supabase.github.io/wrappers'
+
+// Each external docs page is mapped to a local page
+const pageMap = [
+ {
+ slug: 'airtable',
+ meta: {
+ title: 'Airtable',
+ },
+ remoteFile: 'airtable.md',
+ },
+ {
+ slug: 'auth0',
+ meta: {
+ title: 'Auth0',
+ },
+ remoteFile: 'auth0.md',
+ },
+ {
+ slug: 'bigquery',
+ meta: {
+ title: 'BigQuery',
+ },
+ remoteFile: 'bigquery.md',
+ },
+ {
+ slug: 'clickhouse',
+ meta: {
+ title: 'ClickHouse',
+ },
+ remoteFile: 'clickhouse.md',
+ },
+ {
+ slug: 'cognito',
+ meta: {
+ title: 'AWS Cognito',
+ },
+ remoteFile: 'cognito.md',
+ },
+ {
+ slug: 'firebase',
+ meta: {
+ title: 'Firebase',
+ },
+ remoteFile: 'firebase.md',
+ },
+ {
+ slug: 'logflare',
+ meta: {
+ title: 'Logflare',
+ },
+ remoteFile: 'logflare.md',
+ },
+ {
+ slug: 'mssql',
+ meta: {
+ title: 'MSSQL',
+ },
+ remoteFile: 'mssql.md',
+ },
+ {
+ slug: 'redis',
+ meta: {
+ title: 'Redis',
+ },
+ remoteFile: 'redis.md',
+ },
+ {
+ slug: 's3',
+ meta: {
+ title: 'AWS S3',
+ },
+ remoteFile: 's3.md',
+ },
+ {
+ slug: 'stripe',
+ meta: {
+ title: 'Stripe',
+ },
+ remoteFile: 'stripe.md',
+ },
+]
+
+interface Params {
+ slug?: string[]
+}
+
+const WrappersDocs = async ({ params }: { params: Params }) => {
+ const { isExternal, meta, ...data } = await getContent(params)
+
+ const options = isExternal
+ ? ({
+ mdxOptions: {
+ remarkPlugins: [
+ remarkMkDocsAdmonition,
+ emoji,
+ remarkPyMdownTabs,
+ [removeTitle, meta.title],
+ ],
+ rehypePlugins: [[linkTransform, urlTransform], rehypeSlug],
+ },
+ } as SerializeOptions)
+ : undefined
+
+ return
+}
+
+/**
+ * Fetch markdown from external repo
+ */
+const getContent = async (params: Params) => {
+ const federatedPage = pageMap.find(
+ ({ slug }) => params && slug && params.slug && slug === params.slug.at(0)
+ )
+
+ let isExternal: boolean
+ let meta: any
+ let content: string
+ let editLink: string
+
+ if (!federatedPage) {
+ isExternal = false
+ editLink = `supabase/supabase/apps/docs/content/guides/database/extensions/wrappers${params.slug?.length ? `/${params.slug.join('/')}` : ''}.mdx`
+ const rawContent = await readFile(
+ join(
+ GUIDES_DIRECTORY,
+ 'database',
+ 'extensions',
+ `wrappers${params.slug?.length ? `/${params.slug.join('/')}` : ''}.mdx`
+ ),
+ 'utf-8'
+ )
+ ;({ data: meta, content } = matter(rawContent))
+ if (!isValidGuideFrontmatter(meta)) {
+ throw Error(`Expected valid frontmatter, got ${JSON.stringify(meta, null, 2)}`)
+ }
+ } else {
+ isExternal = true
+ let remoteFile: string
+ ;({ remoteFile, meta } = federatedPage)
+ const repoPath = `${org}/${repo}/${branch}/${docsDir}/${remoteFile}`
+ editLink = `${org}/${repo}/blob/${branch}/${docsDir}/${remoteFile}`
+ const response = await fetchRevalidatePerDay(`https://raw.githubusercontent.com/${repoPath}`)
+ content = await response.text()
+ }
+
+ return {
+ pathname:
+ `/guides/database/extensions/wrappers${params.slug?.length ? `/${params.slug.join('/')}` : ''}` satisfies `/${string}`,
+ isExternal,
+ editLink: newEditLink(editLink),
+ meta,
+ content,
+ }
+}
+
+const urlTransform: UrlTransformFunction = (url) => {
+ try {
+ const externalSiteUrl = new URL(externalSite)
+
+ const placeholderHostname = 'placeholder'
+ const { hostname, pathname, hash } = new URL(url, `http://${placeholderHostname}`)
+
+ // Don't modify a url with a FQDN or a url that's only a hash
+ if (hostname !== placeholderHostname || pathname === '/') {
+ return url
+ }
+ const relativePage = (
+ pathname.endsWith('.md')
+ ? pathname.replace(/\.md$/, '')
+ : relative(externalSiteUrl.pathname, pathname)
+ ).replace(/^\//, '')
+
+ const page = pageMap.find(({ remoteFile }) => `${relativePage}.md` === remoteFile)
+
+ // If we have a mapping for this page, use the mapped path
+ if (page) {
+ return page.slug + hash
+ }
+
+ // If we don't have this page in our docs, link to original docs
+ return `${externalSite}/${relativePage}${hash}`
+ } catch (err) {
+ console.error('Error transforming markdown URL', err)
+ return url
+ }
+}
+
+const generateStaticParams = async () => {
+ const mdxPaths = await genGuidesStaticParams('database/extensions/wrappers')()
+ const federatedPaths = pageMap.map(({ slug }) => ({
+ slug: [slug],
+ }))
+
+ return [...mdxPaths, ...federatedPaths]
+}
+
+const generateMetadata = genGuideMeta(getContent)
+
+export default WrappersDocs
+export { generateStaticParams, generateMetadata }
diff --git a/apps/docs/app/guides/graphql/[[...slug]]/page.tsx b/apps/docs/app/guides/graphql/[[...slug]]/page.tsx
new file mode 100644
index 00000000000..0034e6beece
--- /dev/null
+++ b/apps/docs/app/guides/graphql/[[...slug]]/page.tsx
@@ -0,0 +1,194 @@
+import { type SerializeOptions } from 'next-mdx-remote/dist/types'
+import { redirect } from 'next/navigation'
+import { isAbsolute, relative } from 'path'
+import rehypeSlug from 'rehype-slug'
+
+import { genGuideMeta } from '~/features/docs/GuidesMdx.utils'
+import { GuideTemplate, newEditLink } from '~/features/docs/GuidesMdx.template'
+import { fetchRevalidatePerDay } from '~/features/helpers.fetch'
+import { notFoundLink } from '~/features/recommendations/NotFound.utils'
+import { UrlTransformFunction, linkTransform } from '~/lib/mdx/plugins/rehypeLinkTransform'
+import remarkMkDocsAdmonition from '~/lib/mdx/plugins/remarkAdmonition'
+import { removeTitle } from '~/lib/mdx/plugins/remarkRemoveTitle'
+import remarkPyMdownTabs from '~/lib/mdx/plugins/remarkTabs'
+
+// We fetch these docs at build time from an external repo
+const org = 'supabase'
+const repo = 'pg_graphql'
+const branch = 'master'
+const docsDir = 'docs'
+const externalSite = 'https://supabase.github.io/pg_graphql'
+
+// Each external docs page is mapped to a local page
+const pageMap = [
+ {
+ meta: {
+ id: 'graphql-overview',
+ title: 'GraphQL',
+ subtitle: 'Autogenerated GraphQL APIs with Postgres.',
+ },
+ remoteFile: 'supabase.md',
+ },
+ {
+ slug: 'api',
+ meta: {
+ id: 'graphql-api',
+ title: 'GraphQL API',
+ subtitle: 'Understanding the core concepts of the GraphQL API.',
+ },
+ remoteFile: 'api.md',
+ },
+ {
+ slug: 'views',
+ meta: {
+ id: 'graphql-views',
+ title: 'Views',
+ subtitle: 'Using Postgres Views with GraphQL.',
+ },
+ remoteFile: 'views.md',
+ },
+ {
+ slug: 'functions',
+ meta: {
+ id: 'graphql-functions',
+ title: 'Functions',
+ subtitle: 'Using Postgres Functions with GraphQL.',
+ },
+ remoteFile: 'functions.md',
+ },
+ {
+ slug: 'computed-fields',
+ meta: {
+ id: 'graphql-computed-fields',
+ title: 'Computed Fields',
+ subtitle: 'Using Postgres Computed Fields with GraphQL.',
+ },
+ remoteFile: 'computed-fields.md',
+ },
+ {
+ slug: 'configuration',
+ meta: {
+ id: 'graphql-configuration',
+ title: 'Configuration & Customization',
+ subtitle: 'Extra configuration options can be set on SQL entities using comment directives.',
+ },
+ remoteFile: 'configuration.md',
+ },
+ {
+ slug: 'security',
+ meta: {
+ id: 'graphql-security',
+ title: 'Security',
+ subtitle: 'Securing your GraphQL API.',
+ },
+ remoteFile: 'security.md',
+ },
+ {
+ slug: 'with-apollo',
+ meta: {
+ id: 'graphql-with-apollo',
+ title: 'With Apollo',
+ subtitle: 'Using pg_grapqhl with Apollo.',
+ },
+ remoteFile: 'usage_with_apollo.md',
+ },
+ {
+ slug: 'with-relay',
+ meta: {
+ id: 'graphql-with-relay',
+ title: 'With Relay',
+ subtitle: 'Using pg_grapqhl with Relay.',
+ },
+ remoteFile: 'usage_with_relay.md',
+ },
+]
+
+interface Params {
+ slug?: string[]
+}
+
+const PGGraphQLDocs = async ({ params }: { params: Params }) => {
+ const { meta, ...data } = await getContent(params)
+
+ const options = {
+ mdxOptions: {
+ remarkPlugins: [remarkMkDocsAdmonition, remarkPyMdownTabs, [removeTitle, meta.title]],
+ rehypePlugins: [[linkTransform, urlTransform], rehypeSlug],
+ },
+ } as SerializeOptions
+
+ return
+}
+
+/**
+ * Fetch markdown from external repo and transform links
+ */
+const getContent = async ({ slug }: Params) => {
+ const page = pageMap.find((page) => page.slug === slug?.at(0))
+
+ if (!page) {
+ redirect(notFoundLink(`graphql/${slug ? slug.join('/') : ''}`))
+ }
+
+ const { remoteFile, meta } = page
+
+ const editLink = newEditLink(`${org}/${repo}/blob/${branch}/${docsDir}/${remoteFile}`)
+
+ const response = await fetchRevalidatePerDay(
+ `https://raw.githubusercontent.com/${org}/${repo}/${branch}/${docsDir}/${remoteFile}`
+ )
+
+ const content = await response.text()
+
+ return {
+ pathname: `/guides/graphql${slug?.length ? `/${slug.join('/')}` : ''}` satisfies `/${string}`,
+ meta,
+ content,
+ editLink,
+ }
+}
+
+const urlTransform: UrlTransformFunction = (url) => {
+ try {
+ const externalSiteUrl = new URL(externalSite)
+
+ const placeholderHostname = 'placeholder'
+ const { hostname, pathname, hash } = new URL(url, `http://${placeholderHostname}`)
+
+ // Don't modify a url with a FQDN or a url that's only a hash
+ if (hostname !== placeholderHostname || pathname === '/') {
+ return url
+ }
+
+ const getRelativePath = () => {
+ if (pathname.endsWith('.md')) {
+ return pathname.replace(/\.md$/, '')
+ }
+ if (isAbsolute(url)) {
+ return relative(externalSiteUrl.pathname, pathname)
+ }
+ return pathname
+ }
+
+ const relativePath = getRelativePath().replace(/^\//, '')
+
+ const page = pageMap.find(({ remoteFile }) => `${relativePath}.md` === remoteFile)
+
+ // If we have a mapping for this page, use the mapped path
+ if (page) {
+ return 'graphql/' + page.slug + hash
+ }
+
+ // If we don't have this page in our docs, link to original docs
+ return `${externalSite}/${relativePath}${hash}`
+ } catch (err) {
+ console.error('Error transforming markdown URL', err)
+ return url
+ }
+}
+
+const generateStaticParams = async () => pageMap.map(({ slug }) => ({ slug: slug ? [slug] : [] }))
+const generateMetadata = genGuideMeta(getContent)
+
+export default PGGraphQLDocs
+export { generateStaticParams, generateMetadata }
diff --git a/apps/docs/app/guides/layout.tsx b/apps/docs/app/guides/layout.tsx
new file mode 100644
index 00000000000..8df012ac97c
--- /dev/null
+++ b/apps/docs/app/guides/layout.tsx
@@ -0,0 +1,16 @@
+'use client'
+
+import { usePathname } from 'next/navigation'
+import { type PropsWithChildren } from 'react'
+
+import { getMenuId } from '~/components/Navigation/NavigationMenu/NavigationMenu.utils'
+import Layout from '~/layouts/guides'
+
+const GuidesLayout = ({ children }: PropsWithChildren) => {
+ const pathname = usePathname()
+ const menuId = getMenuId(pathname)
+
+ return {children}
+}
+
+export default GuidesLayout
diff --git a/apps/docs/app/guides/platform/terraform/[[...slug]]/page.tsx b/apps/docs/app/guides/platform/terraform/[[...slug]]/page.tsx
new file mode 100644
index 00000000000..f9cbcc62a0c
--- /dev/null
+++ b/apps/docs/app/guides/platform/terraform/[[...slug]]/page.tsx
@@ -0,0 +1,142 @@
+import matter from 'gray-matter'
+import { type SerializeOptions } from 'next-mdx-remote/dist/types'
+import { redirect } from 'next/navigation'
+import rehypeSlug from 'rehype-slug'
+import { genGuideMeta } from '~/features/docs/GuidesMdx.utils'
+import { GuideTemplate, newEditLink } from '~/features/docs/GuidesMdx.template'
+import { fetchRevalidatePerDay } from '~/features/helpers.fetch'
+import { notFoundLink } from '~/features/recommendations/NotFound.utils'
+import { isValidGuideFrontmatter } from '~/lib/docs'
+import { UrlTransformFunction, linkTransform } from '~/lib/mdx/plugins/rehypeLinkTransform'
+import remarkMkDocsAdmonition from '~/lib/mdx/plugins/remarkAdmonition'
+import { removeTitle } from '~/lib/mdx/plugins/remarkRemoveTitle'
+import remarkPyMdownTabs from '~/lib/mdx/plugins/remarkTabs'
+import {
+ terraformDocsBranch,
+ terraformDocsDocsDir,
+ terraformDocsOrg,
+ terraformDocsRepo,
+} from '../terraformConstants'
+
+// Each external docs page is mapped to a local page
+const pageMap = [
+ {
+ remoteFile: 'README.md',
+ meta: {
+ title: 'Terraform Provider',
+ },
+ useRoot: true,
+ },
+ {
+ slug: 'tutorial',
+ remoteFile: 'tutorial.md',
+ meta: {
+ title: 'Using the Supabase Terraform Provider',
+ },
+ },
+]
+
+interface Params {
+ slug?: string[]
+}
+
+const TerraformDocs = async ({ params }: { params: Params }) => {
+ const { meta, ...data } = await getContent(params)
+
+ const options = {
+ mdxOptions: {
+ remarkPlugins: [remarkMkDocsAdmonition, remarkPyMdownTabs, [removeTitle, meta.title]],
+ rehypePlugins: [[linkTransform, urlTransform], rehypeSlug],
+ },
+ } as SerializeOptions
+
+ return
+}
+
+/**
+ * The GitHub repo uses relative links, which don't lead to the right locations
+ * in docs.
+ *
+ * @param url The original link, as written in the Markdown file
+ * @returns The rewritten link
+ */
+const urlTransform: UrlTransformFunction = (url: string) => {
+ try {
+ const placeholderHostname = 'placeholder'
+ const { hostname, pathname, hash } = new URL(url, `http://${placeholderHostname}`)
+
+ // Don't modify a url with a FQDN or a url that's only a hash
+ if (hostname !== placeholderHostname || pathname === '/') {
+ return url
+ }
+
+ const getBasename = (pathname: string) =>
+ pathname.endsWith('.md') ? pathname.replace(/\.md$/, '') : pathname
+ const stripLeadingPrefix = (pathname: string) => pathname.replace(/^\//, '')
+ const stripLeadingDocs = (pathname: string) => pathname.replace(/^docs\//, '')
+
+ const relativePath = stripLeadingPrefix(getBasename(pathname))
+
+ const page = pageMap.find(
+ ({ remoteFile, useRoot }) =>
+ (useRoot && `${relativePath}.md` === remoteFile) ||
+ (!useRoot && `${stripLeadingDocs(relativePath)}.md` === remoteFile)
+ )
+
+ if (page) {
+ return 'terraform' + `/${page.slug}` + hash
+ }
+
+ // If we don't have this page in our docs, link to GitHub repo
+ return `https://github.com/${terraformDocsOrg}/${terraformDocsRepo}/blob/${terraformDocsBranch}${pathname}${hash}`
+ } catch (err) {
+ console.error('Error transforming markdown URL', err)
+ return url
+ }
+}
+
+/**
+ * Fetch markdown from external repo
+ */
+const getContent = async ({ slug }: Params) => {
+ const [requestedSlug] = slug ?? []
+ const page = pageMap.find((page) => page.slug === requestedSlug)
+
+ if (!page) {
+ redirect(notFoundLink('platform/terraform' + (slug?.join('/') ?? '')))
+ }
+
+ const { meta, remoteFile, useRoot } = page
+
+ const editLink = newEditLink(
+ `${terraformDocsOrg}/${terraformDocsRepo}/blob/${terraformDocsBranch}/${useRoot ? '' : `${terraformDocsDocsDir}/`}${remoteFile}`
+ )
+
+ let response = await fetchRevalidatePerDay(
+ `https://raw.githubusercontent.com/${terraformDocsOrg}/${terraformDocsRepo}/${terraformDocsBranch}/${useRoot ? '' : `${terraformDocsDocsDir}/`}${remoteFile}`
+ )
+
+ let rawContent = await response.text()
+ // Strip out HTML comments
+ rawContent = rawContent.replace(//, '')
+ const { content, data } = matter(rawContent)
+ Object.assign(meta, data)
+
+ if (!isValidGuideFrontmatter(meta)) {
+ throw Error('Guide frontmatter is invalid.')
+ }
+
+ return {
+ pathname:
+ `/guides/platform/terraform${slug?.length ? `/${slug.join('/')}` : ''}` satisfies `/${string}`,
+ meta,
+ content,
+ editLink,
+ }
+}
+
+const generateStaticParams = async () => pageMap.map(({ slug }) => ({ slug: slug ? [slug] : [] }))
+const generateMetadata = genGuideMeta(getContent)
+
+export default TerraformDocs
+export { generateStaticParams, generateMetadata }
diff --git a/apps/docs/pages/guides/platform/terraform/reference.tsx b/apps/docs/app/guides/platform/terraform/reference/page.tsx
similarity index 88%
rename from apps/docs/pages/guides/platform/terraform/reference.tsx
rename to apps/docs/app/guides/platform/terraform/reference/page.tsx
index 8004ab606c9..c251d8133ea 100644
--- a/apps/docs/pages/guides/platform/terraform/reference.tsx
+++ b/apps/docs/app/guides/platform/terraform/reference/page.tsx
@@ -1,22 +1,36 @@
import { codeBlock } from 'common-tags'
-import { GetStaticProps, InferGetStaticPropsType } from 'next'
+import { Check, PlusCircle } from 'lucide-react'
import Link from 'next/link'
import ReactMarkdown from 'react-markdown'
import {
CodeBlock,
Heading,
- IconCheck,
- IconPlusCircle,
PopoverContent_Shadcn_,
PopoverTrigger_Shadcn_,
Popover_Shadcn_,
- Tabs,
} from 'ui'
-import { MenuId } from '~/components/Navigation/NavigationMenu/NavigationMenu'
-import Layout from '~/layouts/DefaultGuideLayout'
-import { org, repo, branch, docsDir } from './[[...slug]]'
+import { genGuideMeta } from '~/features/docs/GuidesMdx.utils'
+import { GuideTemplate, newEditLink } from '~/features/docs/GuidesMdx.template'
+import { fetchRevalidatePerDay } from '~/features/helpers.fetch'
+import { TabPanel, Tabs } from '~/features/ui/Tabs'
+import {
+ terraformDocsBranch,
+ terraformDocsDocsDir,
+ terraformDocsOrg,
+ terraformDocsRepo,
+} from '../terraformConstants'
+
+const meta = {
+ title: 'Terraform Provider reference',
+ subtitle: 'Resources and data sources available through the Terraform Provider',
+}
+
+const generateMetadata = genGuideMeta(() => ({
+ pathname: '/guides/platform/terraform/reference',
+ meta,
+}))
function ProviderSettings({ schema }: { schema: any }) {
const attributes = schema.block.attributes
@@ -63,7 +77,7 @@ function ProviderSettings({ schema }: { schema: any }) {
{attributes[attribute].optional && (
<>
-
+
true
>
)}
@@ -71,7 +85,7 @@ function ProviderSettings({ schema }: { schema: any }) {
{attributes[attribute].sensitive && (
<>
-
+
true
>
)}
@@ -92,7 +106,7 @@ function Resources({ schema }: { schema: any }) {
You can configure these resources using the Supabase Terraform provider:
{Object.keys(schema).map((resource) => (
-
+
Example usage
{codeBlock`
resource "${resource}" "" {
@@ -137,7 +151,7 @@ function Resources({ schema }: { schema: any }) {
Nested type
-
+
@@ -177,7 +191,7 @@ function Resources({ schema }: { schema: any }) {
{schema[resource].block.attributes[attribute].required && (
<>
-
+
true
>
)}
@@ -185,7 +199,7 @@ function Resources({ schema }: { schema: any }) {
{schema[resource].block.attributes[attribute].optional && (
<>
-
+
true
>
)}
@@ -193,7 +207,7 @@ function Resources({ schema }: { schema: any }) {
{schema[resource].block.attributes[attribute].computed && (
<>
-
+
true
>
)}
@@ -202,7 +216,7 @@ function Resources({ schema }: { schema: any }) {
))}
-
+
))}
@@ -216,7 +230,7 @@ function DataSources({ schema }: { schema: any }) {
You can read these resources using the Supabase Terraform provider:
{Object.keys(schema).map((dataSource) => (
-
+
Example usage
{codeBlock`
resource "${dataSource}" "all" {
@@ -263,7 +277,7 @@ function DataSources({ schema }: { schema: any }) {
Nested type
-
+
@@ -306,7 +320,7 @@ function DataSources({ schema }: { schema: any }) {
{schema[dataSource].block.attributes[attribute].required && (
<>
-
+
true
>
)}
@@ -314,7 +328,7 @@ function DataSources({ schema }: { schema: any }) {
{schema[dataSource].block.attributes[attribute].optional && (
<>
-
+
true
>
)}
@@ -322,7 +336,7 @@ function DataSources({ schema }: { schema: any }) {
{schema[dataSource].block.attributes[attribute].computed && (
<>
-
+
true
>
)}
@@ -331,19 +345,20 @@ function DataSources({ schema }: { schema: any }) {
))}
-
+
))}
)
}
-export default function PGGraphQLDocs({
- meta,
- schema,
-}: InferGetStaticPropsType) {
+const TerraformReferencePage = async () => {
+ const { schema } = await getSchema()
+
+ const editLink = newEditLink('supabase/terraform-provider-supabase')
+
return (
-
+
The Terraform Provider provices access to{' '}
-
+
)
}
/**
* Fetch JSON schema from external repo
*/
-export const getStaticProps = (async () => {
- const meta = {
- title: 'Terraform Provider reference',
- subtitle: 'Resources and data sources available through the Terraform Provider',
- }
-
- let response = await fetch(
- `https://raw.githubusercontent.com/${org}/${repo}/${branch}/${docsDir}/schema.json`
+const getSchema = async () => {
+ let response = await fetchRevalidatePerDay(
+ `https://raw.githubusercontent.com/${terraformDocsOrg}/${terraformDocsRepo}/${terraformDocsBranch}/${terraformDocsDocsDir}/schema.json`
)
if (!response.ok) throw Error('Failed to fetch Terraform JSON schema from GitHub')
const schema = await response.json()
return {
- props: {
- meta,
- schema,
- },
+ schema,
}
-}) satisfies GetStaticProps
+}
+
+export default TerraformReferencePage
+export { generateMetadata }
diff --git a/apps/docs/app/guides/platform/terraform/terraformConstants.ts b/apps/docs/app/guides/platform/terraform/terraformConstants.ts
new file mode 100644
index 00000000000..0cc7ad3125b
--- /dev/null
+++ b/apps/docs/app/guides/platform/terraform/terraformConstants.ts
@@ -0,0 +1,9 @@
+/**
+ * Information on where to fetch docs content
+ */
+const terraformDocsOrg = 'supabase'
+const terraformDocsRepo = 'terraform-provider-supabase'
+const terraformDocsBranch = 'v1.1.3'
+const terraformDocsDocsDir = 'docs'
+
+export { terraformDocsOrg, terraformDocsRepo, terraformDocsBranch, terraformDocsDocsDir }
diff --git a/apps/docs/app/guides/self-hosting/analytics/config/page.tsx b/apps/docs/app/guides/self-hosting/analytics/config/page.tsx
new file mode 100644
index 00000000000..d397c0003f0
--- /dev/null
+++ b/apps/docs/app/guides/self-hosting/analytics/config/page.tsx
@@ -0,0 +1,65 @@
+import Param from '~/components/Params'
+import { genGuideMeta } from '~/features/docs/GuidesMdx.utils'
+import { GuideTemplate, newEditLink } from '~/features/docs/GuidesMdx.template'
+import { MDXRemoteBase } from '~/features/docs/MdxBase'
+import specAnalyticsV0 from '~/spec/analytics_v0_config.yaml' assert { type: 'yml' }
+
+const meta = {
+ title: 'Analytics Self-hosting Config',
+ description: 'How to configure and deploy Supabase Analytics.',
+}
+
+const generateMetadata = genGuideMeta(() => ({
+ pathname: '/guides/self-hosting/analytics/config',
+ meta,
+}))
+
+const AnalyticsConfigPage = async () => {
+ const descriptionMdx = specAnalyticsV0.info.description
+
+ return (
+
+
+
+
+ {specAnalyticsV0.info.tags.map(
+ (tag: ReturnType
['info']['tags']) => {
+ return (
+ <>
+ {tag.title}
+ {tag.description}
+
+
Parameters
+
+ {specAnalyticsV0.parameters
+ .filter((param: ReturnType['parameters']) =>
+ param.tags.includes(tag.id)
+ )
+ .map((param: ReturnType['parameters']) => {
+ return (
+
+ )
+ })}
+
+
+ >
+ )
+ }
+ )}
+
+
+ )
+}
+
+export default AnalyticsConfigPage
+export { generateMetadata }
diff --git a/apps/docs/app/guides/self-hosting/auth/config/page.tsx b/apps/docs/app/guides/self-hosting/auth/config/page.tsx
new file mode 100644
index 00000000000..d8a33d04694
--- /dev/null
+++ b/apps/docs/app/guides/self-hosting/auth/config/page.tsx
@@ -0,0 +1,63 @@
+import Param from '~/components/Params'
+import { genGuideMeta } from '~/features/docs/GuidesMdx.utils'
+import { GuideTemplate, newEditLink } from '~/features/docs/GuidesMdx.template'
+import { MDXRemoteBase } from '~/features/docs/MdxBase'
+import specAuthV1 from '~/spec/gotrue_v1_config.yaml' assert { type: 'yml' }
+
+const meta = {
+ title: 'Auth Self-hosting Config',
+ description: 'How to configure and deploy Supabase Auth.',
+}
+
+const generateMetadata = genGuideMeta(() => ({
+ pathname: '/guides/self-hosting/auth/config',
+ meta,
+}))
+
+const AuthConfigPage = async () => {
+ const descriptionMdx = specAuthV1.info.description
+
+ return (
+
+
+
+
+ {specAuthV1.info.tags.map((tag: ReturnType
['info']['tags']) => {
+ return (
+ <>
+ {tag.title}
+ {tag.description}
+
+
Parameters
+
+ {specAuthV1.parameters
+ .filter((param: ReturnType['parameters']) =>
+ param.tags.includes(tag.id)
+ )
+ .map((param: ReturnType['parameters']) => {
+ return (
+
+ )
+ })}
+
+
+ >
+ )
+ })}
+
+
+ )
+}
+
+export default AuthConfigPage
+export { generateMetadata }
diff --git a/apps/docs/app/guides/self-hosting/realtime/config/page.tsx b/apps/docs/app/guides/self-hosting/realtime/config/page.tsx
new file mode 100644
index 00000000000..01180ba859c
--- /dev/null
+++ b/apps/docs/app/guides/self-hosting/realtime/config/page.tsx
@@ -0,0 +1,63 @@
+import Param from '~/components/Params'
+import { genGuideMeta } from '~/features/docs/GuidesMdx.utils'
+import { GuideTemplate, newEditLink } from '~/features/docs/GuidesMdx.template'
+import { MDXRemoteBase } from '~/features/docs/MdxBase'
+import specRealtimeV0 from '~/spec/realtime_v0_config.yaml' assert { type: 'yml' }
+
+const meta = {
+ title: 'Realtime Self-hosting Config',
+ description: 'How to configure and deploy Supabase Realtime.',
+}
+
+const generateMetadata = genGuideMeta(() => ({
+ pathname: '/guides/self-hosting/realtime/config',
+ meta,
+}))
+
+const RealtimeConfigPage = async () => {
+ const descriptionMdx = specRealtimeV0.info.description
+
+ return (
+
+
+
+
+ {specRealtimeV0.info.tags.map((tag: ReturnType
['info']['tags']) => {
+ return (
+ <>
+ {tag.title}
+ {tag.description}
+
+
Parameters
+
+ {specRealtimeV0.parameters
+ .filter((param: ReturnType['parameters']) =>
+ param.tags.includes(tag.id)
+ )
+ .map((param: ReturnType['parameters']) => {
+ return (
+
+ )
+ })}
+
+
+ >
+ )
+ })}
+
+
+ )
+}
+
+export default RealtimeConfigPage
+export { generateMetadata }
diff --git a/apps/docs/app/guides/self-hosting/storage/config/page.tsx b/apps/docs/app/guides/self-hosting/storage/config/page.tsx
new file mode 100644
index 00000000000..766bc4d190a
--- /dev/null
+++ b/apps/docs/app/guides/self-hosting/storage/config/page.tsx
@@ -0,0 +1,63 @@
+import Param from '~/components/Params'
+import { genGuideMeta } from '~/features/docs/GuidesMdx.utils'
+import { GuideTemplate, newEditLink } from '~/features/docs/GuidesMdx.template'
+import { MDXRemoteBase } from '~/features/docs/MdxBase'
+import specStorageV0 from '~/spec/storage_v0_config.yaml' assert { type: 'yml' }
+
+const meta = {
+ title: 'Storage Self-hosting Config',
+ description: 'How to configure and deploy Supabase Storage.',
+}
+
+const generateMetadata = genGuideMeta(() => ({
+ pathname: '/guides/self-hosting/storage/config',
+ meta,
+}))
+
+const StorageConfigPage = async () => {
+ const descriptionMdx = specStorageV0.info.description
+
+ return (
+
+
+
+
+ {specStorageV0.info.tags.map((tag: ReturnType
['info']['tags']) => {
+ return (
+ <>
+ {tag.title}
+ {tag.description}
+
+
Parameters
+
+ {specStorageV0.parameters
+ .filter((param: ReturnType['parameters']) =>
+ param.tags.includes(tag.id)
+ )
+ .map((param: ReturnType['parameters']) => {
+ return (
+
+ )
+ })}
+
+
+ >
+ )
+ })}
+
+
+ )
+}
+
+export default StorageConfigPage
+export { generateMetadata }
diff --git a/apps/docs/app/layout.tsx b/apps/docs/app/layout.tsx
new file mode 100644
index 00000000000..a35a75df6e3
--- /dev/null
+++ b/apps/docs/app/layout.tsx
@@ -0,0 +1,58 @@
+import '@code-hike/mdx/styles'
+import 'config/code-hike.scss'
+import '../styles/main.scss'
+import '../styles/new-docs.scss'
+import '../styles/prism-okaidia.scss'
+
+import { genFaviconData } from 'common/MetaFavicons/app-router'
+import { type Metadata, type Viewport } from 'next'
+
+import { BASE_PATH } from '~/lib/constants'
+import { GlobalProviders } from '~/features/app.providers'
+import { TopNavSkeleton } from '~/layouts/MainSkeleton'
+
+const metadata: Metadata = {
+ applicationName: 'Supabase Docs',
+ title: 'Supabase Docs',
+ description:
+ 'Supabase is an open source Firebase alternative providing all the backend features you need to build a product.',
+ metadataBase: new URL('https://supabase.com'),
+ icons: genFaviconData(BASE_PATH),
+ robots: {
+ index: true,
+ follow: true,
+ },
+ openGraph: {
+ type: 'article',
+ authors: 'Supabase',
+ url: `${BASE_PATH}`,
+ images: `${BASE_PATH}/img/supabase-og-image.png`,
+ publishedTime: new Date().toISOString(),
+ modifiedTime: new Date().toISOString(),
+ },
+ twitter: {
+ card: 'summary_large_image',
+ site: '@supabase',
+ creator: '@supabase',
+ images: `${BASE_PATH}/img/supabase-og-image.png`,
+ },
+}
+
+const viewport: Viewport = {
+ themeColor: '#1E1E1E',
+}
+
+const RootLayout = ({ children }: { children: React.ReactNode }) => {
+ return (
+
+
+
+ {children}
+
+
+
+ )
+}
+
+export { metadata, viewport }
+export default RootLayout
diff --git a/apps/docs/app/not-found/layout.tsx b/apps/docs/app/not-found/layout.tsx
new file mode 100644
index 00000000000..b34cd4356b2
--- /dev/null
+++ b/apps/docs/app/not-found/layout.tsx
@@ -0,0 +1,20 @@
+import { type Metadata } from 'next'
+import { type PropsWithChildren } from 'react'
+import { LayoutMainContent } from '~/layouts/DefaultLayout'
+import { SidebarSkeleton } from '~/layouts/MainSkeleton'
+
+const metadata: Metadata = {
+ title: 'Not found',
+ robots: {
+ index: false,
+ },
+}
+
+const NotFoundLayout = ({ children }: PropsWithChildren) => (
+
+ {children}
+
+)
+
+export default NotFoundLayout
+export { metadata }
diff --git a/apps/docs/app/not-found/page.tsx b/apps/docs/app/not-found/page.tsx
new file mode 100644
index 00000000000..129aa70aec9
--- /dev/null
+++ b/apps/docs/app/not-found/page.tsx
@@ -0,0 +1,47 @@
+import { type Metadata } from 'next'
+import Link from 'next/link'
+
+import { Button } from 'ui'
+
+import { SearchButton, Recommendations } from '~/features/recommendations/NotFound.client'
+
+const metadata: Metadata = {
+ robots: {
+ index: false,
+ follow: false,
+ },
+}
+
+const NotFoundPage = async ({ searchParams: { page } }: { searchParams: { page?: string } }) => {
+ return (
+
+ 404: We couldn't find that page
+
+ Sorry, we couldn't find that page. It might be missing, or we had a temporary error
+ generating it.
+
+
+
+
+
+ Return to homepage
+
+
+
+
+ Report missing page
+
+
+
+
+
+ )
+}
+
+export default NotFoundPage
+export { metadata }
diff --git a/apps/docs/app/page.tsx b/apps/docs/app/page.tsx
new file mode 100644
index 00000000000..a272040b75e
--- /dev/null
+++ b/apps/docs/app/page.tsx
@@ -0,0 +1,347 @@
+import { type Metadata, type ResolvingMetadata } from 'next'
+import Link from 'next/link'
+import { IconBackground, TextLink } from 'ui'
+import { IconPanel } from 'ui-patterns/IconPanel'
+
+import MenuIconPicker from '~/components/Navigation/NavigationMenu/MenuIconPicker'
+import { GlassPanelWithIconPicker } from '~/features/ui/GlassPanelWithIconPicker'
+import { IconPanelWithIconPicker } from '~/features/ui/IconPanelWithIconPicker'
+import HomeLayout from '~/layouts/HomeLayout'
+import { BASE_PATH } from '~/lib/constants'
+
+const generateMetadata = async (_, parent: ResolvingMetadata): Promise => {
+ const parentAlternates = (await parent).alternates
+
+ return {
+ alternates: {
+ ...parentAlternates,
+ canonical: `${BASE_PATH}`,
+ },
+ }
+}
+
+const products = [
+ {
+ title: 'Database',
+ icon: 'database',
+ hasLightIcon: true,
+ href: '/guides/database/overview',
+ description:
+ 'Supabase provides a full Postgres database for every project with Realtime functionality, database backups, extensions, and more.',
+ },
+ {
+ title: 'Auth',
+ icon: 'auth',
+ hasLightIcon: true,
+ href: '/guides/auth',
+ description:
+ 'Add and manage email and password, passwordless, OAuth, and mobile logins to your project through a suite of identity providers and APIs.',
+ },
+ {
+ title: 'Storage',
+ icon: 'storage',
+ hasLightIcon: true,
+ href: '/guides/storage',
+ description:
+ 'Store, organize, transform, and serve large files—fully integrated with your Postgres database with Row Level Security access policies.',
+ },
+ {
+ title: 'AI & Vectors',
+ icon: 'ai',
+ hasLightIcon: true,
+ href: '/guides/ai',
+ description: 'Use Supabase to store and search embedding vectors.',
+ },
+ {
+ title: 'Realtime',
+ icon: 'realtime',
+ hasLightIcon: true,
+ href: '/guides/realtime',
+ description:
+ 'Listen to database changes, store and sync user states across clients, broadcast data to clients subscribed to a channel, and more.',
+ },
+ {
+ title: 'Edge Functions',
+ icon: 'edge-functions',
+ hasLightIcon: true,
+ href: '/guides/functions',
+ description:
+ 'Globally distributed, server-side functions to execute your code closest to your users for the lowest latency.',
+ },
+]
+
+const migrationGuides = [
+ {
+ title: 'Auth',
+ icon: '/docs/img/icons/auth0-icon',
+ href: '/guides/resources/migrating-to-supabase/auth0',
+ },
+ {
+ title: 'Firebase Auth',
+ icon: '/docs/img/icons/firebase-icon',
+ href: '/guides/resources/migrating-to-supabase/firebase-auth',
+ },
+ {
+ title: 'Firestore Data',
+ icon: '/docs/img/icons/firebase-icon',
+ href: '/guides/resources/migrating-to-supabase/firestore-data',
+ },
+ {
+ title: 'Firebase Storage',
+ icon: '/docs/img/icons/firebase-icon',
+ href: '/guides/resources/migrating-to-supabase/firebase-storage',
+ },
+ {
+ title: 'Heroku',
+ icon: '/docs/img/icons/heroku-icon',
+ href: '/guides/resources/migrating-to-supabase/heroku',
+ },
+ {
+ title: 'Render',
+ icon: '/docs/img/icons/render-icon',
+ href: '/guides/resources/migrating-to-supabase/render',
+ },
+ {
+ title: 'Amazon RDS',
+ icon: '/docs/img/icons/aws-rds-icon',
+ href: '/guides/resources/migrating-to-supabase/amazon-rds',
+ },
+ {
+ title: 'Postgres',
+ icon: '/docs/img/icons/postgres-icon',
+ href: '/guides/resources/migrating-to-supabase/postgres',
+ },
+ {
+ title: 'MySQL',
+ icon: '/docs/img/icons/mysql-icon',
+ href: '/guides/resources/migrating-to-supabase/mysql',
+ },
+ {
+ title: 'MSSQL',
+ icon: '/docs/img/icons/mssql-icon',
+ href: '/guides/resources/migrating-to-supabase/mssql',
+ },
+]
+
+const selfHostingOptions = [
+ {
+ title: 'Auth',
+ icon: 'auth',
+ href: '/reference/self-hosting-auth/introduction',
+ },
+ {
+ title: 'Realtime',
+ icon: 'realtime',
+ href: '/reference/self-hosting-realtime/introduction',
+ },
+ {
+ title: 'Storage',
+ icon: 'storage',
+ href: '/reference/self-hosting-storage/introduction',
+ },
+ {
+ title: 'Analytics',
+ icon: 'analytics',
+ href: '/reference/self-hosting-analytics/introduction',
+ },
+]
+
+const clientLibraries = [
+ {
+ title: 'Javascript',
+ icon: 'reference-javascript',
+ href: '/reference/javascript/introduction',
+ },
+ {
+ title: 'Flutter',
+ icon: 'reference-dart',
+ href: '/reference/dart/introduction',
+ },
+ {
+ title: 'Python',
+ icon: 'reference-python',
+ href: '/reference/python/introduction',
+ },
+ {
+ title: 'C#',
+ icon: 'reference-csharp',
+ href: '/reference/csharp/introduction',
+ },
+ {
+ title: 'Swift',
+ icon: 'reference-swift',
+ href: '/reference/swift/introduction',
+ },
+ {
+ title: 'Kotlin',
+ icon: 'reference-kotlin',
+ href: '/reference/kotlin/introduction',
+ },
+]
+
+const additionalResources = [
+ {
+ title: 'Management API',
+ description: 'Manage your Supabase projects and organizations.',
+ icon: 'reference-api',
+ href: '/reference/api/introduction',
+ },
+ {
+ title: 'Supabase CLI',
+ description: 'Use the CLI to develop, manage and deploy your projects.',
+ icon: 'reference-cli',
+ href: '/reference/cli/introduction',
+ },
+ {
+ title: 'Platform Guides',
+ description: 'Learn more about the tools and services powering Supabase.',
+ icon: 'platform',
+ href: '/guides/platform',
+ },
+ {
+ title: 'Integrations',
+ description: 'Explore a variety of integrations from Supabase partners.',
+ icon: 'integrations',
+ href: '/guides/integrations',
+ },
+]
+
+const HomePage = () => (
+
+
+
Products
+
+ {products.map((product) => {
+ return (
+
+
+
+ {product.description}
+
+
+
+ )
+ })}
+
+
+
+
+
+
+
+ Client Libraries
+
+
+
+
+
+
+ {clientLibraries.map((library) => {
+ return (
+
+
+
+ )
+ })}
+
+
+
+
+
+
+ Migrate to Supabase
+
+
+ Bring your existing data, auth and storage to Supabase following our migration guides.
+
+
+
+
+
+ {migrationGuides.map((guide) => {
+ return (
+
+
+
+
+
+ )
+ })}
+
+
+
+
+
+
+ Additional resources
+
+
+
+
+ {additionalResources.map((resource) => {
+ return (
+
+
+
+ {resource.description}
+
+
+
+ )
+ })}
+
+
+
+
+
+
+
+
+
+
+
+ Self-Hosting
+
+
+
Get started with self-hosting Supabase.
+
+
+
+
+
+
+ {selfHostingOptions.map((option) => {
+ return (
+
+
+
+
+
+ )
+ })}
+
+
+
+
+
+)
+
+export default HomePage
+export { generateMetadata }
diff --git a/apps/docs/components/ApiSchema.tsx b/apps/docs/components/ApiSchema.tsx
index 98ee6ab01e2..42a5b195566 100644
--- a/apps/docs/components/ApiSchema.tsx
+++ b/apps/docs/components/ApiSchema.tsx
@@ -1,6 +1,6 @@
import { CodeBlock } from '@ui/components/CodeBlock'
import { sample } from '@har-sdk/openapi-sampler'
-import { Tabs, TabPanel } from '~/components/Tabs'
+import { Tabs, TabPanel } from '~/features/ui/Tabs'
type IParamProps = any
diff --git a/apps/docs/components/AppleSecretGenerator/index.tsx b/apps/docs/components/AppleSecretGenerator/index.tsx
index ea66eadd23a..ea556ac7de9 100644
--- a/apps/docs/components/AppleSecretGenerator/index.tsx
+++ b/apps/docs/components/AppleSecretGenerator/index.tsx
@@ -1,11 +1,9 @@
-import { lazy, Suspense } from 'react'
+'use client'
-const Generator = lazy(() => import('./AppleSecretGenerator'))
+import dynamic from 'next/dynamic'
+
+const Generator = dynamic(() => import('./AppleSecretGenerator'), { ssr: false })
export function AppleSecretGenerator() {
- return (
-
-
-
- )
+ return
}
diff --git a/apps/docs/components/AuthSmsProviderConfig/AuthSmsProviderConfig.tsx b/apps/docs/components/AuthSmsProviderConfig/AuthSmsProviderConfig.tsx
index e0e74bcd7ac..2039a78854e 100644
--- a/apps/docs/components/AuthSmsProviderConfig/AuthSmsProviderConfig.tsx
+++ b/apps/docs/components/AuthSmsProviderConfig/AuthSmsProviderConfig.tsx
@@ -1,3 +1,5 @@
+'use client'
+
import { useEffect, useReducer, useRef } from 'react'
import { PhoneLoginsItems } from '../Navigation/NavigationMenu/NavigationMenu.constants'
import { IconPanel } from 'ui-patterns/IconPanel'
diff --git a/apps/docs/components/Breadcrumbs.tsx b/apps/docs/components/Breadcrumbs.tsx
new file mode 100644
index 00000000000..c8225015f67
--- /dev/null
+++ b/apps/docs/components/Breadcrumbs.tsx
@@ -0,0 +1,159 @@
+'use client'
+
+import React, { Fragment } from 'react'
+import Link from 'next/link'
+import { usePathname } from 'next/navigation'
+import {
+ Breadcrumb_Shadcn_ as Breadcrumb,
+ BreadcrumbList_Shadcn_ as BreadcrumbList,
+ BreadcrumbItem_Shadcn_ as BreadcrumbItem,
+ BreadcrumbLink_Shadcn_ as BreadcrumbLink,
+ BreadcrumbSeparator_Shadcn_ as BreadcrumbSeparator,
+ BreadcrumbPage_Shadcn_ as BreadcrumbPage,
+ BreadcrumbEllipsis_Shadcn_ as BreadcrumbEllipsis,
+ Button,
+ cn,
+ Drawer,
+ DrawerClose,
+ DrawerContent,
+ DrawerFooter,
+ DrawerTrigger,
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuItem,
+ DropdownMenuTrigger,
+} from 'ui'
+import { getMenuId } from '~/components/Navigation/NavigationMenu/NavigationMenu.utils'
+import { useBreakpoint } from 'common'
+import * as NavItems from './Navigation/NavigationMenu/NavigationMenu.constants'
+
+const Breadcrumbs = ({ className }: { className?: string }) => {
+ const pathname = usePathname()
+ const menuId = getMenuId(pathname)
+ const menu = NavItems[menuId]
+ const breadcrumbs = findMenuItemByUrl(menu, pathname, [])
+ const [open, setOpen] = React.useState(false)
+ const isMobile = useBreakpoint('md')
+
+ const ITEMS_TO_DISPLAY = isMobile ? 4 : 3
+
+ if (!breadcrumbs?.length || breadcrumbs?.length === 1) return null
+
+ const appendedBreadcrumbs = breadcrumbs?.slice(-ITEMS_TO_DISPLAY + 1, isMobile ? -1 : undefined)
+
+ return (
+
+
+ {breadcrumbs.length >= ITEMS_TO_DISPLAY && (
+ <>
+
+ {breadcrumbs[0].url ? (
+
+ {breadcrumbs[0].title || breadcrumbs[0].name}
+
+ ) : (
+ {breadcrumbs[0].title || breadcrumbs[0].name}
+ )}
+
+
+ >
+ )}
+ {breadcrumbs.length > ITEMS_TO_DISPLAY && (
+ <>
+
+ {!isMobile ? (
+
+
+
+
+
+ {breadcrumbs.slice(1, -2).map((crumb, index) => (
+
+ {crumb.url ? (
+ {crumb.title || crumb.name}
+ ) : (
+ crumb.title || crumb.name
+ )}
+
+ ))}
+
+
+ ) : (
+
+
+
+
+
+
+ {breadcrumbs
+ .slice(1, -2)
+ .map((crumb) =>
+ crumb.url ? (
+ {crumb.title || crumb.name}
+ ) : (
+ crumb.title || crumb.name
+ )
+ )}
+
+
+
+ Close
+
+
+
+
+ )}
+
+
+ >
+ )}
+ {appendedBreadcrumbs?.map((crumb, i) => (
+
+
+ {crumb.url ? (
+
+ {crumb.title || crumb.name}
+
+ ) : (
+ {crumb.title || crumb.name}
+ )}
+
+
+
+ ))}
+
+
+ )
+}
+
+function findMenuItemByUrl(menu, targetUrl, parents = []) {
+ // If the menu has items, recursively search through them
+ if (menu.items) {
+ for (let item of menu.items) {
+ const result = findMenuItemByUrl(item, targetUrl, [...parents, menu])
+ if (result) {
+ return result
+ }
+ }
+ }
+
+ // Check if the current menu object itself has the target URL
+ if (menu.url === targetUrl) {
+ return [...parents, menu]
+ }
+
+ // If the URL is not found, return null
+ return null
+}
+
+export default Breadcrumbs
diff --git a/apps/docs/components/ButtonCard.tsx b/apps/docs/components/ButtonCard.tsx
index 5180cc90786..ecc50fd15c0 100644
--- a/apps/docs/components/ButtonCard.tsx
+++ b/apps/docs/components/ButtonCard.tsx
@@ -1,6 +1,7 @@
import React, { FC } from 'react'
import Image from 'next/legacy/image'
import Link from 'next/link'
+import { cn } from 'ui'
interface Props {
title: string
@@ -9,6 +10,7 @@ interface Props {
icon?: string | any
children?: any
layout?: 'vertical' | 'horizontal'
+ className?: string
}
const ButtonCard: FC = ({
@@ -18,14 +20,16 @@ const ButtonCard: FC = ({
description = '',
to,
layout = 'vertical',
+ className,
}) => {
return (
{children ? (
children
diff --git a/apps/docs/components/DocsCoverLogo.tsx b/apps/docs/components/DocsCoverLogo.tsx
index 0e8965c50b6..8a66b35ea13 100644
--- a/apps/docs/components/DocsCoverLogo.tsx
+++ b/apps/docs/components/DocsCoverLogo.tsx
@@ -1,3 +1,5 @@
+'use client'
+
import React, { type PropsWithChildren } from 'react'
import { LazyMotion, domAnimation, m } from 'framer-motion'
diff --git a/apps/docs/components/Extensions/Extensions.tsx b/apps/docs/components/Extensions/Extensions.tsx
index 9f7304ebab2..cd2a80942c9 100644
--- a/apps/docs/components/Extensions/Extensions.tsx
+++ b/apps/docs/components/Extensions/Extensions.tsx
@@ -58,7 +58,7 @@ export default function Extensions() {
-
+
Filter
{tags.sort().map((tag) => (
diff --git a/apps/docs/components/Extensions/index.tsx b/apps/docs/components/Extensions/index.tsx
index e2debfda82f..466582bc117 100644
--- a/apps/docs/components/Extensions/index.tsx
+++ b/apps/docs/components/Extensions/index.tsx
@@ -1,3 +1,5 @@
+'use client'
+
import { lazy, Suspense } from 'react'
const ExtensionsInternal = lazy(() => import('./Extensions'))
diff --git a/apps/docs/components/Feedback/Feedback.tsx b/apps/docs/components/Feedback/Feedback.tsx
index 3b86b5dabe1..cd0a6341f8b 100644
--- a/apps/docs/components/Feedback/Feedback.tsx
+++ b/apps/docs/components/Feedback/Feedback.tsx
@@ -74,7 +74,7 @@ function Feedback() {
const [modalOpen, setModalOpen] = useState(false)
const feedbackButtonRef = useRef(null)
- const pathname = usePathname()
+ const pathname = usePathname() ?? ''
const sendTelemetryEvent = useSendTelemetryEvent()
const { mutate: sendFeedbackComment } = useSendFeedbackMutation()
const supabase = useSupabaseClient()
diff --git a/apps/docs/components/GuidesTableOfContents.tsx b/apps/docs/components/GuidesTableOfContents.tsx
index 1125f974076..78b438090a9 100644
--- a/apps/docs/components/GuidesTableOfContents.tsx
+++ b/apps/docs/components/GuidesTableOfContents.tsx
@@ -1,3 +1,5 @@
+'use client'
+
import { usePathname } from 'next/navigation'
import { useEffect, useState } from 'react'
import { cn } from 'ui'
@@ -20,7 +22,7 @@ const formatSlug = (slug: string) => {
const formatTOCHeader = (content: string) => {
let begin = false
- const res = []
+ const res: Array = []
for (const x of content) {
if (x === '`') {
if (!begin) {
@@ -52,17 +54,24 @@ const useTocRerenderTrigger = () => {
return toggleRenderFlag
}
+interface TOCHeader {
+ id?: string
+ text: string
+ link: string
+ level: number
+}
+
const GuidesTableOfContents = ({
className,
overrideToc,
video,
}: {
className?: string
- overrideToc?: Array<{ text: string; link: string; level: number }>
+ overrideToc?: Array
video?: string
}) => {
useSubscribeTocRerender()
- const [tocList, setTocList] = useState([])
+ const [tocList, setTocList] = useState([])
const pathname = usePathname()
const [hash] = useHash()
@@ -79,6 +88,7 @@ const GuidesTableOfContents = ({
const headings = Array.from(
document.querySelector('#sb-docs-guide-main-article')?.querySelectorAll('h2, h3') ?? []
)
+
const newHeadings = headings
.filter((heading) => heading.id)
.map((heading) => {
@@ -87,9 +97,10 @@ const GuidesTableOfContents = ({
if (!link) return null
const level = heading.tagName === 'H2' ? 2 : 3
- return { text, link, level }
+
+ return { text, link, level } as Partial
})
- .filter(Boolean)
+ .filter((x): x is TOCHeader => !!x && !!x.text && !!x.link && !!x.level)
setTocList(newHeadings)
})
@@ -140,3 +151,4 @@ const GuidesTableOfContents = ({
export default GuidesTableOfContents
export { useTocRerenderTrigger }
+export type { TOCHeader }
diff --git a/apps/docs/components/HomePageCover.tsx b/apps/docs/components/HomePageCover.tsx
index d9ee30ad170..6c084ce3ec9 100644
--- a/apps/docs/components/HomePageCover.tsx
+++ b/apps/docs/components/HomePageCover.tsx
@@ -1,3 +1,5 @@
+'use client'
+
import Link from 'next/link'
import { IconBackground, IconPlay } from 'ui'
import { useBreakpoint } from 'common'
@@ -100,12 +102,12 @@ const HomePageCover = (props) => {
)
return (
-
+
-
{props.meta?.title}
+
{props.title}
Learn how to get up and running with Supabase through tutorials, APIs and platform
resources.
diff --git a/apps/docs/components/JwtGenerator/index.tsx b/apps/docs/components/JwtGenerator/index.tsx
index 0896688868a..d104d40a779 100644
--- a/apps/docs/components/JwtGenerator/index.tsx
+++ b/apps/docs/components/JwtGenerator/index.tsx
@@ -1,3 +1,5 @@
+'use client'
+
import dynamic from 'next/dynamic'
import { Suspense } from 'react'
diff --git a/apps/docs/components/MDX/create_client_snippet.mdx b/apps/docs/components/MDX/create_client_snippet.mdx
new file mode 100644
index 00000000000..4e2fe443c23
--- /dev/null
+++ b/apps/docs/components/MDX/create_client_snippet.mdx
@@ -0,0 +1,7 @@
+
+
+Make sure you're using the right `supabase` client in the following code.
+
+If you're not using Server-Side Rendering or cookie-based Auth, you can directly use the `createClient` from `@supabase/supabase-js`. If you're using Server-Side Rendering, see the [Server-Side Auth guide](/docs/guides/auth/server-side/creating-a-client) for instructions on creating your Supabase client.
+
+
diff --git a/apps/docs/components/MDX/oauth_pkce_flow.mdx b/apps/docs/components/MDX/oauth_pkce_flow.mdx
index 53c03e47c44..f4bb7617a45 100644
--- a/apps/docs/components/MDX/oauth_pkce_flow.mdx
+++ b/apps/docs/components/MDX/oauth_pkce_flow.mdx
@@ -57,9 +57,9 @@ At the callback endpoint, handle the code exchange to save the user session.
Create a new file at `app/auth/callback/route.ts` and populate with the following:
```ts app/auth/callback/route.ts
-import { cookies } from 'next/headers'
import { NextResponse } from 'next/server'
-import { type CookieOptions, createServerClient } from '@supabase/ssr'
+// The client you created from the Server-Side Auth instructions
+import { createClient } from '@/utils/supabase/server'
export async function GET(request: Request) {
const { searchParams, origin } = new URL(request.url)
@@ -68,27 +68,19 @@ export async function GET(request: Request) {
const next = searchParams.get('next') ?? '/'
if (code) {
- const cookieStore = cookies()
- const supabase = createServerClient(
- process.env.NEXT_PUBLIC_SUPABASE_URL!,
- process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
- {
- cookies: {
- get(name: string) {
- return cookieStore.get(name)?.value
- },
- set(name: string, value: string, options: CookieOptions) {
- cookieStore.set({ name, value, ...options })
- },
- remove(name: string, options: CookieOptions) {
- cookieStore.delete({ name, ...options })
- },
- },
- }
- )
+ const supabase = createClient()
const { error } = await supabase.auth.exchangeCodeForSession(code)
if (!error) {
- return NextResponse.redirect(`${origin}${next}`)
+ const forwardedHost = request.headers.get('x-forwarded-host') // original origin before load balancer
+ const isLocalEnv = process.env.NODE_ENV === 'development'
+ if (isLocalEnv) {
+ // we can be sure that there is no load balancer in between, so no need to watch for X-Forwarded-Host
+ return NextResponse.redirect(`${origin}${next}`)
+ } else if (forwardedHost) {
+ return NextResponse.redirect(`https://${forwardedHost}${next}`)
+ } else {
+ return NextResponse.redirect(`${origin}${next}`)
+ }
}
}
@@ -132,7 +124,7 @@ export const GET = async (event) => {
Create a new file at `src/pages/auth/callback.ts` and populate with the following:
```ts src/pages/auth/callback.ts
-import { createServerClient } from '@supabase/ssr'
+import { createServerClient, parseCookieHeader } from '@supabase/ssr'
import { type APIRoute } from 'astro'
export const GET: APIRoute = async ({ request, cookies, redirect }) => {
@@ -146,14 +138,13 @@ export const GET: APIRoute = async ({ request, cookies, redirect }) => {
import.meta.env.PUBLIC_SUPABASE_ANON_KEY,
{
cookies: {
- get(key) {
- return cookies.get(key)?.value
+ getAll() {
+ return parseCookieHeader(Astro.request.headers.get('Cookie') ?? '')
},
- set(key, value, options) {
- cookies.set(key, value, options)
- },
- remove(key, options) {
- cookies.delete(key, options)
+ setAll(cookiesToSet) {
+ cookiesToSet.forEach(({ name, value, options }) =>
+ Astro.cookies.set(name, value, options)
+ )
},
},
}
@@ -179,7 +170,7 @@ Create a new file at `app/routes/auth.callback.tsx` and populate with the follow
```ts app/routes/auth.callback.tsx
import { redirect, type LoaderFunctionArgs } from '@remix-run/node'
-import { createServerClient, parse, serialize } from '@supabase/ssr'
+import { createServerClient, parseCookieHeader, serializeCookieHeader } from '@supabase/ssr'
export async function loader({ request }: LoaderFunctionArgs) {
const requestUrl = new URL(request.url)
@@ -191,14 +182,13 @@ export async function loader({ request }: LoaderFunctionArgs) {
const cookies = parse(request.headers.get('Cookie') ?? '')
const supabase = createServerClient(process.env.SUPABASE_URL!, process.env.SUPABASE_ANON_KEY!, {
cookies: {
- get(key) {
- return cookies[key]
+ getAll() {
+ return parseCookieHeader(request.headers.get('Cookie') ?? '')
},
- set(key, value, options) {
- headers.append('Set-Cookie', serialize(key, value, options))
- },
- remove(key, options) {
- headers.append('Set-Cookie', serialize(key, '', options))
+ setAll(cookiesToSet) {
+ cookiesToSet.forEach(({ name, value, options }) =>
+ headers.append('Set-Cookie', serializeCookieHeader(name, value, options))
+ )
},
},
})
@@ -227,7 +217,20 @@ app.get("/auth/callback", async function (req, res) {
const next = req.query.next ?? "/"
if (code) {
- const supabase = createClient({ req, res })
+ const supabase = createServerClient(
+ process.env.SUPABASE_URL,
+ process.env.SUPABASE_ANON_KEY, {
+ cookies: {
+ getAll() {
+ return parseCookieHeader(context.req.headers.cookie ?? '')
+ },
+ setAll(cookiesToSet) {
+ cookiesToSet.forEach(({ name, value, options }) =>
+ context.res.appendHeader('Set-Cookie', serializeCookieHeader(name, value, options))
+ )
+ },
+ },
+ })
await supabase.auth.exchangeCodeForSession(code)
}
diff --git a/apps/docs/components/MDX/partials.tsx b/apps/docs/components/MDX/partials.tsx
new file mode 100644
index 00000000000..7b10795e752
--- /dev/null
+++ b/apps/docs/components/MDX/partials.tsx
@@ -0,0 +1,29 @@
+'use client'
+
+import AuthRateLimits from './auth_rate_limits.mdx'
+import CreateClientSnippet from './create_client_snippet.mdx'
+import DatabaseSetup from './database_setup.mdx'
+import GetSessionWarning from './get_session_warning.mdx'
+import HuggingFaceDeployment from './ai/quickstart_hf_deployment.mdx'
+import KotlinProjectSetup from './kotlin_project_setup.mdx'
+import MigrationWarnings from './migration_warnings.mdx'
+import OAuthPkceFlow from './oauth_pkce_flow.mdx'
+import ProjectSetup from './project_setup.mdx'
+import QuickstartIntro from './quickstart_intro.mdx'
+import SocialProviderSettingsSupabase from './social_provider_settings_supabase.mdx'
+import SocialProviderSetup from './social_provider_setup.mdx'
+
+export {
+ AuthRateLimits,
+ CreateClientSnippet,
+ DatabaseSetup,
+ GetSessionWarning,
+ HuggingFaceDeployment,
+ KotlinProjectSetup,
+ MigrationWarnings,
+ ProjectSetup,
+ OAuthPkceFlow,
+ QuickstartIntro,
+ SocialProviderSettingsSupabase,
+ SocialProviderSetup,
+}
diff --git a/apps/docs/components/MDX/user_management_quickstart_sql_template.mdx b/apps/docs/components/MDX/user_management_quickstart_sql_template.mdx
index 28b560e84bb..8006c362da9 100644
--- a/apps/docs/components/MDX/user_management_quickstart_sql_template.mdx
+++ b/apps/docs/components/MDX/user_management_quickstart_sql_template.mdx
@@ -27,7 +27,9 @@ create policy "Users can update own profile." on profiles
-- This trigger automatically creates a profile entry when a new user signs up via Supabase Auth.
-- See https://supabase.com/docs/guides/auth/managing-user-data#using-triggers for more details.
create function public.handle_new_user()
-returns trigger as $$
+returns trigger
+set search_path = ''
+as $$
begin
insert into public.profiles (id, full_name, avatar_url)
values (new.id, new.raw_user_meta_data->>'full_name', new.raw_user_meta_data->>'avatar_url');
diff --git a/apps/docs/components/Mermaid/Mermaid.tsx b/apps/docs/components/Mermaid/Mermaid.tsx
deleted file mode 100644
index e2607613ccf..00000000000
--- a/apps/docs/components/Mermaid/Mermaid.tsx
+++ /dev/null
@@ -1,2 +0,0 @@
-import { Mermaid } from 'mdx-mermaid/lib/Mermaid'
-export default Mermaid
diff --git a/apps/docs/components/Mermaid/index.tsx b/apps/docs/components/Mermaid/index.tsx
deleted file mode 100644
index b73a5d8033d..00000000000
--- a/apps/docs/components/Mermaid/index.tsx
+++ /dev/null
@@ -1,11 +0,0 @@
-import { Suspense, lazy } from 'react'
-
-const MermaidHeavy = lazy(() => import('./Mermaid'))
-
-export function Mermaid(props) {
- return (
-
-
-
- )
-}
diff --git a/apps/docs/components/Navigation/Navigation.types.ts b/apps/docs/components/Navigation/Navigation.types.ts
index 3882fb26e77..dd744fe4b0e 100644
--- a/apps/docs/components/Navigation/Navigation.types.ts
+++ b/apps/docs/components/Navigation/Navigation.types.ts
@@ -32,7 +32,11 @@ type MenuItem = {
community?: boolean
}
-export type HomepageMenuItems = MenuItem[][]
+export type DropdownMenuItem = MenuItem & {
+ menuItems?: MenuItem[][]
+}
+
+export type GlobalMenuItems = DropdownMenuItem[][]
export type NavMenuConstant = Readonly<{
title: string
diff --git a/apps/docs/components/Navigation/NavigationMenu/GlobalMobileMenu.tsx b/apps/docs/components/Navigation/NavigationMenu/GlobalMobileMenu.tsx
new file mode 100644
index 00000000000..e84ae0a852e
--- /dev/null
+++ b/apps/docs/components/Navigation/NavigationMenu/GlobalMobileMenu.tsx
@@ -0,0 +1,198 @@
+import React, { Dispatch, Fragment, SetStateAction, useEffect } from 'react'
+import { m, AnimatePresence, LazyMotion, domAnimation } from 'framer-motion'
+import Image from 'next/image'
+import Link from 'next/link'
+import { usePathname } from 'next/navigation'
+import { useKey } from 'react-use'
+
+import { useIsLoggedIn, useIsUserLoading } from 'common'
+import { Accordion, Button, cn, IconX } from 'ui'
+import { ThemeToggle } from 'ui-patterns'
+
+import { MenuItem, useActiveMenuLabel } from './GlobalNavigationMenu'
+import { GLOBAL_MENU_ITEMS } from './NavigationMenu.constants'
+import type { DropdownMenuItem } from '../Navigation.types'
+
+const DEFAULT_EASE = [0.24, 0.25, 0.05, 1]
+
+const container = {
+ hidden: { opacity: 0 },
+ show: { opacity: 1, transition: { duration: 0.15, staggerChildren: 0.05, ease: DEFAULT_EASE } },
+ exit: { opacity: 0, transition: { duration: 0.15 } },
+}
+
+const listItem = {
+ hidden: { opacity: 0, y: 10 },
+ show: { opacity: 1, y: 0, transition: { duration: 0.25, ease: DEFAULT_EASE } },
+ exit: { opacity: 0, transition: { duration: 0.05 } },
+}
+
+const itemClassName =
+ 'block py-2 pl-2 pr-3.5 text-sm text-foreground-light hover:bg-surface-200 focus-visible:ring-2 focus-visible:outline-none focus-visible:ring-foreground-lighter focus-visible:rounded'
+
+const AccordionMenuItem = ({ section }: { section: DropdownMenuItem[] }) => {
+ const activeLabel = useActiveMenuLabel(GLOBAL_MENU_ITEMS)
+
+ return (
+
+ {section[0].menuItems ? (
+
+ {section[0].menuItems?.map((menuItem, menuItemIndex) => (
+
+ {menuItem.map((item) =>
+ !item.href ? (
+
+ {item.label}
+
+ ) : (
+
+ )
+ )}
+
+ ))}
+
+ ) : (
+
+ {section[0].label}
+
+ )}
+
+ )
+}
+
+const Menu = () => (
+
+ {GLOBAL_MENU_ITEMS.map((section) => (
+
+ ))}
+
+)
+interface Props {
+ open: boolean
+ setOpen: Dispatch>
+}
+
+const GlobalMobileMenu = ({ open, setOpen }: Props) => {
+ const isLoggedIn = useIsLoggedIn()
+ const isUserLoading = useIsUserLoading()
+ const pathname = usePathname()
+
+ // Close mobile menu on route change
+ useEffect(() => {
+ setOpen(false)
+ }, [pathname])
+
+ useKey('Escape', () => setOpen(false))
+
+ return (
+
+
+ {open && (
+
+
+
+
+
+
DOCS
+
+
+
+ setOpen(false)}
+ type="button"
+ className="inline-flex items-center justify-center focus:ring-brand bg-surface-100 hover:bg-surface-200 focus:outline-none focus:ring-2 focus:ring-inset border border-default bg-surface-100/75 text-foreground-light rounded min-w-[30px] w-[30px] h-[30px]"
+ >
+ Close menu
+
+
+
+
+
+
+
+
+ {!isUserLoading && (
+ <>
+ {isLoggedIn ? (
+
+ Dashboard
+
+ ) : (
+ <>
+
+ Sign in
+
+
+ Start your project
+
+ >
+ )}
+ >
+ )}
+
+
+ )}
+
+
+ {open && (
+
+ )}
+
+
+ )
+}
+
+export default GlobalMobileMenu
diff --git a/apps/docs/components/Navigation/NavigationMenu/GlobalNavigationMenu.tsx b/apps/docs/components/Navigation/NavigationMenu/GlobalNavigationMenu.tsx
new file mode 100644
index 00000000000..3adebfe9d72
--- /dev/null
+++ b/apps/docs/components/Navigation/NavigationMenu/GlobalNavigationMenu.tsx
@@ -0,0 +1,183 @@
+'use client'
+
+import React, { FC, Fragment, useEffect, useState } from 'react'
+import Link from 'next/link'
+import { usePathname } from 'next/navigation'
+import {
+ Badge,
+ cn,
+ MenubarSeparator,
+ NavigationMenu,
+ NavigationMenuContent,
+ NavigationMenuItem,
+ NavigationMenuLink,
+ NavigationMenuList,
+ NavigationMenuTrigger,
+ navigationMenuTriggerStyle,
+} from 'ui'
+
+import MenuIconPicker from './MenuIconPicker'
+import { GLOBAL_MENU_ITEMS } from './NavigationMenu.constants'
+
+/**
+ * Get TopNav active label based on current pathname
+ */
+export const useActiveMenuLabel = (GLOBAL_MENU_ITEMS) => {
+ const pathname = usePathname()
+ const [activeLabel, setActiveLabel] = useState('')
+
+ useEffect(() => {
+ // check if homepage
+ if (pathname === '/') {
+ return setActiveLabel('Home')
+ }
+
+ for (let index = 0; index < GLOBAL_MENU_ITEMS.length; index++) {
+ const section = GLOBAL_MENU_ITEMS[index]
+ // check if first level menu items match beginning of url
+ if (section[0].href?.startsWith(pathname)) {
+ return setActiveLabel(section[0].label)
+ }
+ // check if second level menu items match beginning of url
+ if (section[0].menuItems) {
+ section[0].menuItems.map((menuItemGroup) =>
+ menuItemGroup.map(
+ (menuItem) => menuItem.href?.startsWith(pathname) && setActiveLabel(section[0].label)
+ )
+ )
+ }
+ }
+ }, [pathname])
+
+ return activeLabel
+}
+
+const GlobalNavigationMenu: FC = () => {
+ const activeLabel = useActiveMenuLabel(GLOBAL_MENU_ITEMS)
+ const triggerClassName =
+ 'h-[var(--header-height)] p-2 bg-transparent border-0 border-b-2 border-transparent font-normal rounded-none text-foreground-light hover:text-foreground data-[state=open]:!text-foreground data-[radix-collection-item]:focus-visible:ring-2 data-[radix-collection-item]:focus-visible:ring-foreground-lighter data-[radix-collection-item]:focus-visible:text-foreground h-full focus-visible:rounded !shadow-none outline-none transition-all outline-0 focus-visible:outline-4 focus-visible:outline-offset-1 focus-visible:outline-brand-600'
+
+ return (
+
+
+
+ {GLOBAL_MENU_ITEMS.map((section, sectionIdx) =>
+ section[0].menuItems ? (
+
+
+ {section[0].label === 'Home' ? (
+
+ ) : (
+ section[0].label
+ )}
+
+
+
+ {section[0].menuItems?.map((menuItem, menuItemIndex) => (
+
+ {menuItemIndex !== 0 && }
+ {menuItem.map((item, itemIdx) =>
+ !item.href ? (
+
+ {item.label}
+
+ ) : (
+
+
+
+ )
+ )}
+
+ ))}
+
+
+
+ ) : (
+
+
+
+ {section[0].label === 'Home' ? (
+
+ ) : (
+ section[0].label
+ )}
+
+
+
+ )
+ )}
+
+
+
+ )
+}
+
+export const MenuItem = React.forwardRef<
+ React.ElementRef<'a'>,
+ React.ComponentPropsWithoutRef<'a'> & {
+ icon?: string
+ community?: boolean
+ }
+>(({ className, title, href = '', icon, community, children, ...props }, ref) => {
+ return (
+
+ {children ?? (
+ <>
+ {icon && }
+ {title}
+ {community && Community }
+ >
+ )}
+
+ )
+})
+
+GlobalNavigationMenu.displayName = 'GlobalNavigationMenu'
+MenuItem.displayName = 'MenuItem'
+
+export default GlobalNavigationMenu
diff --git a/apps/docs/components/Navigation/NavigationMenu/HomeMenu.tsx b/apps/docs/components/Navigation/NavigationMenu/HomeMenu.tsx
deleted file mode 100644
index 944345923cf..00000000000
--- a/apps/docs/components/Navigation/NavigationMenu/HomeMenu.tsx
+++ /dev/null
@@ -1,59 +0,0 @@
-import Link from 'next/link'
-import { Fragment } from 'react'
-import { Badge, cn } from 'ui'
-import { HOMEPAGE_MENU_ITEMS } from './NavigationMenu.constants'
-import HomeMenuIconPicker from './HomeMenuIconPicker'
-
-const NavigationMenuHome = () => {
- return (
-
-
- {HOMEPAGE_MENU_ITEMS.map((section, sectionIndex) => {
- return (
-
- {sectionIndex !== 0 && (
-
- )}
-
-
- {section.map((link, i) => {
- if (!link.href) {
- return (
-
- {link.label}
-
- )
- } else {
- return (
-
-
- {link?.icon && }
- {link.label}
- {link.community && Community }
-
-
- )
- }
- })}
-
-
-
- )
- })}
-
-
- )
-}
-
-export default NavigationMenuHome
diff --git a/apps/docs/components/Navigation/NavigationMenu/HomeMenuIconPicker.tsx b/apps/docs/components/Navigation/NavigationMenu/MenuIconPicker.tsx
similarity index 84%
rename from apps/docs/components/Navigation/NavigationMenu/HomeMenuIconPicker.tsx
rename to apps/docs/components/Navigation/NavigationMenu/MenuIconPicker.tsx
index b4f2e7ae2a2..18fef33a67b 100644
--- a/apps/docs/components/Navigation/NavigationMenu/HomeMenuIconPicker.tsx
+++ b/apps/docs/components/Navigation/NavigationMenu/MenuIconPicker.tsx
@@ -1,3 +1,5 @@
+'use client'
+
import React from 'react'
import {
IconMenuApi,
@@ -24,12 +26,18 @@ import {
IconMenuKotlin,
IconMenuAI,
IconMenuDevCli,
-} from './HomeMenuIcons'
+ IconGitHub,
+ IconSupport,
+ IconTroubleshooting,
+ IconBranching,
+} from './MenuIcons'
-function getMenuIcon(menuKey: string, width: number = 16, height: number = 16, className: string) {
+function getMenuIcon(menuKey: string, width: number = 16, height: number = 16, className?: string) {
switch (menuKey) {
case 'home':
return
+ case 'branching':
+ return
case 'getting-started':
return
case 'database':
@@ -76,23 +84,29 @@ function getMenuIcon(menuKey: string, width: number = 16, height: number = 16, c
return
case 'status':
return
+ case 'github':
+ return
+ case 'support':
+ return
+ case 'contributing':
+ return
default:
return
}
}
-type HomeMenuIconPickerProps = {
+type MenuIconPickerProps = {
icon: string
width?: number
height?: number
className?: string
}
-export default function HomeMenuIconPicker({
+export default function MenuIconPicker({
icon,
width = 16,
height = 16,
className,
-}: HomeMenuIconPickerProps) {
+}: MenuIconPickerProps) {
return getMenuIcon(icon, width, height, className)
}
diff --git a/apps/docs/components/Navigation/NavigationMenu/HomeMenuIcons.tsx b/apps/docs/components/Navigation/NavigationMenu/MenuIcons.tsx
similarity index 76%
rename from apps/docs/components/Navigation/NavigationMenu/HomeMenuIcons.tsx
rename to apps/docs/components/Navigation/NavigationMenu/MenuIcons.tsx
index e762f8f3c78..c9dfa878980 100644
--- a/apps/docs/components/Navigation/NavigationMenu/HomeMenuIcons.tsx
+++ b/apps/docs/components/Navigation/NavigationMenu/MenuIcons.tsx
@@ -519,3 +519,119 @@ export function IconMenuStatus({ width = 16, height = 16, className }: HomeMenuI
)
}
+
+export function IconBranching({ width = 16, height = 16, className }: HomeMenuIcon) {
+ return (
+
+
+
+
+
+
+
+ )
+}
+
+export function IconGitHub({ width = 16, height = 16, className }: HomeMenuIcon) {
+ return (
+
+
+
+ )
+}
+
+export function IconSupport({ width = 16, height = 16, className }: HomeMenuIcon) {
+ return (
+
+
+
+ )
+}
+
+export function IconTerraform({ width = 16, height = 16, className }: HomeMenuIcon) {
+ return (
+
+
+
+
+
+ )
+}
+
+export function IconTroubleshooting({ width = 16, height = 16, className }: HomeMenuIcon) {
+ return (
+
+
+
+ )
+}
diff --git a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts
index b11aab55b23..25603cb34ce 100644
--- a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts
+++ b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts
@@ -1,15 +1,10 @@
-import type { HomepageMenuItems, NavMenuConstant, References } from '../Navigation.types'
+import { IS_DEV } from '~/lib/constants'
+import type { GlobalMenuItems, NavMenuConstant, References } from '../Navigation.types'
-export const HOMEPAGE_MENU_ITEMS: HomepageMenuItems = [
+export const GLOBAL_MENU_ITEMS: GlobalMenuItems = [
[
{
- label: 'Home',
- icon: 'home',
- href: '/',
- level: 'home',
- },
- {
- label: 'Getting Started',
+ label: 'Start',
icon: 'getting-started',
href: '/guides/getting-started',
level: 'gettingstarted',
@@ -17,164 +12,192 @@ export const HOMEPAGE_MENU_ITEMS: HomepageMenuItems = [
],
[
{
- label: 'Product',
- },
- {
- label: 'Database',
- icon: 'database',
- href: '/guides/database/overview',
- level: 'database',
- },
- {
- label: 'Auth',
- icon: 'auth',
- href: '/guides/auth',
- level: 'auth',
- },
- {
- label: 'Storage',
- icon: 'storage',
- href: '/guides/storage',
- level: 'storage',
- },
- {
- label: 'Edge Functions',
- icon: 'edge-functions',
- href: '/guides/functions',
- level: 'functions',
- },
- {
- label: 'Realtime',
- icon: 'realtime',
- href: '/guides/realtime',
- level: 'realtime',
- },
- {
- label: 'AI & Vectors',
- icon: 'ai',
- href: '/guides/ai',
- level: 'ai',
+ label: 'Products',
+ menuItems: [
+ [
+ {
+ label: 'Database',
+ icon: 'database',
+ href: '/guides/database/overview',
+ level: 'database',
+ },
+ {
+ label: 'Auth',
+ icon: 'auth',
+ href: '/guides/auth',
+ level: 'auth',
+ },
+ {
+ label: 'Storage',
+ icon: 'storage',
+ href: '/guides/storage',
+ level: 'storage',
+ },
+ {
+ label: 'Edge Functions',
+ icon: 'edge-functions',
+ href: '/guides/functions',
+ level: 'functions',
+ },
+ {
+ label: 'Realtime',
+ icon: 'realtime',
+ href: '/guides/realtime',
+ level: 'realtime',
+ },
+ {
+ label: 'AI & Vectors',
+ icon: 'ai',
+ href: '/guides/ai',
+ level: 'ai',
+ },
+ ],
+ ],
},
],
[
{
- label: 'Data API',
- },
- {
- label: 'REST',
- icon: 'rest',
- href: '/guides/api',
- level: 'api',
- },
- {
- label: 'GraphQL',
- icon: 'graphql',
- href: '/guides/graphql',
- level: 'graphql',
+ label: 'Build',
+ menuItems: [
+ [
+ {
+ label: 'Local Dev / CLI',
+ icon: 'dev-cli',
+ href: '/guides/cli',
+ level: 'reference_javascript',
+ },
+ {
+ label: 'Platform',
+ icon: 'platform',
+ href: '/guides/platform',
+ level: 'platform',
+ },
+ {
+ label: 'Self-Hosting',
+ icon: 'self-hosting',
+ href: '/guides/self-hosting',
+ level: 'self_hosting',
+ },
+ {
+ label: 'Integrations',
+ icon: 'integrations',
+ hasLightIcon: true,
+ href: 'https://supabase.com/partners/integrations',
+ level: 'integrations',
+ },
+ ],
+ ],
},
],
[
{
- label: 'Development Cycle',
- },
- {
- label: 'Local Dev / CLI',
- icon: 'dev-cli',
- href: '/guides/cli',
- level: 'reference_javascript',
- },
- {
- label: 'Platform',
- icon: 'platform',
- href: '/guides/platform',
- level: 'platform',
- },
- {
- label: 'Self-Hosting',
- icon: 'self-hosting',
- href: '/guides/self-hosting',
- level: 'self_hosting',
- },
- ],
- [
- {
- label: 'Client Library Reference',
- },
- {
- label: 'JavaScript',
- icon: 'reference-javascript',
- href: '/reference/javascript/introduction',
- level: 'reference_javascript',
- },
- {
- label: 'Flutter',
- icon: 'reference-dart',
- href: '/reference/dart/introduction',
- level: 'reference_dart',
- },
- {
- label: 'Swift',
- icon: 'reference-swift',
- href: '/reference/swift/introduction',
- level: 'reference_swift',
- },
- {
- label: 'Python',
- icon: 'reference-python',
- href: '/reference/python/introduction',
- level: 'reference_python',
- community: true,
- },
- {
- label: 'C#',
- icon: 'reference-csharp',
- href: '/reference/csharp/introduction',
- level: 'reference_csharp',
- community: true,
- },
- {
- label: 'Kotlin',
- icon: 'reference-kotlin',
- href: '/reference/kotlin/introduction',
- level: 'reference_kotlin',
- community: true,
+ label: 'Reference',
+ menuItems: [
+ [
+ {
+ label: 'Client Library Reference',
+ },
+ {
+ label: 'JavaScript',
+ icon: 'reference-javascript',
+ href: '/reference/javascript/introduction',
+ level: 'reference_javascript',
+ },
+ {
+ label: 'Flutter',
+ icon: 'reference-dart',
+ href: '/reference/dart/introduction',
+ level: 'reference_dart',
+ },
+ {
+ label: 'Swift',
+ icon: 'reference-swift',
+ href: '/reference/swift/introduction',
+ level: 'reference_swift',
+ },
+ {
+ label: 'Python',
+ icon: 'reference-python',
+ href: '/reference/python/introduction',
+ level: 'reference_python',
+ },
+ {
+ label: 'C#',
+ icon: 'reference-csharp',
+ href: '/reference/csharp/introduction',
+ level: 'reference_csharp',
+ community: true,
+ },
+ {
+ label: 'Kotlin',
+ icon: 'reference-kotlin',
+ href: '/reference/kotlin/introduction',
+ level: 'reference_kotlin',
+ community: true,
+ },
+ ],
+ [
+ {
+ label: 'CLI Commands',
+ icon: 'reference-cli',
+ href: '/reference/cli/introduction',
+ level: 'reference_javascript',
+ },
+ {
+ label: 'Management API',
+ icon: 'reference-api',
+ href: '/reference/api/introduction',
+ level: 'reference_javascript',
+ },
+ ],
+ [
+ { label: 'Data API' },
+ {
+ label: 'REST',
+ icon: 'rest',
+ href: '/guides/api',
+ level: 'api',
+ },
+ {
+ label: 'GraphQL',
+ icon: 'graphql',
+ href: '/guides/graphql',
+ level: 'graphql',
+ },
+ ],
+ ],
},
],
[
{
label: 'Resources',
- },
- {
- label: 'CLI Commands',
- icon: 'reference-cli',
- href: '/reference/cli/introduction',
- level: 'reference_javascript',
- },
- {
- label: 'Management API',
- icon: 'reference-api',
- href: '/reference/api/introduction',
- level: 'reference_javascript',
- },
- {
- label: 'Guides and Examples',
- icon: 'resources',
- href: '/guides/resources',
- level: 'resources',
- },
- {
- label: 'Integrations',
- icon: 'integrations',
- hasLightIcon: true,
- href: 'https://supabase.com/partners/integrations',
- level: 'integrations',
- },
- ],
- [
- {
- label: 'Status',
- icon: 'status',
- href: 'https://status.supabase.com/',
+ menuItems: [
+ [
+ {
+ label: 'Migration guides',
+ icon: 'resources',
+ href: '/guides/resources',
+ level: 'resources',
+ },
+ {
+ label: 'Changelog',
+ icon: 'changelog',
+ hasLightIcon: true,
+ href: 'https://supabase.com/changelog',
+ level: 'changelog',
+ },
+ {
+ label: 'Status',
+ icon: 'status',
+ href: 'https://status.supabase.com/',
+ },
+ {
+ label: 'Contributing',
+ icon: 'contributing',
+ href: '/contributing' as `/${string}`,
+ },
+ ],
+ ],
},
],
]
@@ -226,7 +249,8 @@ export const REFERENCES: References = {
export const gettingstarted: NavMenuConstant = {
icon: 'getting-started',
- title: 'Getting Started',
+ title: 'Start with Supabase',
+ url: '/guides/getting-started',
items: [
{ name: 'Features', url: '/guides/getting-started/features' },
{ name: 'Architecture', url: '/guides/getting-started/architecture' },
@@ -238,6 +262,7 @@ export const gettingstarted: NavMenuConstant = {
{ name: 'NuxtJS', url: '/guides/getting-started/quickstarts/nuxtjs' },
{ name: 'Vue', url: '/guides/getting-started/quickstarts/vue' },
{ name: 'Flutter', url: '/guides/getting-started/quickstarts/flutter' },
+ { name: 'iOS SwiftUI', url: '/guides/getting-started/quickstarts/ios-swiftui' },
{
name: 'Android Kotlin',
url: '/guides/getting-started/quickstarts/kotlin',
@@ -733,6 +758,10 @@ export const database: NavMenuConstant = {
name: 'Column Level Security',
url: '/guides/database/postgres/column-level-security',
},
+ {
+ name: 'Hardening the Data API',
+ url: '/guides/database/hardening-data-api',
+ },
{
name: 'Custom Claims & RBAC',
url: '/guides/database/postgres/custom-claims-and-role-based-access-control-rbac',
@@ -746,10 +775,6 @@ export const database: NavMenuConstant = {
name: 'Superuser Access and Unsupported Operations',
url: '/guides/database/postgres/roles-superuser',
},
- {
- name: 'Column level privileges',
- url: '/guides/database/postgres/column-level-security',
- },
],
},
{
@@ -860,10 +885,6 @@ export const database: NavMenuConstant = {
name: 'PostGIS: Geo queries',
url: '/guides/database/extensions/postgis',
},
- {
- name: 'pg-safeupdate: Required Where Clauses',
- url: '/guides/database/extensions/pg-safeupdate',
- },
{
name: 'pgsodium (pending deprecation): Encryption Features',
url: '/guides/database/extensions/pgsodium',
@@ -1179,7 +1200,7 @@ export const functions: NavMenuConstant = {
},
{
name: 'Examples',
- url: '/guides/functions/examples',
+ url: undefined,
items: [
{
name: 'CORS support for invoking from the browser',
@@ -1295,6 +1316,11 @@ export const realtime: NavMenuConstant = {
},
],
},
+ {
+ name: 'Security',
+ url: undefined,
+ items: [{ name: 'Authorization', url: '/guides/realtime/authorization' }],
+ },
{
name: 'Guides',
url: undefined,
@@ -1307,6 +1333,14 @@ export const realtime: NavMenuConstant = {
name: 'Using Realtime with Next.js',
url: '/guides/realtime/realtime-with-nextjs',
},
+ {
+ name: 'Using Realtime Presence with Flutter',
+ url: '/guides/realtime/realtime-user-presence',
+ },
+ {
+ name: 'Listening to Postgres Changes with Flutter',
+ url: '/guides/realtime/realtime-listening-flutter',
+ },
],
},
{
@@ -1691,6 +1725,7 @@ export const platform: NavMenuConstant = {
url: undefined,
items: [
{ name: 'Logging', url: '/guides/platform/logs' },
+ { name: 'Log Drains', url: '/guides/platform/log-drains' },
{ name: 'Metrics', url: '/guides/platform/metrics' },
{ name: 'Monitoring with Sentry', url: '/guides/platform/sentry-monitoring' },
],
@@ -1699,7 +1734,7 @@ export const platform: NavMenuConstant = {
name: 'Platform Management',
url: undefined,
items: [
- { name: 'Access Control', url: '/guides/platform/access-control' },
+ { name: 'Regions', url: '/guides/platform/regions' },
{
name: 'Custom Postgres Config',
url: '/guides/platform/custom-postgres-config',
@@ -1727,11 +1762,18 @@ export const platform: NavMenuConstant = {
url: '/guides/platform/network-restrictions',
},
{ name: 'Performance Tuning', url: '/guides/platform/performance' },
- { name: 'Permissions', url: '/guides/platform/permissions' },
- { name: 'SSL Enforcement', url: '/guides/platform/ssl-enforcement' },
{ name: 'Branching', url: '/guides/platform/branching' },
],
},
+ {
+ name: 'Security',
+ url: undefined,
+ items: [
+ { name: 'Access Control', url: '/guides/platform/access-control' },
+ { name: 'SSL Enforcement', url: '/guides/platform/ssl-enforcement' },
+ { name: 'Platform-required Permissions', url: '/guides/platform/permissions' },
+ ],
+ },
{
name: 'Billing',
url: undefined,
@@ -1864,6 +1906,10 @@ export const resources: NavMenuConstant = {
name: 'Migrate to Supabase',
url: '/guides/resources/migrating-to-supabase',
items: [
+ {
+ name: 'Auth0',
+ url: '/guides/resources/migrating-to-supabase/auth0',
+ },
{
name: 'Firebase Auth',
url: '/guides/resources/migrating-to-supabase/firebase-auth',
diff --git a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.tsx b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.tsx
index 3b8556bd348..95dc17e710f 100644
--- a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.tsx
+++ b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.tsx
@@ -1,10 +1,9 @@
import { memo } from 'react'
-import NavigationMenuHome from './HomeMenu'
import NavigationMenuGuideList from './NavigationMenuGuideList'
import NavigationMenuRefList from './NavigationMenuRefList'
+import { useCloseMenuOnRouteChange } from './NavigationMenu.utils'
enum MenuId {
- Home = 'home',
GettingStarted = 'gettingstarted',
Database = 'database',
Api = 'api',
@@ -44,10 +43,6 @@ interface BaseMenu {
type: string
}
-interface HomeMenu extends BaseMenu {
- type: 'home'
-}
-
interface GuideMenu extends BaseMenu {
type: 'guide'
}
@@ -59,13 +54,9 @@ interface ReferenceMenu extends BaseMenu {
specFile?: string
}
-type Menu = HomeMenu | GuideMenu | ReferenceMenu
+type Menu = GuideMenu | ReferenceMenu
const menus: Menu[] = [
- {
- id: MenuId.Home,
- type: 'home',
- },
{
id: MenuId.GettingStarted,
type: 'guide',
@@ -243,15 +234,15 @@ const menus: Menu[] = [
},
]
-function getMenuById(id: MenuId) {
- return menus.find((menu) => menu.id === id) ?? menus.find((menu) => menu.id === MenuId.Home)
+export function getMenuById(id: MenuId) {
+ return menus.find((menu) => menu.id === id)
}
-function getMenuElement(menu: Menu) {
+function getMenuElement(menu: Menu | undefined) {
+ if (!menu) throw Error('No menu found for this menuId')
+
const menuType = menu.type
switch (menuType) {
- case 'home':
- return
case 'guide':
return
case 'reference':
@@ -264,7 +255,7 @@ function getMenuElement(menu: Menu) {
/>
)
default:
- throw new Error(`Unknown menu type '${menuType}'`)
+ return null
}
}
@@ -272,6 +263,8 @@ const NavigationMenu = ({ menuId }: { menuId: MenuId }) => {
const level = menuId
const menu = getMenuById(level)
+ useCloseMenuOnRouteChange()
+
return getMenuElement(menu)
}
diff --git a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.utils.ts b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.utils.ts
index 6d7ce92302d..28633a25ab9 100644
--- a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.utils.ts
+++ b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.utils.ts
@@ -1,6 +1,11 @@
+'use client'
+
import { useEffect, useState } from 'react'
-import { ICommonItem } from '~/components/reference/Reference.types'
-import { Json } from '~/types'
+import { usePathname } from 'next/navigation'
+import { MenuId } from '~/components/Navigation/NavigationMenu/NavigationMenu'
+import type { ICommonItem } from '~/components/reference/Reference.types'
+import type { Json } from '~/types'
+import { menuState } from '../../../hooks/useMenuState'
export function getPathWithoutHash(relativePath: string) {
return new URL(relativePath, 'http://placeholder').pathname
@@ -93,3 +98,46 @@ export function useSpec(specFile?: string) {
return spec
}
+
+export const useCloseMenuOnRouteChange = () => {
+ const pathname = usePathname()
+
+ useEffect(() => {
+ menuState.setMenuMobileOpen(false)
+ }, [pathname])
+}
+
+export const getMenuId = (pathname: string | null) => {
+ pathname = (pathname ??= '').replace(/^\/guides\//, '')
+
+ switch (true) {
+ case pathname.startsWith('ai'):
+ return MenuId.Ai
+ case pathname.startsWith('api'):
+ return MenuId.Api
+ case pathname.startsWith('auth'):
+ return MenuId.Auth
+ case pathname.startsWith('cli'):
+ return MenuId.Cli
+ case pathname.startsWith('database'):
+ return MenuId.Database
+ case pathname.startsWith('functions'):
+ return MenuId.Functions
+ case pathname.startsWith('getting-started'):
+ return MenuId.GettingStarted
+ case pathname.startsWith('graphql'):
+ return MenuId.Graphql
+ case pathname.startsWith('platform'):
+ return MenuId.Platform
+ case pathname.startsWith('realtime'):
+ return MenuId.Realtime
+ case pathname.startsWith('resources'):
+ return MenuId.Resources
+ case pathname.startsWith('self-hosting'):
+ return MenuId.SelfHosting
+ case pathname.startsWith('storage'):
+ return MenuId.Storage
+ default:
+ return MenuId.GettingStarted
+ }
+}
diff --git a/apps/docs/components/Navigation/NavigationMenu/NavigationMenuCliList.tsx b/apps/docs/components/Navigation/NavigationMenu/NavigationMenuCliList.tsx
index 7cba84fcba4..b5f44986898 100644
--- a/apps/docs/components/Navigation/NavigationMenu/NavigationMenuCliList.tsx
+++ b/apps/docs/components/Navigation/NavigationMenu/NavigationMenuCliList.tsx
@@ -1,13 +1,11 @@
import Link from 'next/link'
-import { useRouter } from 'next/router'
import { IconChevronLeft } from 'ui'
+
+import { BASE_PATH } from '~/lib/constants'
+import clientLibsCommon from '~/spec/common-cli.yml' assert { type: 'yml' }
import * as NavItems from './NavigationMenu.constants'
-import clientLibsCommon from '~/spec/common-cli.yml' assert { type: 'yml' }
-
const NavigationMenuCliList = ({ currentLevel, setLevel, id }) => {
- const router = useRouter()
-
const menu = NavItems[id]
const FunctionLink = ({
@@ -26,7 +24,7 @@ const NavigationMenuCliList = ({ currentLevel, setLevel, id }) => {
href={`#${id}`}
className="cursor-pointer transition text-foreground-lighter text-sm hover:text-brand flex gap-3"
>
- {icon && }
+ {icon && }
{title}
@@ -113,7 +111,7 @@ const NavigationMenuCliList = ({ currentLevel, setLevel, id }) => {
diff --git a/apps/docs/components/Navigation/NavigationMenu/NavigationMenuGuideList.tsx b/apps/docs/components/Navigation/NavigationMenu/NavigationMenuGuideList.tsx
index 97e96e4f842..dc1d852bb3d 100644
--- a/apps/docs/components/Navigation/NavigationMenu/NavigationMenuGuideList.tsx
+++ b/apps/docs/components/Navigation/NavigationMenu/NavigationMenuGuideList.tsx
@@ -1,14 +1,14 @@
+'use client'
+
import * as Accordion from '@radix-ui/react-accordion'
-import { useRouter } from 'next/router'
import * as NavItems from './NavigationMenu.constants'
-import { getPathWithoutHash } from './NavigationMenu.utils'
import NavigationMenuGuideListItems from './NavigationMenuGuideListItems'
+import { usePathname } from 'next/navigation'
const NavigationMenuGuideList = ({ id }: { id: string }) => {
- const path = useRouter().asPath
- const url = getPathWithoutHash(path)
- const firstLevelRoute = url?.split('/')?.slice(0, 4)?.join('/')
+ const pathname = usePathname()
+ const firstLevelRoute = pathname?.split('/')?.slice(0, 4)?.join('/')
const menu = NavItems[id]
diff --git a/apps/docs/components/Navigation/NavigationMenu/NavigationMenuGuideListItems.tsx b/apps/docs/components/Navigation/NavigationMenu/NavigationMenuGuideListItems.tsx
index 0a2a7d6f9fc..f50c663887e 100644
--- a/apps/docs/components/Navigation/NavigationMenu/NavigationMenuGuideListItems.tsx
+++ b/apps/docs/components/Navigation/NavigationMenu/NavigationMenuGuideListItems.tsx
@@ -1,27 +1,25 @@
import * as Accordion from '@radix-ui/react-accordion'
-import { ChevronLeft } from 'lucide-react'
+import { usePathname } from 'next/navigation'
import { useTheme } from 'next-themes'
import Image from 'next/legacy/image'
import Link from 'next/link'
-import { useRouter } from 'next/router'
import React, { useEffect, useRef } from 'react'
-import HomeMenuIconPicker from './HomeMenuIconPicker'
-import { getPathWithoutHash } from './NavigationMenu.utils'
+import MenuIconPicker from './MenuIconPicker'
const HeaderLink = React.memo(function HeaderLink(props: {
title: string
id: string
url: string
}) {
- const router = useRouter()
+ const pathname = usePathname()
return (
{props.title ?? props.id}
@@ -30,10 +28,10 @@ const HeaderLink = React.memo(function HeaderLink(props: {
})
const ContentAccordionLink = React.memo(function ContentAccordionLink(props: any) {
- const router = useRouter()
+ const pathname = usePathname()
const { resolvedTheme } = useTheme()
- const activeItem = props.subItem.url === getPathWithoutHash(router.asPath)
- const activeItemRef = useRef(null)
+ const activeItem = props.subItem.url === pathname
+ const activeItemRef = useRef(null)
const LinkContainer = (props) => {
return (
@@ -77,11 +75,8 @@ const ContentAccordionLink = React.memo(function ContentAccordionLink(props: any
>
{props.subItem.icon && (
@@ -99,7 +94,7 @@ const ContentAccordionLink = React.memo(function ContentAccordionLink(props: any
href={`${subSubItem.url}`}
className={[
'cursor-pointer transition text-sm',
- subSubItem.url === getPathWithoutHash(router.asPath)
+ subSubItem.url === pathname
? 'text-brand'
: 'hover:text-brand text-foreground-lighter',
].join(' ')}
@@ -117,7 +112,7 @@ const ContentAccordionLink = React.memo(function ContentAccordionLink(props: any
})
const ContentLink = React.memo(function ContentLink(props: any) {
- const router = useRouter()
+ const pathname = usePathname()
return (
@@ -125,13 +120,13 @@ const ContentLink = React.memo(function ContentLink(props: any) {
href={props.url}
className={[
'cursor-pointer transition text-sm',
- props.url === router.asPath
+ props.url === pathname
? 'text-brand-link'
: 'hover:text-foreground text-foreground-lighter',
].join(' ')}
>
{props.icon && (
-
+
)}
{props.name}
@@ -144,24 +139,9 @@ const Content = (props) => {
return (
-
-
- Back to Home
-
-
-
+
diff --git a/apps/docs/components/Navigation/NavigationMenu/NavigationMenuRefListItems.tsx b/apps/docs/components/Navigation/NavigationMenu/NavigationMenuRefListItems.tsx
index 20b6ca58861..4d42b905c1d 100644
--- a/apps/docs/components/Navigation/NavigationMenu/NavigationMenuRefListItems.tsx
+++ b/apps/docs/components/Navigation/NavigationMenu/NavigationMenuRefListItems.tsx
@@ -1,20 +1,19 @@
+'use client'
+
import * as Accordion from '@radix-ui/react-accordion'
-import Link from 'next/link'
-import { useRouter } from 'next/router'
-import { IconChevronLeft, IconChevronUp, cn } from 'ui'
-import * as NavItems from './NavigationMenu.constants'
-
+import { ChevronUp } from 'lucide-react'
import Image from 'next/legacy/image'
-
+import { Fragment, memo } from 'react'
+import { cn } from 'ui'
import RevVersionDropdown from '~/components/RefVersionDropdown'
+import type { ICommonItem, ICommonSection } from '~/components/reference/Reference.types'
import { menuState, useMenuActiveRefId } from '~/hooks/useMenuState'
-
-import React, { Fragment } from 'react'
-import { ICommonItem, ICommonSection } from '~/components/reference/Reference.types'
-import HomeMenuIconPicker from './HomeMenuIconPicker'
+import { BASE_PATH } from '~/lib/constants'
+import MenuIconPicker from './MenuIconPicker'
+import * as NavItems from './NavigationMenu.constants'
import { deepFilterSections } from './NavigationMenu.utils'
-const HeaderLink = React.memo(function HeaderLink(props: any) {
+const HeaderLink = memo(function HeaderLink(props: any) {
return (
{props.title ?? props.id}
@@ -34,7 +33,7 @@ interface FunctionLinkProps {
onClick?: () => void
}
-const FunctionLink = React.memo(function FunctionLink({
+const FunctionLink = memo(function FunctionLink({
title,
id,
icon,
@@ -44,10 +43,9 @@ const FunctionLink = React.memo(function FunctionLink({
isSubItem = false,
onClick = () => {},
}: FunctionLinkProps) {
- const router = useRouter()
const activeAccordionItem = useMenuActiveRefId()
- const url = `${router.basePath}${basePath}/${slug}`
+ const url = `${BASE_PATH}${basePath}/${slug}`
const active = activeAccordionItem === id
return (
@@ -61,7 +59,10 @@ const FunctionLink = React.memo(function FunctionLink({
onClick={(e) => {
e.preventDefault()
history.pushState({}, '', url)
- document.getElementById(slug)?.scrollIntoView()
+ const reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches
+ document.getElementById(slug)?.scrollIntoView({
+ behavior: reduceMotion ? 'auto' : 'smooth',
+ })
onClick()
}}
className={cn(
@@ -70,7 +71,7 @@ const FunctionLink = React.memo(function FunctionLink({
active ? 'text-brand' : 'text-foreground-lighter'
)}
>
- {icon && }
+ {icon && }
{title}
{active && !isSubItem && (
)}
{isParent && (
-
@@ -94,7 +95,7 @@ export interface RenderLinkProps {
basePath: string
}
-const RenderLink = React.memo(function RenderLink({ section, basePath }: RenderLinkProps) {
+const RenderLink = memo(function RenderLink({ section, basePath }: RenderLinkProps) {
const activeAccordionItem = useMenuActiveRefId()
if (!('items' in section)) {
@@ -181,22 +182,8 @@ const NavigationMenuRefListItems = ({
return (
-
-
-
Back to Main Menu
-
-
+
@@ -223,4 +210,4 @@ const NavigationMenuRefListItems = ({
)
}
-export default React.memo(NavigationMenuRefListItems)
+export default memo(NavigationMenuRefListItems)
diff --git a/apps/docs/components/Navigation/NavigationMenu/TopNavBar.tsx b/apps/docs/components/Navigation/NavigationMenu/TopNavBar.tsx
index 7be6e326264..0b72eeb9e57 100644
--- a/apps/docs/components/Navigation/NavigationMenu/TopNavBar.tsx
+++ b/apps/docs/components/Navigation/NavigationMenu/TopNavBar.tsx
@@ -1,108 +1,151 @@
-import { useTheme } from 'next-themes'
-import Image from 'next/legacy/image'
+import { FC, memo, useState } from 'react'
import Link from 'next/link'
-import { FC } from 'react'
-import { Button, IconCommand, IconGitHub, IconSearch } from 'ui'
-import { SearchButton } from 'ui-patterns/Cmdk'
+import dynamic from 'next/dynamic'
+
import { useIsLoggedIn, useIsUserLoading } from 'common'
-import { ThemeToggle } from 'ui-patterns/ThemeToggle'
+import { SearchButton } from 'ui-patterns/Cmdk'
+import { Button, buttonVariants, cn } from 'ui'
+import { Command, Search, Menu } from 'lucide-react'
+
+import Image from 'next/image'
+
+import GlobalNavigationMenu from './GlobalNavigationMenu'
+const GlobalMobileMenu = dynamic(() => import('./GlobalMobileMenu'))
+const TopNavDropdown = dynamic(() => import('./TopNavDropdown'))
const TopNavBar: FC = () => {
const isLoggedIn = useIsLoggedIn()
const isUserLoading = useIsUserLoading()
- const { resolvedTheme } = useTheme()
+ const [mobileMenuOpen, setMobileMenuOpen] = useState(false)
return (
-
-
-
-
-
- DOCS
-
-
-
-
-
-
-
-
+ <>
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
setMobileMenuOpen(!mobileMenuOpen)}
+ >
+
+
+
+
+
-
-
-
+
+
+ >
)
}
+
+const HeaderLogo = memo(() => {
+ return (
+
+
+
+ DOCS
+
+ )
+})
+
+HeaderLogo.displayName = 'HeaderLogo'
+
+TopNavBar.displayName = 'TopNavBar'
+
export default TopNavBar
diff --git a/apps/docs/components/Navigation/NavigationMenu/TopNavDropdown.tsx b/apps/docs/components/Navigation/NavigationMenu/TopNavDropdown.tsx
new file mode 100644
index 00000000000..5b102255a38
--- /dev/null
+++ b/apps/docs/components/Navigation/NavigationMenu/TopNavDropdown.tsx
@@ -0,0 +1,116 @@
+'use client'
+
+import React, { Fragment } from 'react'
+import Link from 'next/link'
+import { useTheme } from 'next-themes'
+import { Menu } from 'lucide-react'
+import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuGroup,
+ DropdownMenuItem,
+ DropdownMenuLabel,
+ DropdownMenuRadioGroup,
+ DropdownMenuRadioItem,
+ DropdownMenuSeparator,
+ DropdownMenuTrigger,
+ Theme,
+ buttonVariants,
+ cn,
+ themes,
+} from 'ui'
+
+import MenuIconPicker from './MenuIconPicker'
+
+const menu = [
+ [
+ {
+ label: 'Supabase.com',
+ icon: 'home',
+ href: 'https://supabase.com',
+ otherProps: {
+ target: '_blank',
+ rel: 'noreferrer noopener',
+ },
+ },
+ {
+ label: 'GitHub',
+ icon: 'github',
+ href: 'https://github.com/supabase/supabase',
+ otherProps: {
+ target: '_blank',
+ rel: 'noreferrer noopener',
+ },
+ },
+ {
+ label: 'Support',
+ icon: 'support',
+ href: 'https://supabase.com/support',
+ otherProps: {
+ target: '_blank',
+ rel: 'noreferrer noopener',
+ },
+ },
+ ],
+]
+
+const TopNavDropdown = () => {
+ const { theme, setTheme } = useTheme()
+
+ return (
+
+
+
+
+
+
+
+ {menu.map((menuSection, sectionIdx) => (
+
+ {sectionIdx !== 0 && }
+ {menuSection.map((sectionItem, itemIdx) => (
+
+ {}}>
+ {sectionItem.icon && (
+
+ )}
+ {sectionItem.label}
+
+
+ ))}
+
+ ))}
+
+
+ Theme
+ {
+ setTheme(value)
+ }}
+ >
+ {themes
+ .filter((x) => x.value === 'light' || x.value === 'dark' || x.value === 'system')
+ .map((theme: Theme) => (
+
+ {theme.name}
+
+ ))}
+
+
+
+
+ )
+}
+
+export default TopNavDropdown
diff --git a/apps/docs/components/Navigation/SideBar.tsx b/apps/docs/components/Navigation/SideBar.tsx
index e1b957d095e..fcf02a89a98 100644
--- a/apps/docs/components/Navigation/SideBar.tsx
+++ b/apps/docs/components/Navigation/SideBar.tsx
@@ -1,6 +1,6 @@
import Link from 'next/link'
import Image from 'next/legacy/image'
-import { useRouter } from 'next/router'
+import { usePathname } from 'next/navigation'
import { IconChevronRight, IconArrowLeft } from '~/../../packages/ui'
import { REFERENCES } from './NavigationMenu/NavigationMenu.constants'
@@ -8,8 +8,8 @@ import { NavMenuGroup, NavMenuSection } from './Navigation.types'
import * as Accordion from '@radix-ui/react-accordion'
const SideBar = ({ menuItems = [] }: { menuItems: any }) => {
- const { asPath } = useRouter()
- const pathSegments = asPath.split('/')
+ const pathname = usePathname()
+ const pathSegments = pathname.split('/')
const isInReferencePages = pathSegments.includes('reference') && pathSegments.length >= 3
const referenceMeta = pathSegments.length >= 3 ? REFERENCES[pathSegments[2]] : undefined
@@ -18,11 +18,11 @@ const SideBar = ({ menuItems = [] }: { menuItems: any }) => {
const foundItem = group.items.find((section) => {
if (section.items.length > 0) {
const foundSubItem = section.items.find((item) => {
- if (item.url === asPath) return item
+ if (item.url === pathname) return item
})
if (foundSubItem) return section
} else {
- if (section.url === asPath) return section
+ if (section.url === pathname) return section
}
})
if (foundItem) return group
@@ -35,7 +35,7 @@ const SideBar = ({ menuItems = [] }: { menuItems: any }) => {
return undefined
} else {
return section.items.find((item) => {
- if (item.url === asPath) return item
+ if (item.url === pathname) return item
})
}
})
@@ -43,7 +43,7 @@ const SideBar = ({ menuItems = [] }: { menuItems: any }) => {
return (
{isInReferencePages && (
@@ -79,7 +79,7 @@ const SideBar = ({ menuItems = [] }: { menuItems: any }) => {
className={[
'py-1.5 px-5 rounded text-sm transition',
`${
- item.url === asPath
+ item.url === pathname
? 'bg-background text-brand-link'
: 'text-foreground-light hover:text-foreground'
}`,
@@ -118,7 +118,7 @@ const SideBar = ({ menuItems = [] }: { menuItems: any }) => {
className={[
'py-1.5 px-5 rounded text-sm transition',
`${
- section.url === asPath
+ section.url === pathname
? 'bg-background text-brand'
: 'text-foreground-light hover:text-foreground'
}`,
@@ -156,7 +156,7 @@ const SideBar = ({ menuItems = [] }: { menuItems: any }) => {
className={[
'py-1.5 ml-4 px-5 rounded text-sm transition',
`${
- item.url === asPath
+ item.url === pathname
? 'bg-background text-brand'
: 'text-foreground-light hover:text-foreground'
}`,
diff --git a/apps/docs/components/Options.tsx b/apps/docs/components/Options.tsx
index feb2f5aa291..bf8fe66baeb 100644
--- a/apps/docs/components/Options.tsx
+++ b/apps/docs/components/Options.tsx
@@ -50,7 +50,7 @@ const Option: FC
= (props) => {
flex flex-col gap-3
"
>
-
+
{props.name ?? 'no-name'}
diff --git a/apps/docs/components/Params.tsx b/apps/docs/components/Params.tsx
index b3ea6721498..28e20391744 100644
--- a/apps/docs/components/Params.tsx
+++ b/apps/docs/components/Params.tsx
@@ -8,7 +8,7 @@ type IParamProps = any
const Param = ({ name, isOptional, type, description, children, isPrimitive }: IParamProps) => {
return (
-
+
{!isPrimitive && (
{name ?? 'no-name'}
)}
diff --git a/apps/docs/components/ProjectConfigVariables/ProjectConfigVariables.tsx b/apps/docs/components/ProjectConfigVariables/ProjectConfigVariables.tsx
index a9f18ad4e30..dc0d637cba4 100644
--- a/apps/docs/components/ProjectConfigVariables/ProjectConfigVariables.tsx
+++ b/apps/docs/components/ProjectConfigVariables/ProjectConfigVariables.tsx
@@ -1,11 +1,35 @@
-import { useIsLoggedIn, useIsUserLoading } from 'common'
+'use client'
+
+import type {
+ Branch,
+ Org,
+ Project,
+ Variable,
+} from '~/components/ProjectConfigVariables/ProjectConfigVariables.utils'
+import type { ProjectApiData } from '~/lib/fetch/projectApi'
+
+import { Copy, Check } from 'lucide-react'
import Link from 'next/link'
import { useEffect, useMemo } from 'react'
import CopyToClipboard from 'react-copy-to-clipboard'
import { withErrorBoundary } from 'react-error-boundary'
-import { Button_Shadcn_ as Button, Input_Shadcn_ as Input, cn, IconCopy, IconCheck } from 'ui'
import { proxy, useSnapshot } from 'valtio'
+import { useIsLoggedIn, useIsUserLoading } from 'common'
+import { Button_Shadcn_ as Button, Input_Shadcn_ as Input, cn } from 'ui'
+
+import {
+ ComboBox,
+ ComboBoxOption,
+} from '~/components/ProjectConfigVariables/ProjectConfigVariables.ComboBox'
+import {
+ fromBranchValue,
+ fromOrgProjectValue,
+ prettyFormatVariable,
+ toBranchValue,
+ toDisplayNameOrgProject,
+ toOrgProjectValue,
+} from '~/components/ProjectConfigVariables/ProjectConfigVariables.utils'
import { useCopy } from '~/hooks/useCopy'
import { useBranchesQuery } from '~/lib/fetch/branches'
import { useOrganizationsQuery } from '~/lib/fetch/organizations'
@@ -14,20 +38,6 @@ import { useProjectsQuery } from '~/lib/fetch/projects'
import { LOCAL_STORAGE_KEYS, retrieve, storeOrRemoveNull } from '~/lib/storage'
import { useOnLogout } from '~/lib/userAuth'
-import { ComboBox, ComboBoxOption } from './ProjectConfigVariables.ComboBox'
-import {
- type Branch,
- type Org,
- type Project,
- type Variable,
- fromBranchValue,
- fromOrgProjectValue,
- prettyFormatVariable,
- toBranchValue,
- toDisplayNameOrgProject,
- toOrgProjectValue,
-} from './ProjectConfigVariables.utils'
-
type ProjectOrgDataState =
| 'userLoading'
| 'loggedOut'
@@ -61,7 +71,6 @@ const projectsStore = proxy({
storeOrRemoveNull('local', LOCAL_STORAGE_KEYS.SAVED_ORG, org?.id.toString())
projectsStore.selectedProject = project
- // @ts-ignore -- problem in OpenAPI spec -- project has ref property
storeOrRemoveNull('local', LOCAL_STORAGE_KEYS.SAVED_PROJECT, project?.ref)
},
selectedBranch: null as Branch | null,
@@ -114,7 +123,6 @@ function OrgProjectSelector() {
: projects.map((project) => {
const organization = organizations.find((org) => org.id === project.organization_id)
return {
- // @ts-ignore -- problem in OpenAPI spec -- project has ref property
id: project.ref,
value: toOrgProjectValue(organization, project),
displayName: toDisplayNameOrgProject(organization, project),
@@ -131,9 +139,7 @@ function OrgProjectSelector() {
let storedOrg: Org
let storedProject: Project
if (storedMaybeOrgId && storedMaybeProjectRef) {
- // @ts-ignore -- problem in OpenAPI spec -- org id is returned as number, not string
storedOrg = organizations.find((org) => org.id === Number(storedMaybeOrgId))
- // @ts-ignore -- problem in OpenAPI spec -- project has ref property
storedProject = projects.find((project) => project.ref === storedMaybeProjectRef)
}
@@ -165,7 +171,6 @@ function OrgProjectSelector() {
if (!orgId || !projectRef) return
const org = organizations.find((org) => org.id === orgId)
- // @ts-ignore -- problem in OpenAPI spec -- project has ref property
const project = projects.find((project) => project.ref === projectRef)
if (org && project && project.organization_id === org.id) {
@@ -182,11 +187,9 @@ function BranchSelector() {
const { selectedProject, selectedBranch, setSelectedBranch } = useSnapshot(projectsStore)
- // @ts-ignore -- problem in OpenAPI spec -- project has is_branch_enabled property
const hasBranches = selectedProject?.is_branch_enabled ?? false
const { data, isPending, isError } = useBranchesQuery(
- // @ts-ignore -- problem in OpenAPI spec -- project has ref property
{ projectRef: selectedProject?.ref },
{ enabled: isLoggedIn && hasBranches }
)
@@ -263,9 +266,7 @@ function VariableView({ variable, className }: { variable: Variable; className?:
const { selectedProject, selectedBranch } = useSnapshot(projectsStore)
- // @ts-ignore -- problem in OpenAPI spec -- project has is_branch-enabled property
const hasBranches = selectedProject?.is_branch_enabled ?? false
- // @ts-ignore -- problem in OpenAPI spec -- project has ref property
const ref = hasBranches ? selectedBranch?.project_ref : selectedProject?.ref
const {
@@ -279,6 +280,17 @@ function VariableView({ variable, className }: { variable: Variable; className?:
{ enabled: isLoggedIn && !!ref }
)
+ function isInvalid(apiData: ProjectApiData) {
+ switch (variable) {
+ case 'url':
+ return !apiData.autoApiService.endpoint
+ case 'anonKey':
+ // If the anon key is not available, the backend may return the string:
+ // You're using an older version of Supabase. Create a new project for the latest Auth features.
+ return /older version/.test(apiData.autoApiService.defaultApiKey)
+ }
+ }
+
const stateSummary: VariableDataState = isUserLoading
? 'userLoading'
: !isLoggedIn
@@ -287,7 +299,7 @@ function VariableView({ variable, className }: { variable: Variable; className?:
? 'loggedIn.noSelectedProject'
: isPending
? 'loggedIn.selectedProject.dataPending'
- : isError
+ : isError || isInvalid(apiData)
? 'loggedIn.selectedProject.dataError'
: 'loggedIn.selectedProject.dataSuccess'
@@ -331,7 +343,7 @@ function VariableView({ variable, className }: { variable: Variable; className?:
onClick={handleCopy}
aria-label="Copy"
>
- {copied ? : }
+ {copied ? : }
diff --git a/apps/docs/components/RealtimeLimitsEstimator/index.tsx b/apps/docs/components/RealtimeLimitsEstimator/index.tsx
index 34fe3d20a42..aaabdd71fb0 100644
--- a/apps/docs/components/RealtimeLimitsEstimator/index.tsx
+++ b/apps/docs/components/RealtimeLimitsEstimator/index.tsx
@@ -1,3 +1,5 @@
+'use client'
+
import { lazy, Suspense } from 'react'
const Estimator = lazy(() => import('./RealtimeLimitsEstimator'))
diff --git a/apps/docs/components/RefVersionDropdown.tsx b/apps/docs/components/RefVersionDropdown.tsx
index dbe99840640..19c92b28898 100644
--- a/apps/docs/components/RefVersionDropdown.tsx
+++ b/apps/docs/components/RefVersionDropdown.tsx
@@ -1,4 +1,4 @@
-import { useRouter } from 'next/router'
+import { usePathname, useRouter } from 'next/navigation'
import {
Badge,
DropdownMenu,
@@ -11,8 +11,9 @@ import {
import { REFERENCES } from './Navigation/NavigationMenu/NavigationMenu.constants'
const RevVersionDropdown = () => {
- const { asPath, push } = useRouter()
- const pathSegments = asPath.split('/')
+ const pathname = usePathname()
+ const { push } = useRouter()
+ const pathSegments = pathname.split('/')
const library = pathSegments.length >= 3 ? pathSegments[2] : undefined
const libraryMeta = REFERENCES?.[library] ?? undefined
diff --git a/apps/docs/components/RegionsList.tsx b/apps/docs/components/RegionsList.tsx
new file mode 100644
index 00000000000..0f9826046b2
--- /dev/null
+++ b/apps/docs/components/RegionsList.tsx
@@ -0,0 +1,14 @@
+import { AWS_REGIONS } from 'shared-data'
+
+export function RegionsList() {
+ return (
+
+ {Object.keys(AWS_REGIONS).map((region) => (
+
+ {AWS_REGIONS[region].displayName}
+ {AWS_REGIONS[region].code}
+
+ ))}
+
+ )
+}
diff --git a/apps/docs/components/StepHikeCompact/index.tsx b/apps/docs/components/StepHikeCompact/index.tsx
index fd346c00711..a20e5f8d4bb 100644
--- a/apps/docs/components/StepHikeCompact/index.tsx
+++ b/apps/docs/components/StepHikeCompact/index.tsx
@@ -1,4 +1,3 @@
-//import { Step } from 'next-seo/lib/types'
import { FC, PropsWithChildren } from 'react'
import { cn } from 'ui'
diff --git a/apps/docs/components/index.tsx b/apps/docs/components/index.tsx
index 8fcca7efa37..c3fc9b95741 100644
--- a/apps/docs/components/index.tsx
+++ b/apps/docs/components/index.tsx
@@ -4,11 +4,10 @@
// Basic UI things
import Link from 'next/link'
-import { Accordion, Admonition, Alert, Button, CodeBlock, markdownComponents } from 'ui'
+import { Accordion, Admonition, Alert, Button, CodeBlock, Image, markdownComponents } from 'ui'
import { GlassPanel } from 'ui-patterns/GlassPanel'
import { IconPanel } from 'ui-patterns/IconPanel'
-import { ThemeImage } from 'ui-patterns/ThemeImage'
-import { TabPanel, Tabs } from '~/components/Tabs'
+import { TabPanel, Tabs } from '~/features/ui/Tabs'
// Common components
import { CH } from '@code-hike/mdx/components'
@@ -70,7 +69,7 @@ import {
IconMenuSelfHosting,
IconMenuStorage,
IconMenuSwift,
-} from './Navigation/NavigationMenu/HomeMenuIcons'
+} from './Navigation/NavigationMenu/MenuIcons'
// Heavy/rare (lazy-loaded)
import SqlToRest from '@ui-patterns/SqlToRest'
@@ -78,7 +77,6 @@ import { AppleSecretGenerator } from './AppleSecretGenerator'
import { AuthSmsProviderConfig } from './AuthSmsProviderConfig'
import { Extensions } from './Extensions'
import { JwtGenerator } from './JwtGenerator'
-import { Mermaid } from './Mermaid'
import { RealtimeLimitsEstimator } from './RealtimeLimitsEstimator'
const components = {
@@ -143,11 +141,10 @@ const components = {
IconMenuStorage,
IconMenuSwift,
IconPanel,
- Image: (props: any) =>
,
+ Image: (props: any) =>
,
JwtGenerator,
KotlinProjectSetup,
Link,
- Mermaid,
MigrationWarnings,
NavData,
OAuthPkceFlow,
diff --git a/apps/docs/components/reference/ApiOperationSection.tsx b/apps/docs/components/reference/ApiOperationSection.tsx
index f6911560c9c..e1bb2f03efc 100644
--- a/apps/docs/components/reference/ApiOperationSection.tsx
+++ b/apps/docs/components/reference/ApiOperationSection.tsx
@@ -1,7 +1,7 @@
import { CodeBlock } from 'ui'
import Param from '~/components/Params'
+import { Tabs, TabPanel } from '~/features/ui/Tabs'
import RefSubLayout from '~/layouts/ref/RefSubLayout'
-import { Tabs, TabPanel } from '~/components/Tabs'
import { ReactMarkdown } from 'react-markdown/lib/react-markdown'
const ApiOperationSection = (props) => {
diff --git a/apps/docs/components/reference/CLICommandSection.tsx b/apps/docs/components/reference/CLICommandSection.tsx
index 6997aeaca7c..6e3f81b4bbf 100644
--- a/apps/docs/components/reference/CLICommandSection.tsx
+++ b/apps/docs/components/reference/CLICommandSection.tsx
@@ -1,10 +1,10 @@
import ReactMarkdown from 'react-markdown'
import { CodeBlock, IconChevronRight } from 'ui'
-import spec from '~/spec/cli_v1_commands.yaml' assert { type: 'yml' }
import Options from '~/components/Options'
import Param from '~/components/Params'
-import { Tabs, TabPanel } from '~/components/Tabs'
+import { Tabs, TabPanel } from '~/features/ui/Tabs'
import RefSubLayout from '~/layouts/ref/RefSubLayout'
+import spec from '~/spec/cli_v1_commands.yaml' assert { type: 'yml' }
import RefDetailCollapse from './RefDetailCollapse'
export type Flag = {
@@ -80,7 +80,7 @@ const CliCommandSection = (props) => {
{command.description}
) : (
-
+
{command.summary}
)}
diff --git a/apps/docs/components/reference/OldVersionAlert.tsx b/apps/docs/components/reference/OldVersionAlert.tsx
index 993dbd0fb4d..5c3f4a04664 100644
--- a/apps/docs/components/reference/OldVersionAlert.tsx
+++ b/apps/docs/components/reference/OldVersionAlert.tsx
@@ -1,21 +1,22 @@
import Link from 'next/link'
-import { useRouter } from 'next/router'
+import { usePathname } from 'next/navigation'
import { Admonition } from 'ui-patterns/admonition'
+
import { useMenuActiveRefId } from '~/hooks/useMenuState'
-import { ICommonSection } from './Reference.types'
+import type { ICommonSection } from './Reference.types'
export interface OldVersionAlertProps {
sections: ICommonSection[]
}
const OldVersionAlert = ({ sections }: OldVersionAlertProps) => {
- const router = useRouter()
+ const pathname = usePathname()
const activeRefId = useMenuActiveRefId()
const activeSection = sections.find(({ id }) => id === activeRefId)
// Remove the version number from URL to get the latest
- const latestVersionUrl = router.asPath
+ const latestVersionUrl = pathname
.split('/')
.slice(0, -2)
.concat(activeSection ? [activeSection.slug] : [])
diff --git a/apps/docs/components/reference/RefFunctionSection.tsx b/apps/docs/components/reference/RefFunctionSection.tsx
index 8c9d9fecd8a..0a101e55018 100644
--- a/apps/docs/components/reference/RefFunctionSection.tsx
+++ b/apps/docs/components/reference/RefFunctionSection.tsx
@@ -7,7 +7,7 @@ import Param from '~/components/Params'
import RefDetailCollapse from '~/components/reference/RefDetailCollapse'
import RefSubLayout from '~/layouts/ref/RefSubLayout'
import { extractTsDocNode, generateParameters } from '~/lib/refGenerator/helpers'
-import { IRefFunctionSection } from './Reference.types'
+import type { IRefFunctionSection } from './Reference.types'
const RefFunctionSection: React.FC
= (props) => {
const item = props.spec.functions.find((x: any) => x.id === props.funcData.id)
diff --git a/apps/docs/components/reference/RefSEO.tsx b/apps/docs/components/reference/RefSEO.tsx
index 237ecec3f15..6a468b713c3 100644
--- a/apps/docs/components/reference/RefSEO.tsx
+++ b/apps/docs/components/reference/RefSEO.tsx
@@ -1,5 +1,5 @@
import { NextSeo } from 'next-seo'
-import { useRouter } from 'next/router'
+import { useRouter } from 'next/compat/router'
function RefSEO({ title }) {
const router = useRouter()
diff --git a/apps/docs/components/reference/RefSectionHandler.tsx b/apps/docs/components/reference/RefSectionHandler.tsx
index b3b189c9ce0..91e73b90dc4 100644
--- a/apps/docs/components/reference/RefSectionHandler.tsx
+++ b/apps/docs/components/reference/RefSectionHandler.tsx
@@ -1,5 +1,5 @@
+import { useRouter } from 'next/compat/router'
import Head from 'next/head'
-import { useRouter } from 'next/router'
import { useEffect } from 'react'
import { type MenuId } from '~/components/Navigation/NavigationMenu/NavigationMenu'
@@ -10,8 +10,8 @@ import RefSubLayout from '~/layouts/ref/RefSubLayout'
import ApiOperationSection from './ApiOperationSection'
import CliCommandSection from './CLICommandSection'
import OldVersionAlert from './OldVersionAlert'
-import { IAPISpec, ICommonSection, IRefStaticDoc, ISpec, TypeSpec } from './Reference.types'
-import { MainSkeleton } from '~/layouts/MainSkeleton'
+import type { IAPISpec, ICommonSection, IRefStaticDoc, ISpec, TypeSpec } from './Reference.types'
+import { SidebarSkeleton, TopNavSkeleton } from '~/layouts/MainSkeleton'
import MgmtApiOperationSection from '~/components/reference/MgmtApiOperationSection'
interface RefSectionHandlerProps {
@@ -80,66 +80,68 @@ const RefSectionHandler = (props: RefSectionHandlerProps) => {
-
- {props.isOldVersion && }
-
- {props.sections.map((section, i) => {
- const sectionType = section.type
- switch (sectionType) {
- case 'markdown':
- const markdownData = props.pageProps.docs.find((doc) => doc.id === section.id)
+
+
+ {props.isOldVersion && }
+
+ {props.sections.map((section, i) => {
+ const sectionType = section.type
+ switch (sectionType) {
+ case 'markdown':
+ const markdownData = props.pageProps.docs.find((doc) => doc.id === section.id)
- return (
-
- )
- case 'function':
- return (
-
- )
- case 'cli-command':
- return (
-
- )
- case 'operation':
- if (props.type === 'mgmt-api') {
return (
-
+ )
+ case 'function':
+ return (
+
)
- } else {
+ case 'cli-command':
return (
-
)
- }
- default:
- throw new Error(`Unknown common section type '${sectionType}'`)
- }
- })}
-
-
+ case 'operation':
+ if (props.type === 'mgmt-api') {
+ return (
+
+ )
+ } else {
+ return (
+
+ )
+ }
+ default:
+ throw new Error(`Unknown common section type '${sectionType}'`)
+ }
+ })}
+
+
+
>
)
}
diff --git a/apps/docs/components/reference/Reference.types.ts b/apps/docs/components/reference/Reference.types.ts
index e56647d9c18..1a52db858b2 100644
--- a/apps/docs/components/reference/Reference.types.ts
+++ b/apps/docs/components/reference/Reference.types.ts
@@ -1,4 +1,4 @@
-import { enrichedOperation } from '~/lib/refGenerator/helpers'
+import type { enrichedOperation } from '~/lib/refGenerator/helpers'
export interface ISpec {
openref: any
diff --git a/apps/docs/content/guides/ai/choosing-compute-addon.mdx b/apps/docs/content/guides/ai/choosing-compute-addon.mdx
index fec64e9167f..24f339d2742 100644
--- a/apps/docs/content/guides/ai/choosing-compute-addon.mdx
+++ b/apps/docs/content/guides/ai/choosing-compute-addon.mdx
@@ -30,18 +30,18 @@ This benchmark uses the dbpedia-entities-openai-1M dataset containing 1,000,000
>
-| Plan | Vectors | m | ef_construction | ef_search | QPS | Latency Mean | Latency p95 | RAM Usage | RAM |
-| ------ | --------- | --- | --------------- | --------- | ---- | ------------ | ----------- | ---------- | ------ |
-| Micro | 100,000 | 16 | 64 | 60 | 580 | 0.017 sec | 0.024 sec | 1.2 (Swap) | 1 GB |
-| Small | 250,000 | 24 | 64 | 60 | 440 | 0.022 sec | 0.033 sec | 2 GB | 2 GB |
-| Medium | 500,000 | 24 | 64 | 80 | 350 | 0.028 sec | 0.045 sec | 4 GB | 4 GB |
-| Large | 1,000,000 | 32 | 80 | 100 | 270 | 0.073 sec | 0.108 sec | 7 GB | 8 GB |
-| XL | 1,000,000 | 32 | 80 | 100 | 525 | 0.038 sec | 0.059 sec | 9 GB | 16 GB |
-| 2XL | 1,000,000 | 32 | 80 | 100 | 790 | 0.025 sec | 0.037 sec | 9 GB | 32 GB |
-| 4XL | 1,000,000 | 32 | 80 | 100 | 1650 | 0.015 sec | 0.018 sec | 11 GB | 64 GB |
-| 8XL | 1,000,000 | 32 | 80 | 100 | 2690 | 0.015 sec | 0.016 sec | 13 GB | 128 GB |
-| 12XL | 1,000,000 | 32 | 80 | 100 | 3900 | 0.014 sec | 0.016 sec | 13 GB | 192 GB |
-| 16XL | 1,000,000 | 32 | 80 | 100 | 4200 | 0.014 sec | 0.016 sec | 20 GB | 256 GB |
+| Compute Size | Vectors | m | ef_construction | ef_search | QPS | Latency Mean | Latency p95 | RAM Usage | RAM |
+| ------------ | --------- | --- | --------------- | --------- | ---- | ------------ | ----------- | ---------- | ------ |
+| Micro | 100,000 | 16 | 64 | 60 | 580 | 0.017 sec | 0.024 sec | 1.2 (Swap) | 1 GB |
+| Small | 250,000 | 24 | 64 | 60 | 440 | 0.022 sec | 0.033 sec | 2 GB | 2 GB |
+| Medium | 500,000 | 24 | 64 | 80 | 350 | 0.028 sec | 0.045 sec | 4 GB | 4 GB |
+| Large | 1,000,000 | 32 | 80 | 100 | 270 | 0.073 sec | 0.108 sec | 7 GB | 8 GB |
+| XL | 1,000,000 | 32 | 80 | 100 | 525 | 0.038 sec | 0.059 sec | 9 GB | 16 GB |
+| 2XL | 1,000,000 | 32 | 80 | 100 | 790 | 0.025 sec | 0.037 sec | 9 GB | 32 GB |
+| 4XL | 1,000,000 | 32 | 80 | 100 | 1650 | 0.015 sec | 0.018 sec | 11 GB | 64 GB |
+| 8XL | 1,000,000 | 32 | 80 | 100 | 2690 | 0.015 sec | 0.016 sec | 13 GB | 128 GB |
+| 12XL | 1,000,000 | 32 | 80 | 100 | 3900 | 0.014 sec | 0.016 sec | 13 GB | 192 GB |
+| 16XL | 1,000,000 | 32 | 80 | 100 | 4200 | 0.014 sec | 0.016 sec | 20 GB | 256 GB |
Accuracy was 0.99 for benchmarks.
@@ -56,23 +56,23 @@ This benchmark uses the [gist-960](http://corpus-texmex.irisa.fr/) dataset, whic
scrollable
size="small"
type="underlined"
- defaultActiveId="openai1536"
+ defaultActiveId="gist960"
queryGroup="benchmark"
>
-
+
-| Plan | Vectors | m | ef_construction | ef_search | QPS | Latency Mean | Latency p95 | RAM Usage | RAM |
-| ------ | --------- | --- | --------------- | --------- | ---- | ------------ | ----------- | ------------- | ------ |
-| Micro | 30,000 | 16 | 64 | 65 | 430 | 0.024 sec | 0.034 sec | 1.2 GB (Swap) | 1 GB |
-| Small | 100,000 | 32 | 80 | 60 | 260 | 0.040 sec | 0.054 sec | 2.2 GB (Swap) | 2 GB |
-| Medium | 250,000 | 32 | 80 | 90 | 120 | 0.083 sec | 0.106 sec | 4 GB | 4 GB |
-| Large | 500,000 | 32 | 80 | 120 | 160 | 0.063 sec | 0.087 sec | 7 GB | 8 GB |
-| XL | 1,000,000 | 32 | 80 | 200 | 200 | 0.049 sec | 0.072 sec | 13 GB | 16 GB |
-| 2XL | 1,000,000 | 32 | 80 | 200 | 340 | 0.025 sec | 0.029 sec | 17 GB | 32 GB |
-| 4XL | 1,000,000 | 32 | 80 | 200 | 630 | 0.031 sec | 0.050 sec | 18 GB | 64 GB |
-| 8XL | 1,000,000 | 32 | 80 | 200 | 1100 | 0.034 sec | 0.048 sec | 19 GB | 128 GB |
-| 12XL | 1,000,000 | 32 | 80 | 200 | 1420 | 0.041 sec | 0.095 sec | 21 GB | 192 GB |
-| 16XL | 1,000,000 | 32 | 80 | 200 | 1650 | 0.037 sec | 0.081 sec | 23 GB | 256 GB |
+| Compute Size | Vectors | m | ef_construction | ef_search | QPS | Latency Mean | Latency p95 | RAM Usage | RAM |
+| ------------ | --------- | --- | --------------- | --------- | ---- | ------------ | ----------- | ------------- | ------ |
+| Micro | 30,000 | 16 | 64 | 65 | 430 | 0.024 sec | 0.034 sec | 1.2 GB (Swap) | 1 GB |
+| Small | 100,000 | 32 | 80 | 60 | 260 | 0.040 sec | 0.054 sec | 2.2 GB (Swap) | 2 GB |
+| Medium | 250,000 | 32 | 80 | 90 | 120 | 0.083 sec | 0.106 sec | 4 GB | 4 GB |
+| Large | 500,000 | 32 | 80 | 120 | 160 | 0.063 sec | 0.087 sec | 7 GB | 8 GB |
+| XL | 1,000,000 | 32 | 80 | 200 | 200 | 0.049 sec | 0.072 sec | 13 GB | 16 GB |
+| 2XL | 1,000,000 | 32 | 80 | 200 | 340 | 0.025 sec | 0.029 sec | 17 GB | 32 GB |
+| 4XL | 1,000,000 | 32 | 80 | 200 | 630 | 0.031 sec | 0.050 sec | 18 GB | 64 GB |
+| 8XL | 1,000,000 | 32 | 80 | 200 | 1100 | 0.034 sec | 0.048 sec | 19 GB | 128 GB |
+| 12XL | 1,000,000 | 32 | 80 | 200 | 1420 | 0.041 sec | 0.095 sec | 21 GB | 192 GB |
+| 16XL | 1,000,000 | 32 | 80 | 200 | 1650 | 0.037 sec | 0.081 sec | 23 GB | 256 GB |
Accuracy was 0.99 for benchmarks.
@@ -94,18 +94,18 @@ This benchmark uses the [dbpedia-entities-openai-1M](https://huggingface.co/data
>
-| Plan | Vectors | m | ef_construction | ef_search | QPS | Latency Mean | Latency p95 | RAM Usage | RAM |
-| ------ | --------- | --- | --------------- | --------- | ---- | ------------ | ----------- | ------------- | ------ |
-| Micro | 15,000 | 16 | 40 | 40 | 480 | 0.011 sec | 0.016 sec | 1.2 GB (Swap) | 1 GB |
-| Small | 50,000 | 32 | 64 | 100 | 175 | 0.031 sec | 0.051 sec | 2.2 GB (Swap) | 2 GB |
-| Medium | 100,000 | 32 | 64 | 100 | 240 | 0.083 sec | 0.126 sec | 4 GB | 4 GB |
-| Large | 224,482 | 32 | 64 | 100 | 280 | 0.017 sec | 0.028 sec | 8 GB | 8 GB |
-| XL | 500,000 | 24 | 56 | 100 | 360 | 0.055 sec | 0.135 sec | 13 GB | 16 GB |
-| 2XL | 1,000,000 | 24 | 56 | 250 | 560 | 0.036 sec | 0.058 sec | 32 GB | 32 GB |
-| 4XL | 1,000,000 | 24 | 56 | 250 | 950 | 0.021 sec | 0.033 sec | 39 GB | 64 GB |
-| 8XL | 1,000,000 | 24 | 56 | 250 | 1650 | 0.016 sec | 0.023 sec | 40 GB | 128 GB |
-| 12XL | 1,000,000 | 24 | 56 | 250 | 1900 | 0.015 sec | 0.021 sec | 38 GB | 192 GB |
-| 16XL | 1,000,000 | 24 | 56 | 250 | 2200 | 0.015 sec | 0.020 sec | 40 GB | 256 GB |
+| Compute Size | Vectors | m | ef_construction | ef_search | QPS | Latency Mean | Latency p95 | RAM Usage | RAM |
+| ------------ | --------- | --- | --------------- | --------- | ---- | ------------ | ----------- | ------------- | ------ |
+| Micro | 15,000 | 16 | 40 | 40 | 480 | 0.011 sec | 0.016 sec | 1.2 GB (Swap) | 1 GB |
+| Small | 50,000 | 32 | 64 | 100 | 175 | 0.031 sec | 0.051 sec | 2.2 GB (Swap) | 2 GB |
+| Medium | 100,000 | 32 | 64 | 100 | 240 | 0.083 sec | 0.126 sec | 4 GB | 4 GB |
+| Large | 224,482 | 32 | 64 | 100 | 280 | 0.017 sec | 0.028 sec | 8 GB | 8 GB |
+| XL | 500,000 | 24 | 56 | 100 | 360 | 0.055 sec | 0.135 sec | 13 GB | 16 GB |
+| 2XL | 1,000,000 | 24 | 56 | 250 | 560 | 0.036 sec | 0.058 sec | 32 GB | 32 GB |
+| 4XL | 1,000,000 | 24 | 56 | 250 | 950 | 0.021 sec | 0.033 sec | 39 GB | 64 GB |
+| 8XL | 1,000,000 | 24 | 56 | 250 | 1650 | 0.016 sec | 0.023 sec | 40 GB | 128 GB |
+| 12XL | 1,000,000 | 24 | 56 | 250 | 1900 | 0.015 sec | 0.021 sec | 38 GB | 192 GB |
+| 16XL | 1,000,000 | 24 | 56 | 250 | 2200 | 0.015 sec | 0.020 sec | 40 GB | 256 GB |
Accuracy was 0.99 for benchmarks.
@@ -120,15 +120,14 @@ It is possible to upload more vectors to a single table if Memory allows it (for
-
-
-
+
## IVFFlat
@@ -145,34 +144,34 @@ This benchmark uses the dbpedia-entities-openai-1M dataset containing 1,000,000
>
-| Plan | Vectors | Lists | Probes | QPS | Latency Mean | Latency p95 | RAM Usage | RAM |
-| ------ | --------- | ----- | ------ | ---- | ------------ | ----------- | ------------- | ------ |
-| Micro | 100,000 | 500 | 50 | 205 | 0.048 sec | 0.066 sec | 1.2 GB (Swap) | 1 GB |
-| Small | 250,000 | 1000 | 60 | 160 | 0.062 sec | 0.079 sec | 2 GB | 2 GB |
-| Medium | 500,000 | 2000 | 80 | 120 | 0.082 sec | 0.104 sec | 3.2 GB | 4 GB |
-| Large | 1,000,000 | 5000 | 150 | 75 | 0.269 sec | 0.375 sec | 6.5 GB | 8 GB |
-| XL | 1,000,000 | 5000 | 150 | 150 | 0.131 sec | 0.178 sec | 9 GB | 16 GB |
-| 2XL | 1,000,000 | 5000 | 150 | 300 | 0.066 sec | 0.099 sec | 10 GB | 32 GB |
-| 4XL | 1,000,000 | 5000 | 150 | 570 | 0.035 sec | 0.046 sec | 10 GB | 64 GB |
-| 8XL | 1,000,000 | 5000 | 150 | 1400 | 0.023 sec | 0.028 sec | 12 GB | 128 GB |
-| 12XL | 1,000,000 | 5000 | 150 | 1550 | 0.030 sec | 0.039 sec | 12 GB | 192 GB |
-| 16XL | 1,000,000 | 5000 | 150 | 1800 | 0.030 sec | 0.039 sec | 16 GB | 256 GB |
+| Compute Size | Vectors | Lists | Probes | QPS | Latency Mean | Latency p95 | RAM Usage | RAM |
+| ------------ | --------- | ----- | ------ | ---- | ------------ | ----------- | ------------- | ------ |
+| Micro | 100,000 | 500 | 50 | 205 | 0.048 sec | 0.066 sec | 1.2 GB (Swap) | 1 GB |
+| Small | 250,000 | 1000 | 60 | 160 | 0.062 sec | 0.079 sec | 2 GB | 2 GB |
+| Medium | 500,000 | 2000 | 80 | 120 | 0.082 sec | 0.104 sec | 3.2 GB | 4 GB |
+| Large | 1,000,000 | 5000 | 150 | 75 | 0.269 sec | 0.375 sec | 6.5 GB | 8 GB |
+| XL | 1,000,000 | 5000 | 150 | 150 | 0.131 sec | 0.178 sec | 9 GB | 16 GB |
+| 2XL | 1,000,000 | 5000 | 150 | 300 | 0.066 sec | 0.099 sec | 10 GB | 32 GB |
+| 4XL | 1,000,000 | 5000 | 150 | 570 | 0.035 sec | 0.046 sec | 10 GB | 64 GB |
+| 8XL | 1,000,000 | 5000 | 150 | 1400 | 0.023 sec | 0.028 sec | 12 GB | 128 GB |
+| 12XL | 1,000,000 | 5000 | 150 | 1550 | 0.030 sec | 0.039 sec | 12 GB | 192 GB |
+| 16XL | 1,000,000 | 5000 | 150 | 1800 | 0.030 sec | 0.039 sec | 16 GB | 256 GB |
-| Plan | Vectors | Lists | Probes | QPS | Latency Mean | Latency p95 | RAM Usage | RAM |
-| ------ | --------- | ----- | ------ | ---- | ------------ | ----------- | ------------- | ------ |
-| Micro | 100,000 | 500 | 70 | 160 | 0.062 sec | 0.079 sec | 1.2 GB (Swap) | 1 GB |
-| Small | 250,000 | 1000 | 100 | 100 | 0.096 sec | 0.113 sec | 2 GB | 2 GB |
-| Medium | 500,000 | 2000 | 120 | 85 | 0.117 sec | 0.147 sec | 3.2 GB | 4 GB |
-| Large | 1,000,000 | 5000 | 250 | 50 | 0.394 sec | 0.521 sec | 6.5 GB | 8 GB |
-| XL | 1,000,000 | 5000 | 250 | 100 | 0.197 sec | 0.255 sec | 10 GB | 16 GB |
-| 2XL | 1,000,000 | 5000 | 250 | 200 | 0.098 sec | 0.140 sec | 10 GB | 32 GB |
-| 4XL | 1,000,000 | 5000 | 250 | 390 | 0.051 sec | 0.066 sec | 11 GB | 64 GB |
-| 8XL | 1,000,000 | 5000 | 250 | 850 | 0.036 sec | 0.042 sec | 12 GB | 128 GB |
-| 12XL | 1,000,000 | 5000 | 250 | 1000 | 0.043 sec | 0.055 sec | 13 GB | 192 GB |
-| 16XL | 1,000,000 | 5000 | 250 | 1200 | 0.043 sec | 0.055 sec | 16 GB | 256 GB |
+| Compute Size | Vectors | Lists | Probes | QPS | Latency Mean | Latency p95 | RAM Usage | RAM |
+| ------------ | --------- | ----- | ------ | ---- | ------------ | ----------- | ------------- | ------ |
+| Micro | 100,000 | 500 | 70 | 160 | 0.062 sec | 0.079 sec | 1.2 GB (Swap) | 1 GB |
+| Small | 250,000 | 1000 | 100 | 100 | 0.096 sec | 0.113 sec | 2 GB | 2 GB |
+| Medium | 500,000 | 2000 | 120 | 85 | 0.117 sec | 0.147 sec | 3.2 GB | 4 GB |
+| Large | 1,000,000 | 5000 | 250 | 50 | 0.394 sec | 0.521 sec | 6.5 GB | 8 GB |
+| XL | 1,000,000 | 5000 | 250 | 100 | 0.197 sec | 0.255 sec | 10 GB | 16 GB |
+| 2XL | 1,000,000 | 5000 | 250 | 200 | 0.098 sec | 0.140 sec | 10 GB | 32 GB |
+| 4XL | 1,000,000 | 5000 | 250 | 390 | 0.051 sec | 0.066 sec | 11 GB | 64 GB |
+| 8XL | 1,000,000 | 5000 | 250 | 850 | 0.036 sec | 0.042 sec | 12 GB | 128 GB |
+| 12XL | 1,000,000 | 5000 | 250 | 1000 | 0.043 sec | 0.055 sec | 13 GB | 192 GB |
+| 16XL | 1,000,000 | 5000 | 250 | 1200 | 0.043 sec | 0.055 sec | 16 GB | 256 GB |
@@ -190,18 +189,18 @@ This benchmark uses the [gist-960](http://corpus-texmex.irisa.fr/) dataset, whic
>
-| Plan | Vectors | Lists | QPS | Latency Mean | Latency p95 | RAM Usage | RAM |
-| ------ | --------- | ----- | ---- | ------------ | ----------- | ------------- | ------ |
-| Micro | 30,000 | 30 | 75 | 0.065 sec | 0.088 sec | 1.1 GB (Swap) | 1 GB |
-| Small | 100,000 | 100 | 78 | 0.064 sec | 0.092 sec | 1.8 GB | 2 GB |
-| Medium | 250,000 | 250 | 58 | 0.085 sec | 0.129 sec | 3.2 GB | 4 GB |
-| Large | 500,000 | 500 | 55 | 0.088 sec | 0.140 sec | 5 GB | 8 GB |
-| XL | 1,000,000 | 1000 | 110 | 0.046 sec | 0.070 sec | 14 GB | 16 GB |
-| 2XL | 1,000,000 | 1000 | 235 | 0.083 sec | 0.136 sec | 10 GB | 32 GB |
-| 4XL | 1,000,000 | 1000 | 420 | 0.071 sec | 0.106 sec | 11 GB | 64 GB |
-| 8XL | 1,000,000 | 1000 | 815 | 0.072 sec | 0.106 sec | 13 GB | 128 GB |
-| 12XL | 1,000,000 | 1000 | 1150 | 0.052 sec | 0.078 sec | 15.5 GB | 192 GB |
-| 16XL | 1,000,000 | 1000 | 1345 | 0.072 sec | 0.106 sec | 17.5 GB | 256 GB |
+| Compute Size | Vectors | Lists | QPS | Latency Mean | Latency p95 | RAM Usage | RAM |
+| ------------ | --------- | ----- | ---- | ------------ | ----------- | ------------- | ------ |
+| Micro | 30,000 | 30 | 75 | 0.065 sec | 0.088 sec | 1.1 GB (Swap) | 1 GB |
+| Small | 100,000 | 100 | 78 | 0.064 sec | 0.092 sec | 1.8 GB | 2 GB |
+| Medium | 250,000 | 250 | 58 | 0.085 sec | 0.129 sec | 3.2 GB | 4 GB |
+| Large | 500,000 | 500 | 55 | 0.088 sec | 0.140 sec | 5 GB | 8 GB |
+| XL | 1,000,000 | 1000 | 110 | 0.046 sec | 0.070 sec | 14 GB | 16 GB |
+| 2XL | 1,000,000 | 1000 | 235 | 0.083 sec | 0.136 sec | 10 GB | 32 GB |
+| 4XL | 1,000,000 | 1000 | 420 | 0.071 sec | 0.106 sec | 11 GB | 64 GB |
+| 8XL | 1,000,000 | 1000 | 815 | 0.072 sec | 0.106 sec | 13 GB | 128 GB |
+| 12XL | 1,000,000 | 1000 | 1150 | 0.052 sec | 0.078 sec | 15.5 GB | 192 GB |
+| 16XL | 1,000,000 | 1000 | 1345 | 0.072 sec | 0.106 sec | 17.5 GB | 256 GB |
@@ -219,51 +218,50 @@ This benchmark uses the [dbpedia-entities-openai-1M](https://huggingface.co/data
>
-| Plan | Vectors | Lists | QPS | Latency Mean | Latency p95 | RAM Usage | RAM |
-| ------ | --------- | ----- | ---- | ------------ | ----------- | ------------- | ------ |
-| Micro | 20,000 | 40 | 135 | 0.372 sec | 0.412 sec | 1.2 GB (Swap) | 1 GB |
-| Small | 50,000 | 100 | 140 | 0.357 sec | 0.398 sec | 1.8 GB | 2 GB |
-| Medium | 100,000 | 200 | 130 | 0.383 sec | 0.446 sec | 3.7 GB | 4 GB |
-| Large | 250,000 | 500 | 130 | 0.378 sec | 0.434 sec | 7 GB | 8 GB |
-| XL | 500,000 | 1000 | 235 | 0.213 sec | 0.271 sec | 13.5 GB | 16 GB |
-| 2XL | 1,000,000 | 2000 | 380 | 0.133 sec | 0.236 sec | 30 GB | 32 GB |
-| 4XL | 1,000,000 | 2000 | 720 | 0.068 sec | 0.120 sec | 35 GB | 64 GB |
-| 8XL | 1,000,000 | 2000 | 1250 | 0.039 sec | 0.066 sec | 38 GB | 128 GB |
-| 12XL | 1,000,000 | 2000 | 1600 | 0.030 sec | 0.052 sec | 41 GB | 192 GB |
-| 16XL | 1,000,000 | 2000 | 1790 | 0.029 sec | 0.051 sec | 45 GB | 256 GB |
+| Compute Size | Vectors | Lists | QPS | Latency Mean | Latency p95 | RAM Usage | RAM |
+| ------------ | --------- | ----- | ---- | ------------ | ----------- | ------------- | ------ |
+| Micro | 20,000 | 40 | 135 | 0.372 sec | 0.412 sec | 1.2 GB (Swap) | 1 GB |
+| Small | 50,000 | 100 | 140 | 0.357 sec | 0.398 sec | 1.8 GB | 2 GB |
+| Medium | 100,000 | 200 | 130 | 0.383 sec | 0.446 sec | 3.7 GB | 4 GB |
+| Large | 250,000 | 500 | 130 | 0.378 sec | 0.434 sec | 7 GB | 8 GB |
+| XL | 500,000 | 1000 | 235 | 0.213 sec | 0.271 sec | 13.5 GB | 16 GB |
+| 2XL | 1,000,000 | 2000 | 380 | 0.133 sec | 0.236 sec | 30 GB | 32 GB |
+| 4XL | 1,000,000 | 2000 | 720 | 0.068 sec | 0.120 sec | 35 GB | 64 GB |
+| 8XL | 1,000,000 | 2000 | 1250 | 0.039 sec | 0.066 sec | 38 GB | 128 GB |
+| 12XL | 1,000,000 | 2000 | 1600 | 0.030 sec | 0.052 sec | 41 GB | 192 GB |
+| 16XL | 1,000,000 | 2000 | 1790 | 0.029 sec | 0.051 sec | 45 GB | 256 GB |
For 1,000,000 vectors 10 probes results to accuracy of 0.91. And for 500,000 vectors and below 10 probes results to accuracy in the range of 0.95 - 0.99. To increase accuracy, you need to increase the number of probes.
-| Plan | Vectors | Lists | QPS | Latency Mean | Latency p95 | RAM Usage | RAM |
-| ------ | --------- | ----- | --- | ------------ | ----------- | --------- | ------ |
-| Micro | 20,000 | 40 | - | - | - | - | 1 GB |
-| Small | 50,000 | 100 | - | - | - | - | 2 GB |
-| Medium | 100,000 | 200 | - | - | - | - | 4 GB |
-| Large | 250,000 | 500 | - | - | - | - | 8 GB |
-| XL | 500,000 | 1000 | - | - | - | - | 16 GB |
-| 2XL | 1,000,000 | 2000 | 140 | 0.358 sec | 0.575 sec | 30 GB | 32 GB |
-| 4XL | 1,000,000 | 2000 | 270 | 0.186 sec | 0.304 sec | 35 GB | 64 GB |
-| 8XL | 1,000,000 | 2000 | 470 | 0.104 sec | 0.166 sec | 38 GB | 128 GB |
-| 12XL | 1,000,000 | 2000 | 600 | 0.085 sec | 0.132 sec | 41 GB | 192 GB |
-| 16XL | 1,000,000 | 2000 | 670 | 0.081 sec | 0.129 sec | 45 GB | 256 GB |
+| Compute Size | Vectors | Lists | QPS | Latency Mean | Latency p95 | RAM Usage | RAM |
+| ------------ | --------- | ----- | --- | ------------ | ----------- | --------- | ------ |
+| Micro | 20,000 | 40 | - | - | - | - | 1 GB |
+| Small | 50,000 | 100 | - | - | - | - | 2 GB |
+| Medium | 100,000 | 200 | - | - | - | - | 4 GB |
+| Large | 250,000 | 500 | - | - | - | - | 8 GB |
+| XL | 500,000 | 1000 | - | - | - | - | 16 GB |
+| 2XL | 1,000,000 | 2000 | 140 | 0.358 sec | 0.575 sec | 30 GB | 32 GB |
+| 4XL | 1,000,000 | 2000 | 270 | 0.186 sec | 0.304 sec | 35 GB | 64 GB |
+| 8XL | 1,000,000 | 2000 | 470 | 0.104 sec | 0.166 sec | 38 GB | 128 GB |
+| 12XL | 1,000,000 | 2000 | 600 | 0.085 sec | 0.132 sec | 41 GB | 192 GB |
+| 16XL | 1,000,000 | 2000 | 670 | 0.081 sec | 0.129 sec | 45 GB | 256 GB |
For 1,000,000 vectors 40 probes results to accuracy of 0.98. Note that exact values may vary depending on the dataset and queries, we recommend to run benchmarks with your own data to get precise results. Use this table as a reference.
-
-
-
+
@@ -277,7 +275,7 @@ There are various ways to improve your pgvector performance. Here are some tips:
### Pre-warming your database
-It's useful to execute a few thousand “warm-up” queries before going into production. This helps help with RAM utilization. This can also help to determine that you've selected the right instance size for your workload.
+It's useful to execute a few thousand “warm-up” queries before going into production. This helps help with RAM utilization. This can also help to determine that you've selected the right compute size for your workload.
### Finetune index parameters
@@ -292,27 +290,27 @@ You can increase the Requests per Second by increasing `m` and `ef_construction`
>
-
-
-
+
-
-
-
+
+
+
@@ -322,15 +320,15 @@ Check out more tips and the complete step-by-step guide in [Going to Production
We follow techniques outlined in the [ANN Benchmarks](https://github.com/erikbern/ann-benchmarks) methodology. A Python test runner is responsible for uploading the data, creating the index, and running the queries. The pgvector engine is implemented using [vecs](https://github.com/supabase/vecs), a Python client for pgvector.
-
-
-
+
Each test is run for a minimum of 30-40 minutes. They include a series of experiments executed at different concurrency levels to measure the engine's performance under different load types. The results are then averaged.
diff --git a/apps/docs/content/guides/ai/engineering-for-scale.mdx b/apps/docs/content/guides/ai/engineering-for-scale.mdx
index 17a4a27f9c3..f0e5e5be6a0 100644
--- a/apps/docs/content/guides/ai/engineering-for-scale.mdx
+++ b/apps/docs/content/guides/ai/engineering-for-scale.mdx
@@ -14,15 +14,14 @@ For small workloads, it's typical to store your data in a single database.
If you've used [Vecs](/docs/guides/ai/vecs-python-client) to create 3 different collections, you can expose collections to your web or mobile application using [views](/docs/guides/database/tables#views):
-
-
-
+
For example, with 3 collections, called `docs`, `posts`, and `images`, we could expose the "docs" inside the public schema like this:
@@ -50,15 +49,14 @@ const { data, error } = await supabase
As you move into production, we recommend splitting your collections into separate projects. This is because it allows your vector stores to scale independently of your production data. Vectors typically grow faster than operational data, and they have different resource requirements. Running them on separate databases removes the single-point-of-failure.
-
-
-
+
You can use as many secondary databases as you need to manage your collections. With this architecture, you have 2 options for accessing collections within your application:
@@ -134,12 +132,11 @@ const { data, error } = await supabase
This diagram provides an example architecture that allows you to access the collections either with our client libraries or using Vecs. You can add as many secondary databases as you need (in this example we only show one):
-
-
-
+
diff --git a/apps/docs/content/guides/ai/examples/building-chatgpt-plugins.mdx b/apps/docs/content/guides/ai/examples/building-chatgpt-plugins.mdx
index a37988c88c2..d30ad096e96 100644
--- a/apps/docs/content/guides/ai/examples/building-chatgpt-plugins.mdx
+++ b/apps/docs/content/guides/ai/examples/building-chatgpt-plugins.mdx
@@ -32,11 +32,12 @@ We'll be saving the Postgres documentation in Postgres, and ChatGPT will be retr
### Step 1: Fork the ChatGPT Retrieval Plugin repository
diff --git a/apps/docs/content/guides/ai/examples/huggingface-image-captioning.mdx b/apps/docs/content/guides/ai/examples/huggingface-image-captioning.mdx
index 64012a95fea..d2737bd6e29 100644
--- a/apps/docs/content/guides/ai/examples/huggingface-image-captioning.mdx
+++ b/apps/docs/content/guides/ai/examples/huggingface-image-captioning.mdx
@@ -41,7 +41,7 @@ Find the complete code on [GitHub](https://github.com/supabase/supabase/tree/mas
```ts
import { serve } from 'https://deno.land/std@0.168.0/http/server.ts'
import { HfInference } from 'https://esm.sh/@huggingface/inference@2.3.2'
-import { createClient } from 'https://esm.sh/@supabase/supabase-js@2.7.1'
+import { createClient } from 'jsr:@supabase/supabase-js@2'
import { Database } from './types.ts'
console.log('Hello from `huggingface-image-captioning` function!')
diff --git a/apps/docs/content/guides/ai/going-to-prod.mdx b/apps/docs/content/guides/ai/going-to-prod.mdx
index 010748a695e..a82522b043b 100644
--- a/apps/docs/content/guides/ai/going-to-prod.mdx
+++ b/apps/docs/content/guides/ai/going-to-prod.mdx
@@ -28,15 +28,14 @@ On the other hand, if you need to scale your application, you will need to [crea
`pgvector` supports two types of indexes: HNSW and IVFFlat. We recommend using [HNSW](/docs/guides/ai/vector-indexes/hnsw-indexes) because of its [performance](https://supabase.com/blog/increase-performance-pgvector-hnsw#hnsw-performance-1536-dimensions) and [robustness against changing data](/docs/guides/ai/vector-indexes/hnsw-indexes#when-should-you-create-hnsw-indexes).
-
-
-
+
## HNSW, understanding `ef_construction`, `ef_search`, and `m`
@@ -50,15 +49,14 @@ Search parameters:
- `ef_search` is the size of the dynamic list for the nearest neighbors (used during the search). Increasing `ef_search` will result in better accuracy, but it will also increase the time required to execute a query (40 is the default value).
-
-
-
+
## IVFFlat, understanding `probes` and `lists`
@@ -72,15 +70,14 @@ The values of lists and probes directly affect accuracy and queries per second (
You can find more examples of how `lists` and `probes` constants affect accuracy and QPS in [pgvector 0.4.0 performance](https://supabase.com/blog/pgvector-performance) blogpost.
-
-
-
+
## Performance tips when using indexes
@@ -114,12 +111,11 @@ You can look at our [Choosing Compute Add-on](/docs/guides/ai/choosing-compute-a
Or take a look at our [pgvector 0.5.0 performance](https://supabase.com/blog/increase-performance-pgvector-hnsw) and [pgvector 0.4.0 performance](https://supabase.com/blog/pgvector-performance) blog posts to see what pgvector is capable of and how the above technique can be used to achieve the best results.
-
-
-
+
diff --git a/apps/docs/content/guides/ai/hybrid-search.mdx b/apps/docs/content/guides/ai/hybrid-search.mdx
index 535b0782338..0a21fd1f83c 100644
--- a/apps/docs/content/guides/ai/hybrid-search.mdx
+++ b/apps/docs/content/guides/ai/hybrid-search.mdx
@@ -166,7 +166,7 @@ from
In practice, you will likely be calling this from the [Supabase client](/docs/reference/javascript/introduction) or through a custom backend layer. Here is a quick example of how you might call this from an [Edge Function](/docs/guides/functions) using JavaScript:
```tsx
-import { createClient } from 'npm:@supabase/supabase-js'
+import { createClient } from 'jsr:@supabase/supabase-js@2'
import OpenAI from 'npm:openai'
const supabaseUrl = Deno.env.get('SUPABASE_URL')!
diff --git a/apps/docs/content/guides/ai/vector-indexes/hnsw-indexes.mdx b/apps/docs/content/guides/ai/vector-indexes/hnsw-indexes.mdx
index 2a1823ad175..eb7d09ac96f 100644
--- a/apps/docs/content/guides/ai/vector-indexes/hnsw-indexes.mdx
+++ b/apps/docs/content/guides/ai/vector-indexes/hnsw-indexes.mdx
@@ -52,15 +52,13 @@ The hierarchical aspect of HNSW builds off of the idea of skip lists.
Skip lists are multi-layer linked lists. The bottom layer is a regular linked list connecting an ordered sequence of elements. Each new layer above removes some elements from the underlying layer (based on a fixed probability), producing a sparser subsequence that “skips” over elements.
-
-
-
+
When searching for an element, the algorithm begins at the top layer and traverses its linked list horizontally. If the target element is found, the algorithm stops and returns it. Otherwise if the next element in the list is greater than the target (or `NULL`), the algorithm drops down to the next layer below. Since each layer below is less sparse than the layer above (with the bottom layer connecting all elements), the target will eventually be found. Skip lists offer O(log n) average complexity for both search and insertion/deletion.
@@ -68,9 +66,11 @@ When searching for an element, the algorithm begins at the top layer and travers
A navigable small world (NSW) is a special type of proximity graph that also includes long-range connections between nodes. These long-range connections support the “small world” property of the graph, meaning almost every node can be reached from any other node within a few hops. Without these additional long-range connections, many hops would be required to reach a far-away node.
-
The “navigable” part of NSW specifically refers to the ability to logarithmically scale the greedy search algorithm on the graph, an algorithm that attempts to make only the locally optimal choice at each hop. Without this property, the graph may still be considered a small world with short paths between far-away nodes, but the greedy algorithm tends to miss them. Greedy search is ideal for NSW because it is quick to navigate and has low computational costs.
diff --git a/apps/docs/content/guides/api/rest/client-libs.mdx b/apps/docs/content/guides/api/rest/client-libs.mdx
index 15f03b0d442..7a19ded8c01 100644
--- a/apps/docs/content/guides/api/rest/client-libs.mdx
+++ b/apps/docs/content/guides/api/rest/client-libs.mdx
@@ -14,6 +14,7 @@ Supabase provides client libraries for the REST and Realtime APIs. Some librarie
| Javascript/Typescript | [supabase-js](https://github.com/supabase/supabase-js) | [Docs](https://supabase.com/docs/reference/javascript/introduction) |
| Dart/Flutter | [supabase-flutter](https://github.com/supabase/supabase-flutter/tree/main/packages/supabase_flutter) | [Docs](https://supabase.com/docs/reference/dart/introduction) |
| Swift | [supabase-swift](https://github.com/supabase/supabase-swift) | [Docs](https://supabase.com/docs/reference/swift/introduction) |
+| Python | [supabase-py](https://github.com/supabase/supabase-py) | [Docs](https://supabase.com/docs/reference/python/initializing) |
## Community libraries
@@ -22,6 +23,5 @@ Supabase provides client libraries for the REST and Realtime APIs. Some librarie
| C# | [supabase-csharp](https://github.com/supabase-community/supabase-csharp) | [Docs](https://supabase.com/docs/reference/csharp/introduction) |
| Go | [supabase-go](https://github.com/supabase-community/supabase-go) | |
| Kotlin | [supabase-kt](https://github.com/supabase-community/supabase-kt) | [Docs](https://supabase.com/docs/reference/kotlin/introduction) |
-| Python | [supabase-py](https://github.com/supabase-community/supabase-py) | [Docs](https://supabase.com/docs/reference/python/initializing) |
| Ruby | [supabase-rb](https://github.com/supabase-community/supabase-rb) | |
| Godot Engine (GDScript) | [supabase-gdscript](https://github.com/supabase-community/godot-engine.supabase) | |
diff --git a/apps/docs/content/guides/api/rest/generating-types.mdx b/apps/docs/content/guides/api/rest/generating-types.mdx
index a9d557a3ac2..5bfd5582380 100644
--- a/apps/docs/content/guides/api/rest/generating-types.mdx
+++ b/apps/docs/content/guides/api/rest/generating-types.mdx
@@ -37,13 +37,13 @@ npx supabase init
Generate types for your project to produce the `types/supabase.ts` file:
```bash
-npx supabase gen types typescript --project-id "$PROJECT_REF" --schema public > types/supabase.ts
+npx supabase gen types --lang=typescript --project-id "$PROJECT_REF" --schema public > types/supabase.ts
```
or in case of local development:
```bash
-npx supabase gen types typescript --local > types/supabase.ts
+npx supabase gen types --lang=typescript --local > types/supabase.ts
```
These types are generated from your database schema. Given a table `public.movies`, the generated types will look like:
@@ -206,10 +206,10 @@ const countriesWithCities: CountriesWithCities = data
One way to keep your type definitions in sync with your database is to set up a GitHub action that runs on a schedule.
-Add the script above to your `package.json` to run it using `npm run update-types`
+Add the following script to your `package.json` to run it using `npm run update-types`
```json
-"update-types": "npx supabase gen types typescript --project-id \"$PROJECT_REF\" > types/supabase.ts"
+"update-types": "npx supabase gen types --lang=typescript --project-id \"$PROJECT_REF\" > types/supabase.ts"
```
Create a file `.github/workflows/update-types.yml` with the following snippet to define the action along with the environment variables. This script will commit new type changes to your repo every night.
diff --git a/apps/docs/content/guides/api/securing-your-api.mdx b/apps/docs/content/guides/api/securing-your-api.mdx
index 8d78d9ea2de..6b54463d0fe 100644
--- a/apps/docs/content/guides/api/securing-your-api.mdx
+++ b/apps/docs/content/guides/api/securing-your-api.mdx
@@ -53,25 +53,9 @@ Any table **without RLS enabled** in the `public` schema will be accessible to t
-## Safeguards towards accidental deletes and updates
+## Disable the API or restrict to custom schema
-By default, all projects have the [safeupdate](https://github.com/eradman/pg-safeupdate) Postgres extension enabled for API queries. This ensures that `delete()` and `update()` requests will fail if there are no filters provided.
-
-To confirm that safeupdate is enabled for API queries, run the following query:
-
-```sql
-select
- usename,
- useconfig
-from pg_shadow
-where usename = 'authenticator';
-```
-
-The expected value for `useconfig` should be:
-
-```javascript
-;['session_preload_libraries=supautils, safeupdate']
-```
+If you don't use the Data API, or if you don't want to expose the `public` schema, you can either disable it entirely or change the automatically exposed schema to one of your choice. See **[Hardening the Data API](/docs/guides/database/hardening-data-api)** for instructions.
## Enforce additional rules on each request
diff --git a/apps/docs/content/guides/api/sql-to-rest.mdx b/apps/docs/content/guides/api/sql-to-rest.mdx
index 4884c7d80e9..e96e844932b 100644
--- a/apps/docs/content/guides/api/sql-to-rest.mdx
+++ b/apps/docs/content/guides/api/sql-to-rest.mdx
@@ -14,19 +14,17 @@ PostgREST supports a subset of SQL, so not all SQL queries will translate.
diff --git a/apps/docs/content/guides/auth/auth-email-templates.mdx b/apps/docs/content/guides/auth/auth-email-templates.mdx
index 470620a2d93..cdff2487be6 100644
--- a/apps/docs/content/guides/auth/auth-email-templates.mdx
+++ b/apps/docs/content/guides/auth/auth-email-templates.mdx
@@ -27,7 +27,7 @@ The templating system provides the following variables for use:
## Editing email templates
-On self-hosted Supabase projects, edit your email templates on the [Email Templates](/dashboard/project/_/auth/templates) page. On self-hosted projects or in local development, edit your [configuration files](/docs/guides/cli/customizing-email-templates).
+On hosted Supabase projects, edit your email templates on the [Email Templates](/dashboard/project/_/auth/templates) page. On self-hosted projects or in local development, edit your [configuration files](/docs/guides/cli/customizing-email-templates).
## Mobile Deep Linking
diff --git a/apps/docs/content/guides/auth/auth-helpers/auth-ui.mdx b/apps/docs/content/guides/auth/auth-helpers/auth-ui.mdx
index c45b58f4bef..8898fd846eb 100644
--- a/apps/docs/content/guides/auth/auth-helpers/auth-ui.mdx
+++ b/apps/docs/content/guides/auth/auth-helpers/auth-ui.mdx
@@ -42,7 +42,7 @@ This renders the Auth component without any styling.
We recommend using one of the predefined themes to style the UI.
Import the theme you want to use and pass it to the `appearance.theme` prop.
-```js mark=4,16 /src/index.js
+```js
import { Auth } from '@supabase/auth-ui-react'
import {
// Import predefined theme
@@ -67,7 +67,7 @@ const App = () => (
The Auth component also supports login with [official social providers](../../auth#providers).
-```js mark=11 /src/index.js
+```js
import { createClient } from '@supabase/supabase-js'
import { Auth } from '@supabase/auth-ui-react'
import { ThemeSupa } from '@supabase/auth-ui-shared'
@@ -146,7 +146,7 @@ There are several ways to customize Auth UI:
Auth UI comes with several themes to customize the appearance. Each predefined theme comes with at least two variations, a `default` variation, and a `dark` variation. You can switch between these themes using the `theme` prop. Import the theme you want to use and pass it to the `appearance.theme` prop.
-```js mark=3,14 /src/index.js
+```js
import { createClient } from '@supabase/supabase-js'
import { Auth } from '@supabase/auth-ui-react'
import { ThemeSupa } from '@supabase/auth-ui-shared'
@@ -175,7 +175,7 @@ Currently there is only one predefined theme available, but we plan to add more.
Auth UI comes with two theme variations: `default` and `dark`. You can switch between these themes with the `theme` prop.
-```js mark=15 /src/index.js
+```js
import { createClient } from '@supabase/supabase-js'
import { Auth } from '@supabase/auth-ui-react'
import { ThemeSupa } from '@supabase/auth-ui-shared'
@@ -201,7 +201,7 @@ If you don't pass a value to `theme` it uses the `"default"` theme. You can pass
Auth UI themes can be overridden using variable tokens. See the [list of variable tokens](https://github.com/supabase/auth-ui/blob/main/packages/shared/src/theming/Themes.ts).
-```js mark=12:19 /src/index.js
+```js
import { createClient } from '@supabase/supabase-js'
import { Auth } from '@supabase/auth-ui-react'
import { ThemeSupa } from '@supabase/auth-ui-shared'
@@ -335,7 +335,7 @@ const App = () => (
You can use custom labels with `localization.variables` like so:
-```js mark=10:15 /src/index.js
+```js
import { createClient } from '@supabase/supabase-js'
import { Auth } from '@supabase/auth-ui-react'
@@ -461,7 +461,7 @@ Currently, translating error messages (e.g. "Invalid credentials") is not suppor
You can hide links by setting the `showLinks` prop to `false`
-```js mark=9 /src/index.js
+```js
import { createClient } from '@supabase/supabase-js'
import { Auth } from '@supabase/auth-ui-react'
diff --git a/apps/docs/content/guides/auth/auth-helpers/nextjs-pages.mdx b/apps/docs/content/guides/auth/auth-helpers/nextjs-pages.mdx
index b24639e091d..85fcaee1b36 100644
--- a/apps/docs/content/guides/auth/auth-helpers/nextjs-pages.mdx
+++ b/apps/docs/content/guides/auth/auth-helpers/nextjs-pages.mdx
@@ -20,7 +20,7 @@ The `auth-helpers` package has been replaced with the `@supabase/ssr` package. W
className="text-foreground-light border-b mt-8 pb-2"
>
-
@@ -97,7 +97,7 @@ function MyApp({ Component, pageProps }) {
Wrap your `pages/_app.tsx` component with the `SessionContextProvider` component:
-```tsx mark=2,8 pages/_app.tsx
+```tsx
import { type AppProps } from 'next/app'
import { createPagesBrowserClient } from '@supabase/auth-helpers-nextjs'
import { SessionContextProvider, Session } from '@supabase/auth-helpers-react'
@@ -238,7 +238,7 @@ export default async (req: NextApiRequest, res: NextApiResponse) => {
For [row level security](/docs/learn/auth-deep-dive/auth-row-level-security) to work properly when fetching data client-side, you need to make sure to use the `supabaseClient` from the `useSupabaseClient` hook and only run your query once the user is defined client-side in the `useUser()` hook:
-```jsx mark=10:17
+```jsx
import { Auth } from '@supabase/auth-ui-react'
import { ThemeSupa } from '@supabase/auth-ui-shared'
import { useUser, useSupabaseClient } from '@supabase/auth-helpers-react'
@@ -933,6 +933,6 @@ import { Database } from '../database.types'
const supabaseClient = useSupabaseClient()
```
-
+
diff --git a/apps/docs/content/guides/auth/auth-helpers/nextjs.mdx b/apps/docs/content/guides/auth/auth-helpers/nextjs.mdx
index 1d14e693b24..a6d7b1dd996 100644
--- a/apps/docs/content/guides/auth/auth-helpers/nextjs.mdx
+++ b/apps/docs/content/guides/auth/auth-helpers/nextjs.mdx
@@ -20,7 +20,7 @@ The `auth-helpers` package has been replaced with the `@supabase/ssr` package. W
className="text-foreground-light border-b mt-8 pb-2"
>
-
@@ -1327,6 +1327,6 @@ export default function() {
For an example of creating multiple Supabase clients, check [Singleton section](/docs/guides/auth/auth-helpers/nextjs#singleton) above.
-
+
diff --git a/apps/docs/content/guides/auth/auth-helpers/remix.mdx b/apps/docs/content/guides/auth/auth-helpers/remix.mdx
index dd9d537f960..85721924341 100644
--- a/apps/docs/content/guides/auth/auth-helpers/remix.mdx
+++ b/apps/docs/content/guides/auth/auth-helpers/remix.mdx
@@ -20,7 +20,7 @@ We generally recommend using the new `@supabase/ssr` package instead of `auth-he
className="text-foreground-light border-b mt-8 pb-2"
>
-
@@ -833,6 +833,6 @@ supabaseClient.auth.signUp({
})
```
-
+
diff --git a/apps/docs/content/guides/auth/auth-helpers/sveltekit.mdx b/apps/docs/content/guides/auth/auth-helpers/sveltekit.mdx
index 6fcdb70efe2..03fea2dc2b2 100644
--- a/apps/docs/content/guides/auth/auth-helpers/sveltekit.mdx
+++ b/apps/docs/content/guides/auth/auth-helpers/sveltekit.mdx
@@ -20,7 +20,7 @@ We generally recommend using the new `@supabase/ssr` package instead of `auth-he
className="text-foreground-light border-b mt-8 pb-2"
>
-
@@ -2031,6 +2031,6 @@ export const GET: RequestHandler = withAuth(async ({ session, getSupabaseClient
- [Auth Helpers Source code](https://github.com/supabase/auth-helpers)
- [SvelteKit example](https://github.com/supabase/auth-helpers/tree/main/examples/sveltekit)
-
+
diff --git a/apps/docs/content/guides/auth/auth-hooks.mdx b/apps/docs/content/guides/auth/auth-hooks.mdx
index 336b9c950d9..5986aeb6d0c 100644
--- a/apps/docs/content/guides/auth/auth-hooks.mdx
+++ b/apps/docs/content/guides/auth/auth-hooks.mdx
@@ -15,11 +15,11 @@ Hooks help you:
You can use hooks at specific points along an Auth flow to perform custom behavior via Postgres Functions. The following hooks are available:
-| Hook | Available on Plan |
-| ----------------------------- | -------------------- |
-| Custom Access Token | Free, Pro |
-| MFA Verification Attempt | Teams and Enterprise |
-| Password Verification Attempt | Teams and Enterprise |
+| Hook | Available on Plan |
+| ----------------------------- | ------------------- |
+| Custom Access Token | Free, Pro |
+| MFA Verification Attempt | Team and Enterprise |
+| Password Verification Attempt | Team and Enterprise |
You can connect a hook to Supabase Auth to signal to Supabase Auth that it should make use of the hook.
@@ -77,7 +77,7 @@ You also need to grant usage to `supabase_auth_admin`:
grant usage on schema public to supabase_auth_admin;
```
-Also revoke permissions from the `authenticated`, `public`, and `anon` roles to ensure the function is not accessible by Supabase Serverless APIs. The `public` role has access to functions created on `public.*` by default and `anon` and `authenticated` inherit permissions from the `public` role. Permission is revoked from the`public` role in order to prevent the `anon` and `authenticated` roles from inheriting permissions to invoke the Postgres Hook.
+Also revoke permissions from the `authenticated`, `public`, and `anon` roles to ensure the function is not accessible by Supabase Serverless APIs. The `public` role has access to functions created on `public.*` by default and `anon` and `authenticated` inherit permissions from the `public` role. Permission is revoked from the `public` role in order to prevent the `anon` and `authenticated` roles from inheriting permissions to invoke the Postgres Hook.
```sql
revoke execute
@@ -85,11 +85,11 @@ revoke execute
from authenticated, anon, public;
```
-For security, we recommend against the use the `security definer` tag. The `security definer` tag specifies that the function is to be executed with the privileges of the user that owns it. When a function is created via the Supabase dashboard with the tag, it will have the extensive permissions of the `postgres` role which make it easier for undesirable actions to occur.
+For security, we recommend against the use of the `security definer` tag. The `security definer` tag specifies that the function is to be executed with the privileges of the user that owns it. When a function is created via the Supabase dashboard with the tag, it will have the extensive permissions of the `postgres` role which make it easier for undesirable actions to occur.
We recommend that you do not use any tag and explicitly grant permissions to `supabase_auth_admin` as described above.
-Read more about `security definer` tag [in our database guide](/docs/guides/database/functions#security-definer-vs-invoker).
+Read more about the `security definer` tag [in our database guide](/docs/guides/database/functions#security-definer-vs-invoker).
### Hook errors
diff --git a/apps/docs/content/guides/auth/auth-mfa.mdx b/apps/docs/content/guides/auth/auth-mfa.mdx
index 41048252e05..af3cf2549bc 100644
--- a/apps/docs/content/guides/auth/auth-mfa.mdx
+++ b/apps/docs/content/guides/auth/auth-mfa.mdx
@@ -34,16 +34,13 @@ Supabase Auth provides:
Below is a flow chart illustrating how these APIs work together to enable MFA features in your app.
- SAAL1[/Session is AAL1/] --> Enroll[Enroll API] --> ShowQR[Show QR code] --> Scan([User: Scan QR code in authenticator]) --> Enter([User: Enter code]) --> Verify[Challenge + Verify API] --> Check{{Is code correct?}}
- Check -->|Yes| AAL2[/Upgrade to AAL2/] --> Done((Done))
- Check -->|No| Enter
- InitA((Login flow)) --> SignIn([User: Sign-in]) --> AAL1[/Upgrade to AAL1/] --> ListFactors[List Factors API]
- ListFactors -->|1 or more factors| OpenAuth([User: Open authenticator]) --> Enter
- ListFactors -->|0 factors| Setup[[Setup flow]]
-`}
+
These sets of APIs let you control the MFA experience that works for you. You can create flows where MFA is optional, mandatory for all, or only specific groups of users.
diff --git a/apps/docs/content/guides/auth/enterprise-sso/auth-sso-saml.mdx b/apps/docs/content/guides/auth/enterprise-sso/auth-sso-saml.mdx
index cea09ebc099..5b553d6d312 100644
--- a/apps/docs/content/guides/auth/enterprise-sso/auth-sso-saml.mdx
+++ b/apps/docs/content/guides/auth/enterprise-sso/auth-sso-saml.mdx
@@ -117,7 +117,7 @@ create table organization_settings (
sso_provider_id uuid unique,
-- name of the organization
name text,
- -- billing plan (paid, free, enterprise)
+ -- billing plan (paid, Free, Enterprise)
billing_plan text
);
```
diff --git a/apps/docs/content/guides/auth/identities.mdx b/apps/docs/content/guides/auth/identities.mdx
index 41f265a8767..6607837877d 100644
--- a/apps/docs/content/guides/auth/identities.mdx
+++ b/apps/docs/content/guides/auth/identities.mdx
@@ -17,11 +17,12 @@ The user identity object contains the following attributes:
| Attributes | Type | Description |
| --------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| id | `string` | The provider id returned by the provider. If the provider is an OAuth provider, the id refers to the user's account with the OAuth provider. If the provider is `email` or `phone`, the id is the user's id from the `auth.users` table. |
+| provider_id | `string` | The provider id returned by the provider. If the provider is an OAuth provider, the id refers to the user's account with the OAuth provider. If the provider is `email` or `phone`, the id is the user's id from the `auth.users` table. |
| user_id | `string` | The user's id that the identity is linked to. |
| identity_data | `object` | The identity metadata. For OAuth and SAML identities, this contains information about the user from the provider. |
-| identity_id | `string` | The unique id of the identity. |
+| id | `string` | The unique id of the identity. |
| provider | `string` | The provider name. |
+| email | `string` | The email is a generated column that references the optional email property in the identity_data |
| created_at | `string` | The timestamp that the identity was created. |
| last_sign_in_at | `string` | The timestamp that the identity was last used to sign in. |
| updated_at | `string` | The timestamp that the identity was last updated. |
diff --git a/apps/docs/content/guides/auth/passwords.mdx b/apps/docs/content/guides/auth/passwords.mdx
index cead55cc21a..56b1a86a367 100644
--- a/apps/docs/content/guides/auth/passwords.mdx
+++ b/apps/docs/content/guides/auth/passwords.mdx
@@ -142,16 +142,19 @@ Your signup email template should contain the following HTML:
Create an API endpoint at `/auth/confirm` to handle the token exchange.
+
+
Create a new file at `app/auth/confirm/route.ts` and populate with the following:
```ts app/auth/confirm/route.ts
-import { createServerClient, type CookieOptions } from '@supabase/ssr'
import { type EmailOtpType } from '@supabase/supabase-js'
import { cookies } from 'next/headers'
import { NextRequest, NextResponse } from 'next/server'
+// The client you created from the Server-Side Auth instructions
+import { createClient } from '@/utils/supabase/server'
export async function GET(request: NextRequest) {
const { searchParams } = new URL(request.url)
@@ -162,24 +165,7 @@ export async function GET(request: NextRequest) {
redirectTo.pathname = next
if (token_hash && type) {
- const cookieStore = cookies()
- const supabase = createServerClient(
- process.env.NEXT_PUBLIC_SUPABASE_URL!,
- process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
- {
- cookies: {
- get(name: string) {
- return cookieStore.get(name)?.value
- },
- set(name: string, value: string, options: CookieOptions) {
- cookieStore.set({ name, value, ...options })
- },
- remove(name: string, options: CookieOptions) {
- cookieStore.delete({ name, ...options })
- },
- },
- }
- )
+ const supabase = createClient()
const { error } = await supabase.auth.verifyOtp({
type,
@@ -214,15 +200,27 @@ export const GET = async (event) => {
const type = url.searchParams.get('type') as EmailOtpType | null
const next = url.searchParams.get('next') ?? '/'
+ /**
+ * Clean up the redirect URL by deleting the Auth flow parameters.
+ *
+ * `next` is preserved for now, because it's needed in the error case.
+ */
+ const redirectTo = new URL(url)
+ redirectTo.pathname = next
+ redirectTo.searchParams.delete('token_hash')
+ redirectTo.searchParams.delete('type')
+
if (token_hash && type) {
const { error } = await supabase.auth.verifyOtp({ token_hash, type })
if (!error) {
- throw redirect(303, `/${next.slice(1)}`)
+ redirectTo.searchParams.delete('next')
+ redirect(303, redirectTo)
}
}
// return the user to an error page with some instructions
- throw redirect(303, '/auth/auth-code-error')
+ redirectTo.pathname = '/auth/error'
+ redirect(303, redirectTo)
}
```
@@ -233,7 +231,7 @@ export const GET = async (event) => {
Create a new file at `src/pages/auth/confirm.ts` and populate with the following:
```ts src/pages/auth/confirm.ts
-import { createServerClient } from '@supabase/ssr'
+import { createServerClient, parseCookieHeader } from '@supabase/ssr'
import { type EmailOtpType } from '@supabase/supabase-js'
import { type APIRoute } from 'astro'
@@ -249,14 +247,11 @@ export const GET: APIRoute = async ({ request, cookies, redirect }) => {
import.meta.env.PUBLIC_SUPABASE_ANON_KEY,
{
cookies: {
- get(key) {
- return cookies.get(key)?.value
+ getAll() {
+ return parseCookieHeader(request.headers.get('Cookie') ?? '')
},
- set(key, value, options) {
- cookies.set(key, value, options)
- },
- remove(key, options) {
- cookies.delete(key, options)
+ setAll(cookiesToSet) {
+ cookiesToSet.forEach(({ name, value, options }) => cookies.set(name, value, options))
},
},
}
@@ -285,7 +280,7 @@ Create a new file at `app/routes/auth.confirm.tsx` and populate with the followi
```ts app/routes/auth.confirm.tsx
import { redirect, type LoaderFunctionArgs } from '@remix-run/node'
-import { createServerClient, parse, serialize } from '@supabase/ssr'
+import { createServerClient, parseCookieHeader, serializeCookieHeader } from '@supabase/ssr'
import { type EmailOtpType } from '@supabase/supabase-js'
export async function loader({ request }: LoaderFunctionArgs) {
@@ -296,18 +291,13 @@ export async function loader({ request }: LoaderFunctionArgs) {
const headers = new Headers()
if (token_hash && type) {
- const cookies = parse(request.headers.get('Cookie') ?? '')
-
const supabase = createServerClient(process.env.SUPABASE_URL!, process.env.SUPABASE_ANON_KEY!, {
cookies: {
- get(key) {
- return cookies[key]
+ getAll() {
+ return parseCookieHeader(request.headers.get('Cookie') ?? '')
},
- set(key, value, options) {
- headers.append('Set-Cookie', serialize(key, value, options))
- },
- remove(key, options) {
- headers.append('Set-Cookie', serialize(key, '', options))
+ setAll(key, value, options) {
+ headers.append('Set-Cookie', serializeCookieHeader(key, value, options))
},
},
})
@@ -333,6 +323,8 @@ export async function loader({ request }: LoaderFunctionArgs) {
Create a new route in your express app and populate with the following:
```js app.js
+// The client you created from the Server-Side Auth instructions
+const { createClient } = require("./lib/supabase")
...
app.get("/auth/confirm", async function (req, res) {
const token_hash = req.query.token_hash
@@ -492,6 +484,14 @@ suspend fun signInWithEmail() {
### Resetting a password
+
+
+
#### Step 1: Create a reset password page
Create a **reset password** page. This page should be publicly accessible.
@@ -542,31 +542,278 @@ If you are on one of the Kotlin targets that have built-in support for redirect
Create a **change password** page at the URL you specified in the previous step. This page should be accessible only to authenticated users.
-
-
-
Collect the user's new password and call `updateUser` to update their password.
-In the PKCE flow, the reset password link only works on the device or browser where the original request was made.
+The PKCE flow allows for server-side authentication. Unlike the implicit flow, which directly provides your app with the access token after the user clicks the confirmation link, the PKCE flow requires an intermediate token exchange step before you can get the access token.
-When the user clicks the link and is redirected to the change password page, their URL contains a `code` query param. If you aren't using the official Supabase libraries, extract the `code` from the URL and exchange it for a session. For example, in JavaScript, call [`supabase.auth.exchangeCodeForSession`](/docs/reference/javascript/auth-exchangecodeforsession). If you're using an official library, the code exchange is handled for you.
+##### Step 1: Update reset password email
-
+Update your reset password email template to send the token hash. See [Email Templates](/docs/guides/auth/auth-email-templates) for how to configure your email templates.
-If your page is server-rendered and the code isn't being automatically exchanged, check whether the Supabase client is being initialized eagerly. Your server-rendered page might be lazily initializing the Supabase client after user interaction, which means the automatic code exchange can't run.
+Your signup email template should contain the following HTML:
-You can either exchange the code yourself or initialize the Supabase client eagerly.
+```html
+Reset Password
-
+Follow this link to reset the password for your user:
+
+ Reset Password
+
+```
+
+##### Step 2: Create token exchange endpoint
+
+Create an API endpoint at `/auth/confirm` to handle the token exchange.
+
+
+
+
+
+
+Create a new file at `app/auth/confirm/route.ts` and populate with the following:
+
+```ts app/auth/confirm/route.ts
+import { type EmailOtpType } from '@supabase/supabase-js'
+import { cookies } from 'next/headers'
+import { NextRequest, NextResponse } from 'next/server'
+// The client you created from the Server-Side Auth instructions
+import { createClient } from '@/utils/supabase/server'
+
+export async function GET(request: NextRequest) {
+ const { searchParams } = new URL(request.url)
+ const token_hash = searchParams.get('token_hash')
+ const type = searchParams.get('type') as EmailOtpType | null
+ const next = searchParams.get('next') ?? '/'
+ const redirectTo = request.nextUrl.clone()
+ redirectTo.pathname = next
+
+ if (token_hash && type) {
+ const supabase = createClient()
+
+ const { error } = await supabase.auth.verifyOtp({
+ type,
+ token_hash,
+ })
+ if (!error) {
+ return NextResponse.redirect(redirectTo)
+ }
+ }
+
+ // return the user to an error page with some instructions
+ redirectTo.pathname = '/auth/auth-code-error'
+ return NextResponse.redirect(redirectTo)
+}
+```
+
+
+
+
+Create a new file at `src/routes/auth/confirm/+server.ts` and populate with the following:
+
+```ts src/routes/auth/confirm/+server.ts
+import { redirect } from '@sveltejs/kit'
+import { type EmailOtpType } from '@supabase/supabase-js'
+
+export const GET = async (event) => {
+ const {
+ url,
+ locals: { supabase },
+ } = event
+ const token_hash = url.searchParams.get('token_hash') as string
+ const type = url.searchParams.get('type') as EmailOtpType | null
+ const next = url.searchParams.get('next') ?? '/'
+
+ /**
+ * Clean up the redirect URL by deleting the Auth flow parameters.
+ *
+ * `next` is preserved for now, because it's needed in the error case.
+ */
+ const redirectTo = new URL(url)
+ redirectTo.pathname = next
+ redirectTo.searchParams.delete('token_hash')
+ redirectTo.searchParams.delete('type')
+
+ if (token_hash && type) {
+ const { error } = await supabase.auth.verifyOtp({ token_hash, type })
+ if (!error) {
+ redirectTo.searchParams.delete('next')
+ redirect(303, redirectTo)
+ }
+ }
+
+ // return the user to an error page with some instructions
+ redirectTo.pathname = '/auth/error'
+ redirect(303, redirectTo)
+}
+```
+
+
+
+
+
+Create a new file at `src/pages/auth/confirm.ts` and populate with the following:
+
+```ts src/pages/auth/confirm.ts
+import { createServerClient, parseCookieHeader } from '@supabase/ssr'
+import { type EmailOtpType } from '@supabase/supabase-js'
+import { type APIRoute } from 'astro'
+
+export const GET: APIRoute = async ({ request, cookies, redirect }) => {
+ const requestUrl = new URL(request.url)
+ const token_hash = requestUrl.searchParams.get('token_hash')
+ const type = requestUrl.searchParams.get('type') as EmailOtpType | null
+ const next = requestUrl.searchParams.get('next') || '/'
+
+ if (token_hash && type) {
+ const supabase = createServerClient(
+ import.meta.env.PUBLIC_SUPABASE_URL,
+ import.meta.env.PUBLIC_SUPABASE_ANON_KEY,
+ {
+ cookies: {
+ getAll() {
+ return parseCookieHeader(request.headers.get('Cookie') ?? '')
+ },
+ setAll(cookiesToSet) {
+ cookiesToSet.forEach(({ name, value, options }) => cookies.set(name, value, options))
+ },
+ },
+ }
+ )
+
+ const { error } = await supabase.auth.verifyOtp({
+ type,
+ token_hash,
+ })
+
+ if (!error) {
+ return redirect(next)
+ }
+ }
+
+ // return the user to an error page with some instructions
+ return redirect('/auth/auth-code-error')
+}
+```
+
+
+
+
+
+Create a new file at `app/routes/auth.confirm.tsx` and populate with the following:
+
+```ts app/routes/auth.confirm.tsx
+import { redirect, type LoaderFunctionArgs } from '@remix-run/node'
+import { createServerClient, parseCookieHeader, serializeCookieHeader } from '@supabase/ssr'
+import { type EmailOtpType } from '@supabase/supabase-js'
+
+export async function loader({ request }: LoaderFunctionArgs) {
+ const requestUrl = new URL(request.url)
+ const token_hash = requestUrl.searchParams.get('token_hash')
+ const type = requestUrl.searchParams.get('type') as EmailOtpType | null
+ const next = requestUrl.searchParams.get('next') || '/'
+ const headers = new Headers()
+
+ if (token_hash && type) {
+ const supabase = createServerClient(process.env.SUPABASE_URL!, process.env.SUPABASE_ANON_KEY!, {
+ cookies: {
+ getAll() {
+ return parseCookieHeader(request.headers.get('Cookie') ?? '')
+ },
+ setAll(key, value, options) {
+ headers.append('Set-Cookie', serializeCookieHeader(key, value, options))
+ },
+ },
+ })
+
+ const { error } = await supabase.auth.verifyOtp({
+ type,
+ token_hash,
+ })
+
+ if (!error) {
+ return redirect(next, { headers })
+ }
+ }
+
+ // return the user to an error page with instructions
+ return redirect('/auth/auth-code-error', { headers })
+}
+```
+
+
+
+
+Create a new route in your express app and populate with the following:
+
+```js app.js
+// The client you created from the Server-Side Auth instructions
+const { createClient } = require("./lib/supabase")
+...
+app.get("/auth/confirm", async function (req, res) {
+ const token_hash = req.query.token_hash
+ const type = req.query.type
+ const next = req.query.next ?? "/"
+
+ if (token_hash && type) {
+ const supabase = createClient({ req, res })
+ const { error } = await supabase.auth.verifyOtp({
+ type,
+ token_hash,
+ })
+ if (!error) {
+ res.redirect(303, `/${next.slice(1)}`)
+ }
+ }
+
+ // return the user to an error page with some instructions
+ res.redirect(303, '/auth/auth-code-error')
+})
+```
+
+
+
+
+##### Step 3: Call the reset password by email function to initiate the flow
+
+
+
+
+```js
+async function signUpNewUser() {
+ const { data, error } = await supabase.auth.resetPasswordForEmail(email)
+}
+```
+
+
+
+
+```swift
+try await supabase.auth.resetPasswordForEmail("hello@example.com")
+```
+
+
+
+
+```kotlin
+supabase.gotrue.sendRecoveryEmail(
+ email = "hello@example.com",
+)
+```
+
+
+
Once you have a session, collect the user's new password and call `updateUser` to update their password.
@@ -622,7 +869,7 @@ See the [Custom SMTP guide](/docs/guides/auth/auth-smtp) for instructions.
#### Local development with Inbucket
-You can test email flows on your local machine. The Supabase CLI automatically captures emails sent locally by using [Inbucket](https://github.com/inbucket/bucket).
+You can test email flows on your local machine. The Supabase CLI automatically captures emails sent locally by using [Inbucket](https://github.com/inbucket/inbucket).
In your terminal, run `supabase status` to get the Inbucket URL. Go to this URL in your browser, and follow the instructions to find your emails.
diff --git a/apps/docs/content/guides/auth/phone-login.mdx b/apps/docs/content/guides/auth/phone-login.mdx
index ae637af9aba..9705d50b1b8 100644
--- a/apps/docs/content/guides/auth/phone-login.mdx
+++ b/apps/docs/content/guides/auth/phone-login.mdx
@@ -101,7 +101,7 @@ const {
data: { session },
error,
} = await supabase.auth.verifyOtp({
- phone: '+13334445555',
+ phone: '13334445555',
token: '123456',
type: 'sms',
})
diff --git a/apps/docs/content/guides/auth/server-side/creating-a-client.mdx b/apps/docs/content/guides/auth/server-side/creating-a-client.mdx
index b213d2cae37..30d2511567c 100644
--- a/apps/docs/content/guides/auth/server-side/creating-a-client.mdx
+++ b/apps/docs/content/guides/auth/server-side/creating-a-client.mdx
@@ -1,25 +1,53 @@
---
title: 'Creating a Supabase client for SSR'
-description: 'Configure Supabase client to use Cookies'
-sidebar_label: 'Creating a client'
+subtitle: 'Configure your Supabase client to use cookies'
---
-### Install Supabase packages
+To use Server-Side Rendering (SSR) with Supabase, you need to configure your Supabase client to use cookies. The `@supabase/ssr` package helps you do this for JavaScript/TypeScript applications.
-The `ssr` package configures Supabase to use Cookies, which is required for server-side languages and frameworks.
+## Install
+
+Install the `@supabase/ssr` and `@supabase/supabase-js` packages:
+
+
+
+
```bash
npm install @supabase/ssr @supabase/supabase-js
```
-### Set environment variables
+
+
+
+
+```bash
+yarn add @supabase/ssr @supabase/supabase-js
+```
+
+
+
+
+
+```bash
+pnpm add @supabase/ssr @supabase/supabase-js
+```
+
+
+
+
+
+## Set environment variables
+
+In your environment variables file, set your Supabase URL and Supabase Anon Key:
+
+
+
-Create a `.env.local` file in your project root directory. You can get your `SUPABASE_URL` and `SUPABASE_ANON_KEY` from inside [your Supabase project's dashboard](https://supabase.com/dashboard/project/_/settings/api).
-
```bash .env.local
NEXT_PUBLIC_SUPABASE_URL=your_supabase_project_url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
@@ -28,8 +56,6 @@ NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
-Create a `.env.local` file in your project root directory. You can get your `SUPABASE_URL` and `SUPABASE_ANON_KEY` from inside [your Supabase project's dashboard](https://supabase.com/dashboard/project/_/settings/api).
-
```bash .env.local
PUBLIC_SUPABASE_URL=your_supabase_project_url
PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
@@ -38,8 +64,6 @@ PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
-Create a `.env` file in your project root directory. You can get your `SUPABASE_URL` and `SUPABASE_ANON_KEY` from inside [your Supabase project's dashboard](https://supabase.com/dashboard/project/_/settings/api).
-
```bash .env
PUBLIC_SUPABASE_URL=your_supabase_project_url
PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
@@ -48,8 +72,6 @@ PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
-Create a `.env` file in your project root directory. You can get your `SUPABASE_URL` and `SUPABASE_ANON_KEY` from inside [your Supabase project's dashboard](https://supabase.com/dashboard/project/_/settings/api).
-
```bash .env
SUPABASE_URL=your_supabase_project_url
SUPABASE_ANON_KEY=your_supabase_anon_key
@@ -58,32 +80,55 @@ SUPABASE_ANON_KEY=your_supabase_anon_key
-Create a `.env` file in your project root directory. You can get your `SUPABASE_URL` and `SUPABASE_ANON_KEY` from inside [your Supabase project's dashboard](https://supabase.com/dashboard/project/_/settings/api).
-
```bash .env
SUPABASE_URL=your_supabase_project_url
SUPABASE_ANON_KEY=your_supabase_anon_key
```
-Install [dotenv](https://www.npmjs.com/package/dotenv)
+Install [dotenv](https://www.npmjs.com/package/dotenv):
```bash
npm i dotenv
```
-and initialize it
+And initialize it:
-```js app.js
-const express = require("express")
-const dotenv = require("dotenv")
-dotenv.config()
-...
+
+
+
+
+```bash
+npm install dotenv
```
+
+
+
+
+```bash
+yarn add dotenv
+```
+
+
+
+
+
+```bash
+pnpm add dotenv
+```
+
+
+
+
+
-### Creating a client
+## Create a client
+
+You'll need some one-time setup code to configure your Supabase client to use cookies. Once your utility code is set up, you can use your new `createClient` utility functions to get a properly configured Supabase client.
+
+Use the browser client in code that runs on the browser, and the server client in code that runs on the server.
-Creating a Supabase client with the `ssr` package automatically configures it to use cookies. This means your user's session is available throughout the entire Next.js stack - client, server, App Router, Pages Router. It just works!
-
-
-
-For the client utility functions, it is recommended to create them in a separate `/utils/supabase` folder. That way, you can import them as `client` into any component or page that needs access to Supabase. For further information, you can look at the [Next.js Auth Guide](/docs/guides/auth/server-side/nextjs).
-
-
+The following code samples are for App Router. For help with Pages Router, see the [Next.js Server-Side Auth guide](/docs/guides/auth/server-side/nextjs?queryGroups=router&router=pages).
-
+
-```ts page.tsx
-"use client";
+```ts utils/supabase/client.tsx
+'use client'
import { createBrowserClient } from '@supabase/ssr'
-export default function Page () {
- const supabase = createBrowserClient(
+export function createClient() {
+ return createBrowserClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
)
-
- return ...
}
```
-
+
-
-
-Server Components only have read access to cookies. Check the `Middleware` tab for an example of refreshing expired sessions before loading a Server Component route.
-
-
-
-```ts page.tsx
-import { createServerClient, type CookieOptions } from '@supabase/ssr'
+```ts utils/supabase/server.tsx
+import { createServerClient } from '@supabase/ssr'
import { cookies } from 'next/headers'
-export default async function Page () {
+export function createClient() {
const cookieStore = cookies()
- const supabase = createServerClient(
+ return createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
- get(name: string) {
- return cookieStore.get(name)?.value
+ getAll() {
+ return cookieStore.getAll()
+ },
+ setAll(cookiesToSet) {
+ try {
+ cookiesToSet.forEach(({ name, value, options }) =>
+ cookieStore.set(name, value, options)
+ )
+ } catch {
+ // The `setAll` method was called from a Server Component.
+ // This can be ignored if you have middleware refreshing
+ // user sessions.
+ }
},
},
}
)
-
- return ...
}
```
@@ -163,72 +203,14 @@ export default async function Page () {
-
-
-Server Components only have read access to cookies. This `Middleware` example can be used to refresh expired sessions before loading Server Component routes.
-
-
+In Next.js, because Server Components cannot set cookies, you'll also need a middleware client to handle cookie refreshes. The middleware should run before every route that needs access to Supabase, or that is protected by Supabase Auth.
```ts middleware.ts
-import { createServerClient, type CookieOptions } from '@supabase/ssr'
-import { NextResponse, type NextRequest } from 'next/server'
+import { type NextRequest } from 'next/server'
+import { updateSession } from '@/utils/supabase/middleware'
export async function middleware(request: NextRequest) {
- let response = NextResponse.next({
- request: {
- headers: request.headers,
- },
- })
-
- const supabase = createServerClient(
- process.env.NEXT_PUBLIC_SUPABASE_URL!,
- process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
- {
- cookies: {
- get(name: string) {
- return request.cookies.get(name)?.value
- },
- set(name: string, value: string, options: CookieOptions) {
- request.cookies.set({
- name,
- value,
- ...options,
- })
- response = NextResponse.next({
- request: {
- headers: request.headers,
- },
- })
- response.cookies.set({
- name,
- value,
- ...options,
- })
- },
- remove(name: string, options: CookieOptions) {
- request.cookies.set({
- name,
- value: '',
- ...options,
- })
- response = NextResponse.next({
- request: {
- headers: request.headers,
- },
- })
- response.cookies.set({
- name,
- value: '',
- ...options,
- })
- },
- },
- }
- )
-
- await supabase.auth.getUser()
-
- return response
+ return await updateSession(request)
}
export const config = {
@@ -245,179 +227,69 @@ export const config = {
}
```
-
+```ts utils/supabase/middlware.ts
+import { createServerClient } from '@supabase/ssr'
+import { NextResponse, type NextRequest } from 'next/server'
-
-
-```ts route.ts
-import { createServerClient, type CookieOptions } from '@supabase/ssr'
-import { cookies } from 'next/headers'
-
-export async function POST(request: Request) {
- const cookieStore = cookies()
+export async function updateSession(request: NextRequest) {
+ let supabaseResponse = NextResponse.next({
+ request,
+ })
const supabase = createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
- get(name: string) {
- return cookieStore.get(name)?.value
+ getAll() {
+ return request.cookies.getAll()
},
- set(name: string, value: string, options: CookieOptions) {
- cookieStore.set({ name, value, ...options })
- },
- remove(name: string, options: CookieOptions) {
- cookieStore.set({ name, value: '', ...options })
+ setAll(cookiesToSet) {
+ cookiesToSet.forEach(({ name, value, options }) => request.cookies.set(name, value))
+ supabaseResponse = NextResponse.next({
+ request,
+ })
+ cookiesToSet.forEach(({ name, value, options }) =>
+ supabaseResponse.cookies.set(name, value, options)
+ )
},
},
}
)
- return ...
-}
-```
+ // IMPORTANT: Avoid writing any logic between createServerClient and
+ // supabase.auth.getUser(). A simple mistake could make it very hard to debug
+ // issues with users being randomly logged out.
-
+ const {
+ data: { user },
+ } = await supabase.auth.getUser()
-
-
-```ts page.tsx
-import { createServerClient, type CookieOptions } from '@supabase/ssr'
-import { cookies } from 'next/headers'
-
-export default async function Page () {
- const serverAction = async () => {
- 'use server'
-
- const cookieStore = cookies()
-
- const supabase = createServerClient(
- process.env.NEXT_PUBLIC_SUPABASE_URL!,
- process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
- {
- cookies: {
- get(name: string) {
- return cookieStore.get(name)?.value
- },
- set(name: string, value: string, options: CookieOptions) {
- cookieStore.set({ name, value, ...options })
- },
- remove(name: string, options: CookieOptions) {
- cookieStore.set({ name, value: '', ...options })
- },
- },
- }
- )
+ if (
+ !user &&
+ !request.nextUrl.pathname.startsWith('/login') &&
+ !request.nextUrl.pathname.startsWith('/auth')
+ ) {
+ // no user, potentially respond by redirecting the user to the login page
+ const url = request.nextUrl.clone()
+ url.pathname = '/login'
+ return NextResponse.redirect(url)
}
- return ...
-}
-```
+ // IMPORTANT: You *must* return the supabaseResponse object as it is. If you're
+ // creating a new response object with NextResponse.next() make sure to:
+ // 1. Pass the request in it, like so:
+ // const myNewResponse = NextResponse.next({ request })
+ // 2. Copy over the cookies, like so:
+ // myNewResponse.cookies.setAll(supabaseResponse.cookies.getAll())
+ // 3. Change the myNewResponse object to fit your needs, but avoid changing
+ // the cookies!
+ // 4. Finally:
+ // return myNewResponse
+ // If this is not done, you may be causing the browser and server to go out
+ // of sync and terminate the user's session prematurely!
-
-
-
-
-```ts index.tsx
-import { type GetServerSidePropsContext } from 'next'
-import { createServerClient, type CookieOptions, serialize } from '@supabase/ssr'
-
-export const getServerSideProps = async (context: GetServerSidePropsContext) => {
- const supabase = createServerClient(
- process.env.NEXT_PUBLIC_SUPABASE_URL!,
- process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
- {
- cookies: {
- get(name: string) {
- return context.req.cookies[name];
- },
- set(name: string, value: string, options: CookieOptions) {
- context.res.appendHeader(
- "Set-Cookie",
- serialize(name, value, options)
- );
- },
- remove(name: string, options: CookieOptions) {
- context.res.appendHeader("Set-Cookie", serialize(name, "", options));
- },
- },
- }
- )
-
- return {...}
-}
-```
-
-
-
-
-
-The `getStaticProps` function gets executed at build time, rather than per request. At build time,
-there is no user, session or cookies. Therefore, we can use the standard `createClient` function
-from `supabase-js`.
-
-```ts page.tsx
-import { createClient } from '@supabase/supabase-js'
-
-export const getStaticProps = async () => {
- const supabase = createClient(
- process.env.NEXT_PUBLIC_SUPABASE_URL!,
- process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
- )
-
- return {...}
-}
-```
-
-
-
-
-
-```ts index.tsx
-import { createServerClient, type CookieOptions, serialize } from "@supabase/ssr"
-import { type NextApiRequest, type NextApiResponse } from "next"
-
-export default async function handler(
- req: NextApiRequest,
- res: NextApiResponse
-) {
- const supabase = createServerClient(
- process.env.NEXT_PUBLIC_SUPABASE_URL!,
- process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
- {
- cookies: {
- get(name: string) {
- return req.cookies[name];
- },
- set(name: string, value: string, options: CookieOptions) {
- res.setHeader("Set-Cookie", serialize(name, value, options));
- },
- remove(name: string, options: CookieOptions) {
- res.setHeader("Set-Cookie", serialize(name, "", options));
- },
- },
- }
- )
-
- res.send(...)
-}
-```
-
-
-
-
-
-```ts index.tsx
-import { createBrowserClient } from "@supabase/ssr"
-
-export default function Index () {
- const supabase = createBrowserClient(
- process.env.NEXT_PUBLIC_SUPABASE_URL!,
- process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
- )
-
- return ...
+ return supabaseResponse
}
```
@@ -427,8 +299,6 @@ export default function Index () {
-Creating a Supabase client with the `ssr` package automatically configures it to use Cookies. This means your user's session is available throughout the entire SvelteKit stack - page, layout, server, hooks.
-
-
-
-API routes, server layout load and form actions can now access the supabase client from the `event` object due to this hook.
-
-
-
```ts hooks.server.ts
import { PUBLIC_SUPABASE_URL, PUBLIC_SUPABASE_ANON_KEY } from '$env/static/public'
import { createServerClient } from '@supabase/ssr'
@@ -452,18 +316,19 @@ import type { Handle } from '@sveltejs/kit'
export const handle: Handle = async ({ event, resolve }) => {
event.locals.supabase = createServerClient(PUBLIC_SUPABASE_URL, PUBLIC_SUPABASE_ANON_KEY, {
cookies: {
- get: (key) => event.cookies.get(key),
- /**
- * Note: You have to add the `path` variable to the
- * set and remove method due to sveltekit's cookie API
- * requiring this to be set, setting the path to an empty string
- * will replicate previous/standard behaviour (https://kit.svelte.dev/docs/types#public-types-cookies)
- */
- set: (key, value, options) => {
- event.cookies.set(key, value, { ...options, path: '/' })
+ getAll() {
+ return event.cookies.getAll()
},
- remove: (key, options) => {
- event.cookies.delete(key, { ...options, path: '/' })
+ setAll(cookiesToSet) {
+ /**
+ * Note: You have to add the `path` variable to the
+ * set and remove method due to sveltekit's cookie API
+ * requiring this to be set, setting the path to an empty string
+ * will replicate previous/standard behavior (https://kit.svelte.dev/docs/types#public-types-cookies)
+ */
+ cookiesToSet.forEach(({ name, value, options }) =>
+ event.cookies.set(name, value, { ...options, path: '/' })
+ )
},
},
})
@@ -505,16 +370,12 @@ export const handle: Handle = async ({ event, resolve }) => {
-
-
Page components can get access to the supabase client from the `data` object due to this load function.
-
-
```ts +layout.ts
import { PUBLIC_SUPABASE_ANON_KEY, PUBLIC_SUPABASE_URL } from '$env/static/public'
import type { LayoutLoad } from './$types'
-import { createBrowserClient, createServerClient, isBrowser, parse } from '@supabase/ssr'
+import { createBrowserClient, createServerClient, isBrowser } from '@supabase/ssr'
export const load: LayoutLoad = async ({ fetch, data, depends }) => {
depends('supabase:auth')
@@ -524,20 +385,14 @@ export const load: LayoutLoad = async ({ fetch, data, depends }) => {
global: {
fetch,
},
- cookies: {
- get(key) {
- const cookie = parse(document.cookie)
- return cookie[key]
- },
- },
})
: createServerClient(PUBLIC_SUPABASE_URL, PUBLIC_SUPABASE_ANON_KEY, {
global: {
fetch,
},
cookies: {
- get() {
- return JSON.stringify(data.session)
+ getAll() {
+ return data.cookies
},
},
})
@@ -562,64 +417,19 @@ export const load: LayoutLoad = async ({ fetch, data, depends }) => {
```ts +layout.server.ts
import type { LayoutServerLoad } from './$types'
-export const load: LayoutServerLoad = async ({ locals: { safeGetSession } }) => {
+export const load: LayoutServerLoad = async ({ locals: { safeGetSession }, cookies }) => {
const { session, user } = await safeGetSession()
return {
session,
user,
+ cookies: cookies.getAll(),
}
}
```
-
-
-```svelte +page.svelte
-
-
-....
-```
-
-
-
-
-
-```ts +server.ts
-import { redirect } from '@sveltejs/kit';
-
-export const GET = async (event) => {
- const { url, locals: { supabase } } = event
- ...
-}
-```
-
-
-
-
-
-```ts +page.server.ts
-import type { Actions } from './$types'
-
-export const actions: Actions = {
- default: async (event) => {
- const { request, url, locals: { supabase } } = event
- const formData = await request.formData()
- const email = formData.get('email') as string
- const password = formData.get('password') as string
- ...
- }
-}
-```
-
-
@@ -646,21 +456,19 @@ export default defineConfig({
```ts index.astro
---
-import { createServerClient, type CookieOptions } from "@supabase/ssr";
+import { createServerClient, parseCookieHeader } from "@supabase/ssr";
const supabase = createServerClient(
import.meta.env.PUBLIC_SUPABASE_URL,
import.meta.env.PUBLIC_SUPABASE_ANON_KEY,
{
cookies: {
- get(key: string) {
- return Astro.cookies.get(key)?.value;
+ getAll() {
+ return parseCookieHeader(Astro.request.headers.get('Cookie') ?? '')
},
- set(key: string, value: string, options: CookieOptions) {
- Astro.cookies.set(key, value, options);
- },
- remove(key: string, options) {
- Astro.cookies.delete(key, options);
+ setAll(cookiesToSet) {
+ cookiesToSet.forEach(({ name, value, options }) =>
+ Astro.cookies.set(name, value, options))
},
},
}
@@ -686,7 +494,7 @@ const supabase = createServerClient(
```ts route.ts
-import { createServerClient, type CookieOptions } from "@supabase/ssr";
+import { createServerClient, parseCookieHeader } from "@supabase/ssr";
import type { APIContext } from "astro";
export async function GET(context: APIContext) {
@@ -695,14 +503,12 @@ export async function GET(context: APIContext) {
import.meta.env.PUBLIC_SUPABASE_ANON_KEY,
{
cookies: {
- get(key: string) {
- return context.cookies.get(key)?.value;
+ getAll() {
+ return parseCookieHeader(context.request.headers.get('Cookie') ?? '')
},
- set(key: string, value: string, options: CookieOptions) {
- context.cookies.set(key, value, options);
- },
- remove(key: string, options) {
- context.cookies.delete(key, options);
+ setAll(cookiesToSet) {
+ cookiesToSet.forEach(({ name, value, options }) =>
+ context.cookies.set(name, value, options))
},
},
}
@@ -729,22 +535,20 @@ export async function GET(context: APIContext) {
```ts _index.tsx
import { type LoaderFunctionArgs } from '@remix-run/node'
-import { createServerClient, parse, serialize } from '@supabase/ssr'
+import { createServerClient, parseCookieHeader, serializeCookieHeader } from '@supabase/ssr'
export async function loader({ request }: LoaderFunctionArgs) {
- const cookies = parse(request.headers.get('Cookie') ?? '')
const headers = new Headers()
const supabase = createServerClient(process.env.SUPABASE_URL!, process.env.SUPABASE_ANON_KEY!, {
cookies: {
- get(key) {
- return cookies[key]
+ getAll() {
+ return parseCookieHeader(request.headers.get('Cookie') ?? '')
},
- set(key, value, options) {
- headers.append('Set-Cookie', serialize(key, value, options))
- },
- remove(key, options) {
- headers.append('Set-Cookie', serialize(key, '', options))
+ setAll(cookiesToSet) {
+ cookiesToSet.forEach(({ name, value, options }) =>
+ headers.append('Set-Cookie', serializeCookieHeader(name, value, options))
+ )
},
},
})
@@ -761,22 +565,20 @@ export async function loader({ request }: LoaderFunctionArgs) {
```ts _index.tsx
import { type ActionFunctionArgs } from '@remix-run/node'
-import { createServerClient, parse, serialize } from '@supabase/ssr'
+import { createServerClient, parseCookieHeader, serializeCookieHeader } from '@supabase/ssr'
export async function action({ request }: ActionFunctionArgs) {
- const cookies = parse(request.headers.get('Cookie') ?? '')
const headers = new Headers()
const supabase = createServerClient(process.env.SUPABASE_URL!, process.env.SUPABASE_ANON_KEY!, {
cookies: {
- get(key) {
- return cookies[key]
+ getAll() {
+ return parseCookieHeader(request.headers.get('Cookie') ?? '')
},
- set(key, value, options) {
- headers.append('Set-Cookie', serialize(key, value, options))
- },
- remove(key, options) {
- headers.append('Set-Cookie', serialize(key, '', options))
+ setAll(cookiesToSet) {
+ cookiesToSet.forEach(({ name, value, options }) =>
+ headers.append('Set-Cookie', serializeCookieHeader(name, value, options))
+ )
},
},
})
@@ -831,27 +633,18 @@ export default function Index() {
```ts lib/supabase.js
-const { createServerClient } = require('@supabase/ssr')
+const { createServerClient, parseCookieHeader, serializeCookieHeader } = require('@supabase/ssr')
exports.createClient = (context) => {
return createServerClient(process.env.SUPABASE_URL, process.env.SUPABASE_ANON_KEY, {
cookies: {
- get: (key) => {
- const cookies = context.req.cookies
- const cookie = cookies[key] ?? ''
- return decodeURIComponent(cookie)
+ getAll() {
+ return parseCookieHeader(context.req.headers.cookie ?? '')
},
- set: (key, value, options) => {
- if (!context.res) return
- context.res.cookie(key, encodeURIComponent(value), {
- ...options,
- sameSite: 'Lax',
- httpOnly: true,
- })
- },
- remove: (key, options) => {
- if (!context.res) return
- context.res.cookie(key, '', { ...options, httpOnly: true })
+ setAll(cookiesToSet) {
+ cookiesToSet.forEach(({ name, value, options }) =>
+ context.res.appendHeader('Set-Cookie', serializeCookieHeader(name, value, options))
+ )
},
},
})
diff --git a/apps/docs/content/guides/auth/server-side/nextjs.mdx b/apps/docs/content/guides/auth/server-side/nextjs.mdx
index 8ddc10fafa5..f50b55645b5 100644
--- a/apps/docs/content/guides/auth/server-side/nextjs.mdx
+++ b/apps/docs/content/guides/auth/server-side/nextjs.mdx
@@ -74,7 +74,7 @@ Create a `utils/supabase` folder with a file for each type of client. Then copy
className="text-foreground-light mt-8 mb-6"
>
-
What does the `cookies` object do?}
id="utility-cookies"
>
@@ -85,11 +85,11 @@ Create a `utils/supabase` folder with a file for each type of client. Then copy
The cookie is named `sb--auth-token` by default.
-
+
-
Do I need to create a new client for every route?}
id="client-deduplication"
>
@@ -99,7 +99,7 @@ Create a `utils/supabase` folder with a file for each type of client. Then copy
- On the server, it basically configures a `fetch` call. You need to reconfigure the fetch call anew for every request to your server, because you need the cookies from the request.
- On the client, `createBrowserClient` already uses a singleton pattern, so you only ever create one instance, no matter how many times you call your `createClient` function.
-
+
@@ -133,23 +133,16 @@ export function createClient() {
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
- get(name: string) {
- return cookieStore.get(name)?.value
+ getAll() {
+ return cookieStore.getAll()
},
- set(name: string, value: string, options: CookieOptions) {
+ setAll(cookiesToSet) {
try {
- cookieStore.set({ name, value, ...options })
- } catch (error) {
- // The `set` method was called from a Server Component.
- // This can be ignored if you have middleware refreshing
- // user sessions.
- }
- },
- remove(name: string, options: CookieOptions) {
- try {
- cookieStore.set({ name, value: '', ...options })
- } catch (error) {
- // The `delete` method was called from a Server Component.
+ cookiesToSet.forEach(({ name, value, options }) =>
+ cookieStore.set(name, value, options)
+ )
+ } catch {
+ // The `setAll` method was called from a Server Component.
// This can be ignored if you have middleware refreshing
// user sessions.
}
@@ -225,14 +218,12 @@ export const config = {
```
```ts utils/supabase/middleware.ts
-import { createServerClient, type CookieOptions } from '@supabase/ssr'
+import { createServerClient } from '@supabase/ssr'
import { NextResponse, type NextRequest } from 'next/server'
export async function updateSession(request: NextRequest) {
- let response = NextResponse.next({
- request: {
- headers: request.headers,
- },
+ let supabaseResponse = NextResponse.next({
+ request,
})
const supabase = createServerClient(
@@ -240,50 +231,55 @@ export async function updateSession(request: NextRequest) {
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
- get(name: string) {
- return request.cookies.get(name)?.value
+ getAll() {
+ return request.cookies.getAll()
},
- set(name: string, value: string, options: CookieOptions) {
- request.cookies.set({
- name,
- value,
- ...options,
- })
- response = NextResponse.next({
- request: {
- headers: request.headers,
- },
- })
- response.cookies.set({
- name,
- value,
- ...options,
- })
- },
- remove(name: string, options: CookieOptions) {
- request.cookies.set({
- name,
- value: '',
- ...options,
- })
- response = NextResponse.next({
- request: {
- headers: request.headers,
- },
- })
- response.cookies.set({
- name,
- value: '',
- ...options,
+ setAll(cookiesToSet) {
+ cookiesToSet.forEach(({ name, value, options }) => request.cookies.set(name, value))
+ supabaseResponse = NextResponse.next({
+ request,
})
+ cookiesToSet.forEach(({ name, value, options }) =>
+ supabaseResponse.cookies.set(name, value, options)
+ )
},
},
}
)
- await supabase.auth.getUser()
+ // IMPORTANT: Avoid writing any logic between createServerClient and
+ // supabase.auth.getUser(). A simple mistake could make it very hard to debug
+ // issues with users being randomly logged out.
- return response
+ const {
+ data: { user },
+ } = await supabase.auth.getUser()
+
+ if (
+ !user &&
+ !request.nextUrl.pathname.startsWith('/login') &&
+ !request.nextUrl.pathname.startsWith('/auth')
+ ) {
+ // no user, potentially respond by redirecting the user to the login page
+ const url = request.nextUrl.clone()
+ url.pathname = '/login'
+ return NextResponse.redirect(url)
+ }
+
+ // IMPORTANT: You *must* return the supabaseResponse object as it is. If you're
+ // creating a new response object with NextResponse.next() make sure to:
+ // 1. Pass the request in it, like so:
+ // const myNewResponse = NextResponse.next({ request })
+ // 2. Copy over the cookies, like so:
+ // myNewResponse.cookies.setAll(supabaseResponse.cookies.getAll())
+ // 3. Change the myNewResponse object to fit your needs, but avoid changing
+ // the cookies!
+ // 4. Finally:
+ // return myNewResponse
+ // If this is not done, you may be causing the browser and server to go out
+ // of sync and terminate the user's session prematurely!
+
+ return supabaseResponse
}
```
@@ -424,6 +420,7 @@ import { type EmailOtpType } from '@supabase/supabase-js'
import { type NextRequest, NextResponse } from 'next/server'
import { createClient } from '@/utils/supabase/server'
+import { redirect } from 'next/navigation'
export async function GET(request: NextRequest) {
const { searchParams } = new URL(request.url)
@@ -431,11 +428,6 @@ export async function GET(request: NextRequest) {
const type = searchParams.get('type') as EmailOtpType | null
const next = searchParams.get('next') ?? '/'
- const redirectTo = request.nextUrl.clone()
- redirectTo.pathname = next
- redirectTo.searchParams.delete('token_hash')
- redirectTo.searchParams.delete('type')
-
if (token_hash && type) {
const supabase = createClient()
@@ -444,14 +436,13 @@ export async function GET(request: NextRequest) {
token_hash,
})
if (!error) {
- redirectTo.searchParams.delete('next')
- return NextResponse.redirect(redirectTo)
+ // redirect user to specified redirect URL or root of app
+ redirect(next)
}
}
- // return the user to an error page with some instructions
- redirectTo.pathname = '/error'
- return NextResponse.redirect(redirectTo)
+ // redirect the user to an error page with some instructions
+ redirect('/error')
}
```
@@ -589,7 +580,7 @@ Create a `utils/supabase` folder with a file for each type of client. Then copy
className="text-foreground-light mt-8 mb-6"
>
-
Why do I need so many types of clients?}
id="nextjs-clients"
>
@@ -601,11 +592,11 @@ Create a `utils/supabase` folder with a file for each type of client. Then copy
- **Component** - Runs on the client. Reads cookies from browser storage. Behind the scenes, `createBrowserClient` reuses the same client instance if called multiple times, so don't worry about deduplicating the client yourself.
- **API route** - Runs on the server. Reads cookies from the request, which is passed through from `NextApiRequest`.
-
+
-
What does the `cookies` object do?}
id="client-storage-cookies"
>
@@ -614,7 +605,7 @@ Create a `utils/supabase` folder with a file for each type of client. Then copy
The cookie is named `sb--auth-token` by default.
-
+
@@ -626,23 +617,25 @@ Create a `utils/supabase` folder with a file for each type of client. Then copy
```ts utils/supabase/server-props.ts
-import { createServerClient, type CookieOptions, serialize } from '@supabase/ssr'
import { type GetServerSidePropsContext } from 'next'
+import { createServerClient, serializeCookieHeader } from '@supabase/ssr'
-export function createClient(context: GetServerSidePropsContext) {
+export function createClient({ req, res }: GetServerSidePropsContext) {
const supabase = createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
- get(name: string) {
- return context.req.cookies[name]
+ getAll() {
+ return Object.keys(req.cookies).map((name) => ({ name, value: req.cookies[name] || '' }))
},
- set(name: string, value: string, options: CookieOptions) {
- context.res.appendHeader('Set-Cookie', serialize(name, value, options))
- },
- remove(name: string, options: CookieOptions) {
- context.res.appendHeader('Set-Cookie', serialize(name, '', options))
+ setAll(cookiesToSet) {
+ res.setHeader(
+ 'Set-Cookie',
+ cookiesToSet.map(({ name, value, options }) =>
+ serializeCookieHeader(name, value, options)
+ )
+ )
},
},
}
@@ -688,14 +681,14 @@ export default function createClient(req: NextApiRequest, res: NextApiResponse)
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
- get(name: string) {
- return req.cookies[name]
+ getAll() {
+ return Object.keys(req.cookies).map((name) => ({ name, value: req.cookies[name] || '' }))
},
- set(name: string, value: string, options: CookieOptions) {
- res.appendHeader('Set-Cookie', serialize(name, value, options))
- },
- remove(name: string, options: CookieOptions) {
- res.appendHeader('Set-Cookie', serialize(name, '', options))
+ setAll(cookiesToSet) {
+ res.setHeader(
+ 'Set-Cookie',
+ cookiesToSet.map(({ name, value, options }) => serialize(name, value, options))
+ )
},
},
}
diff --git a/apps/docs/content/guides/auth/server-side/sveltekit.mdx b/apps/docs/content/guides/auth/server-side/sveltekit.mdx
index 538614629a4..ebc5e57ba38 100644
--- a/apps/docs/content/guides/auth/server-side/sveltekit.mdx
+++ b/apps/docs/content/guides/auth/server-side/sveltekit.mdx
@@ -78,17 +78,16 @@ const supabase: Handle = async ({ event, resolve }) => {
*/
event.locals.supabase = createServerClient(PUBLIC_SUPABASE_URL, PUBLIC_SUPABASE_ANON_KEY, {
cookies: {
- get: (key) => event.cookies.get(key),
+ getAll: () => event.cookies.getAll(),
/**
* SvelteKit's cookies API requires `path` to be explicitly set in
* the cookie options. Setting `path` to `/` replicates previous/
* standard behavior.
*/
- set: (key, value, options) => {
- event.cookies.set(key, value, { ...options, path: '/' })
- },
- remove: (key, options) => {
- event.cookies.delete(key, { ...options, path: '/' })
+ setAll: (cookiesToSet) => {
+ cookiesToSet.forEach(({ name, value, options }) => {
+ event.cookies.set(name, value, { ...options, path: '/' })
+ })
},
},
})
@@ -135,11 +134,11 @@ const authGuard: Handle = async ({ event, resolve }) => {
event.locals.user = user
if (!event.locals.session && event.url.pathname.startsWith('/private')) {
- return redirect(303, '/auth')
+ redirect(303, '/auth')
}
if (event.locals.session && event.url.pathname === '/auth') {
- return redirect(303, '/private')
+ redirect(303, '/private')
}
return resolve(event)
@@ -174,7 +173,9 @@ declare global {
session: Session | null
user: User | null
}
- // interface PageData {}
+ interface PageData {
+ session: Session | null
+ }
// interface PageState {}
// interface Platform {}
}
@@ -200,10 +201,8 @@ Create a Supabase client in your root `+layout.ts`. This client can be used to a
```ts src/routes/+layout.ts
-import { createBrowserClient, createServerClient, isBrowser, parse } from '@supabase/ssr'
-
+import { createBrowserClient, createServerClient, isBrowser } from '@supabase/ssr'
import { PUBLIC_SUPABASE_ANON_KEY, PUBLIC_SUPABASE_URL } from '$env/static/public'
-
import type { LayoutLoad } from './$types'
export const load: LayoutLoad = async ({ data, depends, fetch }) => {
@@ -218,20 +217,14 @@ export const load: LayoutLoad = async ({ data, depends, fetch }) => {
global: {
fetch,
},
- cookies: {
- get(key) {
- const cookie = parse(document.cookie)
- return cookie[key]
- },
- },
})
: createServerClient(PUBLIC_SUPABASE_URL, PUBLIC_SUPABASE_ANON_KEY, {
global: {
fetch,
},
cookies: {
- get() {
- return JSON.stringify(data.session)
+ getAll() {
+ return data.cookies
},
},
})
@@ -256,9 +249,10 @@ export const load: LayoutLoad = async ({ data, depends, fetch }) => {
```ts src/routes/+layout.server.ts
import type { LayoutServerLoad } from './$types'
-export const load: LayoutServerLoad = async ({ locals: { session } }) => {
+export const load: LayoutServerLoad = async ({ locals: { session }, cookies }) => {
return {
session,
+ cookies: cookies.getAll(),
}
}
```
@@ -281,7 +275,7 @@ Set up a listener for Auth events on the client, to handle session refreshes and
```svelte src/routes/+layout.svelte
User Management
-
+
```
-Create a `src/routes/+page.server.ts` file that will return our website URL to be used in our `redirectTo` above.
+Create a `src/routes/+page.server.ts` file that will handle our magic link form when submitted.
-```ts
+```ts src/routes/+page.server.ts
// src/routes/+page.server.ts
-import { redirect } from '@sveltejs/kit'
-import type { PageServerLoad } from './$types'
+import { fail, redirect } from '@sveltejs/kit'
+import type { Actions, PageServerLoad } from './$types'
export const load: PageServerLoad = async ({ url, locals: { safeGetSession } }) => {
const { session } = await safeGetSession()
@@ -295,62 +316,109 @@ export const load: PageServerLoad = async ({ url, locals: { safeGetSession } })
return { url: url.origin }
}
+
+export const actions: Actions = {
+ default: async (event) => {
+ const {
+ url,
+ request,
+ locals: { supabase },
+ } = event
+ const formData = await request.formData()
+ const email = formData.get('email') as string
+ const validEmail = /^[\w-\.+]+@([\w-]+\.)+[\w-]{2,8}$/.test(email)
+
+ if (!validEmail) {
+ return fail(400, { errors: { email: 'Please enter a valid email address' }, email })
+ }
+
+ const { error } = await supabase.auth.signInWithOtp({ email })
+
+ if (error) {
+ return fail(400, {
+ success: false,
+ email,
+ message: `There was an issue, Please contact support.`,
+ })
+ }
+
+ return {
+ success: true,
+ message: 'Please check your email for a magic link to log into the website.',
+ }
+ },
+}
```
-### Proof Key for Code Exchange (PKCE)
+### Email template
-As we are employing Proof Key for Code Exchange (PKCE) in our authentication flow, it is necessary to create a server endpoint responsible for exchanging the code for a session.
+Change the email template to support a server-side authentication flow.
+
+Before we proceed, let's change the email template to support sending a token hash:
+
+- Go to the [Auth templates](/dashboard/project/_/auth/templates) page in your dashboard.
+- Select `Confirm signup` template.
+- Change `{{ .ConfirmationURL }}` to `{{ .SiteURL }}/auth/confirm?token_hash={{ .TokenHash }}&type=email`.
+- Repeat the previous step for `Magic link` template.
+
+
+
+Did you know? You could also customize emails sent out to new users, including the email's looks, content, and query parameters. Check out the [settings of your project](/dashboard/project/_/auth/templates).
+
+
+
+### Confirmation endpoint
+
+As we are working in a server-side rendering (SSR) environment, it is necessary to create a server endpoint responsible for exchanging the `token_hash` for a session.
In the following code snippet, we perform the following steps:
-- Retrieve the code sent back from the Supabase Auth server using the `code` query parameter.
-- Exchange this code for a session, which we store in our chosen storage mechanism (in this case, cookies).
-- Finally, we redirect the user to the `account` page.
+- Retrieve the `token_hash` sent back from the Supabase Auth server using the `token_hash` query parameter.
+- Exchange this `token_hash` for a session, which we store in storage (in this case, cookies).
+- Finally, the user is redirected to the `account` page or the `error` page.
-
-
-
-```js title=src/routes/auth/callback/+server.js
-// src/routes/auth/callback/+server.js
+```ts src/routes/auth/confirm/+server.ts
+// src/routes/auth/confirm/+server.ts
+import type { EmailOtpType } from '@supabase/supabase-js'
import { redirect } from '@sveltejs/kit'
-export const GET = async ({ url, locals: { supabase } }) => {
- const code = url.searchParams.get('code')
-
- if (code) {
- await supabase.auth.exchangeCodeForSession(code)
- }
-
- redirect(303, '/account')
-}
-```
-
-
-
-
-```ts title=src/routes/auth/callback/+server.ts
-// src/routes/auth/callback/+server.ts
-import { redirect, type RequestHandler } from '@sveltejs/kit'
+import type { RequestHandler } from './$types'
export const GET: RequestHandler = async ({ url, locals: { supabase } }) => {
- const code = url.searchParams.get('code')
+ const token_hash = url.searchParams.get('token_hash')
+ const type = url.searchParams.get('type') as EmailOtpType | null
+ const next = url.searchParams.get('next') ?? '/account'
- if (code) {
- await supabase.auth.exchangeCodeForSession(code)
+ /**
+ * Clean up the redirect URL by deleting the Auth flow parameters.
+ *
+ * `next` is preserved for now, because it's needed in the error case.
+ */
+ const redirectTo = new URL(url)
+ redirectTo.pathname = next
+ redirectTo.searchParams.delete('token_hash')
+ redirectTo.searchParams.delete('type')
+
+ if (token_hash && type) {
+ const { error } = await supabase.auth.verifyOtp({ type, token_hash })
+ if (!error) {
+ redirectTo.searchParams.delete('next')
+ redirect(303, redirectTo)
+ }
}
- redirect(303, '/account')
+ redirectTo.pathname = '/auth/error'
+ redirect(303, redirectTo)
}
```
-
-
+### Authentication error page
+
+If there is an error with confirming the token you will be redirect to this error page.
+
+```svelte src/routes/auth/error/+page.svelte
+Login error
+```
### Account page
diff --git a/apps/docs/content/guides/getting-started/tutorials/with-swift.mdx b/apps/docs/content/guides/getting-started/tutorials/with-swift.mdx
index e26045321ce..7a71bc87124 100644
--- a/apps/docs/content/guides/getting-started/tutorials/with-swift.mdx
+++ b/apps/docs/content/guides/getting-started/tutorials/with-swift.mdx
@@ -272,7 +272,7 @@ struct AppView: View {
}
}
.task {
- for await state in await supabase.auth.authStateChanges {
+ for await state in supabase.auth.authStateChanges {
if [.initialSession, .signedIn, .signedOut].contains(state.event) {
isAuthenticated = state.session != nil
}
diff --git a/apps/docs/content/guides/getting-started/tutorials/with-vue-3.mdx b/apps/docs/content/guides/getting-started/tutorials/with-vue-3.mdx
index 27778b2a6b2..09f6924a8c8 100644
--- a/apps/docs/content/guides/getting-started/tutorials/with-vue-3.mdx
+++ b/apps/docs/content/guides/getting-started/tutorials/with-vue-3.mdx
@@ -324,7 +324,7 @@ const uploadAvatar = async (evt) => {
}
}
-watch(path, () => {
+watchEffect(() => {
if (path.value) downloadImage()
})
@@ -365,6 +365,9 @@ And then we can add the widget to the Account page in `src/components/Account.vu
diff --git a/apps/docs/content/guides/platform/access-control.mdx b/apps/docs/content/guides/platform/access-control.mdx
index 02c5acca2a8..a45b9b2bae9 100644
--- a/apps/docs/content/guides/platform/access-control.mdx
+++ b/apps/docs/content/guides/platform/access-control.mdx
@@ -1,85 +1,264 @@
---
title: 'Access Control'
-description: 'Roles and permissions at the organization level'
+description: 'Roles and permissions at the organization and project levels'
---
-Supabase provides granular access controls to manage permissions across your organizations.
-For each organization, a member can have one of the following roles:
+Supabase provides granular access controls to manage permissions across your organizations and projects.
-- Owner
-- Administrator
-- Developer
+For each organization and project, a member can have one of the following roles:
+
+- **Owner**: full access to everything in organization and project resources.
+- **Administrator**: full access to everything in organization and project resources **except** updating organization settings, transferring projects outside of the organization, and adding new owners.
+- **Developer**: read-only access to organization resources and content access to project resources but cannot change any project settings.
+- **Read-Only**: read-only access to organization and project resources.
-Additional roles (Read-only and Billing) are available on the [team and enterprise plans](https://supabase.com/pricing).
+Read-Only role is only available on the [Team and Enterprise plans](https://supabase.com/pricing).
-A default organization is created when you first sign in, at which point you'll be assigned the **Owner** role. Keep in mind that members can access all projects within the organization and that project level access control is not available at this time. Create a separate organization if you need to restrict access to certain projects.
+When you first create an account, a default organization is created for you and you'll be assigned as the **Owner**. Any organizations you create will assign you as **Owner** as well.
-## Manage team members
+## Manage organization members
-To invite others to collaborate, visit your organization's team [settings](/dashboard/org/_/team) to send an invite link to another user's email. The invite expires after 24 hours.
+To invite others to collaborate, visit your organization's team [settings](/dashboard/org/_/team) to send an invite link to another user's email. The invite is valid for 24 hours. For project scoped roles, you may only assign a role to a single project for the user when sending the invite. You can assign roles to multiple projects after the user accepts the invite.
-Invites sent from a SAML SSO account can only be accepted by another SAML SSO account from the same identity provider. This is a security measure to prevent accidental invites to accounts not managed by your enterprise's identity provider.
+Invites sent from a SAML SSO account can only be accepted by another SAML SSO account from the same identity provider.
+
+This is a security measure to prevent accidental invites to accounts not managed by your enterprise's identity provider.
### Transferring ownership of an organization
-Each Supabase organization can have one or more owners. If you no longer want be an owner of an organization, click **Leave team** in your organization's team [settings](/dashboard/org/_/team). You can only leave an organization if there is _at least one other owner_. If you are transferring ownership of your organization to someone else, you will need to invite the new member with the **Owner** role. You can leave the organization after they've accepted the invitation.
+Each Supabase organization must have at least one owner. If your organization has other owners then you can relinquish ownership and leave the organization by clicking **Leave team** in your organization's team [settings](/dashboard/org/_/team).
-### Permissions across roles [#permission-across-roles]
+Otherwise, you'll need to invite a user as **Owner**, and they need to accept the invitation, or promote an existing organization member to **Owner** before you can leave the organization.
-The table below shows the corresponding permissions for each available role you can assign a team member in the Dashboard.
+### Organization Scoped Roles vs Project Scoped Roles
-| Permissions | Owner | Administrator | Developer | Read only [^2] |
-| ------------------------ | ----------------------- | ----------------------- | ----------------------- | ----------------------------------------------- |
-| **Organization** |
-| Change organization name | | | |
-| Delete organization | | | |
-| **Members** |
-| Add an Owner | | | |
-| Remove an Owner | | | |
-| Add an Administrator | | | |
-| Remove an Administrator | | | |
-| Add a Developer | | | |
-| Remove a Developer | | | |
-| Revoke an invite | | | |
-| Resend an invite | | | |
-| Accept an invite[^1] | | | |
-| **Billing** |
-| Read invoices | | | |
-| Read billing email | | | |
-| Change billing email | | | |
-| View subscription | | | |
-| Update subscription | | | |
-| Read billing address | | | |
-| Update billing address | | | |
-| Read tax codes | | | |
-| Update tax codes | | | |
-| Read payment methods | | | |
-| Update payment methods | | | |
-| **Projects** |
-| Create a project | | | |
-| Delete a project | | | |
-| Update a project | | | |
-| Pause a project | | | |
-| Resume a project | | | |
-| Restart a project | | | |
-| Manage tables | | | |
-| View Data | | | | [^3] |
+
-[^1]:
- Invites sent from a SSO account can only be accepted by another SSO account
- coming from the same identity provider. This is a security measure that
- prevents accidental invites to accounts not managed by your company's
- enterprise systems.
+Project scoped roles are only available on the [Enterprise Plan](https://supabase.com/pricing)
-[^2]: Available on the Teams and Enterprise Plans.
-[^3]:
- Only available on projects using PostgreSQL 14 and above. You can upgrade
- your project through [infrastructure settings](https://supabase.com/dashboard/project/_/settings/infrastructure).
+
+
+Each member in the organization can be assigned a role scoped to the organization or to specific projects. If the member has a role at the organization level, they will have the equivalent permissions for that role across all current and future projects in the organization.
+
+With project scoped permissions, you can assign members to roles scoped to specific projects.
+
+### Organization permissions across roles
+
+The table below shows the actions each role can take on the resources belonging to the organization.
+
+| Resource | Action | Owner | Administrator | Developer | Read-Only[^1] |
+| ----------------------------------------------------------------------------------------------------------- | ---------- | :-------------------------------------: | :-------------------------------------: | :-------------------------------------: | :-------------------------------------: |
+| **Organization** | | | | | |
+| Organization Management | Update | | | | |
+| | Delete | | | | |
+| **Members** | | | | | |
+| Organization Members | List | | | | |
+| Owner | Add | | | | |
+| | Remove | | | | |
+| Administrator | Add | | | | |
+| | Remove | | | | |
+| Developer | Add | | | | |
+| | Remove | | | | |
+| Owner (Project-Scoped) | Add | | | | |
+| | Remove | | | | |
+| Administrator (Project-Scoped) | Add | | | | |
+| | Remove | | | | |
+| Developer (Project-Scoped) | Add | | | | |
+| | Remove | | | | |
+| Invite | Revoke | | | | |
+| | Resend | | | | |
+| | Accept[^2] | | | | |
+| **Billing** | | | | | |
+| Invoices | List | | | | |
+| Billing Email | View | | | | |
+| | Update | | | | |
+| Subscription | View | | | | |
+| | Update | | | | |
+| Billing Address | View | | | | |
+| | Update | | | | |
+| Tax Codes | View | | | | |
+| | Update | | | | |
+| Payment Methods | View | | | | |
+| | Update | | | | |
+| Usage | View | | | | |
+| **Integrations (Org Settings)** | | | | | |
+| Authorize GitHub | - | | | | |
+| Add GitHub Repositories | - | | | | |
+| GitHub Connections | Create | | | | |
+| | Update | | | | |
+| | Delete | | | | |
+| | View | | | | |
+| Vercel Connections | Create | | | | |
+| | Update | | | | |
+| | Delete | | | | |
+| | View | | | | |
+| **OAuth Apps** | | | | | |
+| OAuth Apps | Create | | | | |
+| | Update | | | | |
+| | Delete | | | | |
+| | List | | | | |
+| **Audit Logs** | | | | | |
+| View Audit logs | - | | | | |
+| **Legal Documents** | | | | | |
+| SOC2 Type 2 Report | Download | | | | |
+| Security Questionnaire | Download | | | | |
+
+### Project permissions across roles
+
+The table below shows the actions each role can take on the resources belonging to the project.
+
+| Resource | Action | Owner | Admin | Developer | Read-Only [^3] |
+| ------------------------------------------------------------------------------------------------------ | ---------------------- | :-------------------------------------: | :-------------------------------------: | :-------------------------------------: | :-------------------------------------------------------------: |
+| **Project** | | | | | |
+| Project Management | Transfer | | | | |
+| | Create | | | | |
+| | Delete | | | | |
+| | Update (Name) | | | | |
+| | Pause | | | | |
+| | Restore | | | | |
+| | Restart | | | | |
+| Custom Domains | View | | | | |
+| | Update | | | | |
+| Data (Database) | View | | | | |
+| | Manage | | | | |
+| **Infrastructure** | | | | | |
+| Read Replicas | List | | | | |
+| | Create | | | | |
+| | Delete | | | | |
+| Addons | Update | | | | |
+| **Integrations** | | | | | |
+| Authorize GitHub | - | | | | |
+| Add GitHub Repositories | - | | | | |
+| GitHub Connections | Create | | | | |
+| | Update | | | | |
+| | Delete | | | | |
+| | View | | | | |
+| Vercel Connections | Create | | | | |
+| | Update | | | | |
+| | Delete | | | | |
+| | View | | | | |
+| **Database Configuration** | | | | | |
+| Reset Password | - | | | | |
+| Pooling Settings | View | | | | |
+| | Update | | | | |
+| SSL Configuration | View | | | | |
+| | Update | | | | |
+| Disk Size Configuration | View | | | | |
+| | Update | | | | |
+| Network Restrictions | View | | | | |
+| | Create | | | | |
+| | Delete | | | | |
+| Network Bans | View | | | | |
+| | Unban | | | | |
+| **API Configuration** | | | | | |
+| API Keys | Read service key | | | | |
+| | Read anon key | | | | |
+| JWT Secret | View | | | | |
+| | Generate new | | | | |
+| API settings | View | | | | |
+| | Update | | | | |
+| **Auth Configuration** | | | | | |
+| Auth Settings | View | | | | |
+| | Update | | | | |
+| SMTP Settings | View | | | | |
+| | Update | | | | |
+| Advanced Settings | View | | | | |
+| | Update | | | | |
+| **Storage Configuration** | | | | | |
+| Upload Limit | View | | | | |
+| | Update | | | | |
+| S3 Access Keys | View | | | | |
+| | Create | | | | |
+| | Delete | | | | |
+| **Edge Functions Configuration** | | | | | |
+| Secrets | View | | | | [^4] |
+| | Create | | | | |
+| | Delete | | | | |
+| **SQL Editor** | | | | | |
+| Queries | Create | | | | |
+| | Update | | | | |
+| | Delete | | | | |
+| | View | | | | |
+| | List | | | | |
+| | Run | | | | [^5] |
+| **Database** | | | | | |
+| Scheduled Backups | View | | | | |
+| | Download | | | | |
+| | Restore | | | | |
+| Physical backups (PITR) | View | | | | |
+| | Restore | | | | |
+| **Authentication** | | | | | |
+| Users | Create | | | | |
+| | Delete | | | | |
+| | List | | | | |
+| | Send OTP | | | | |
+| | Send password recovery | | | | |
+| | Send magic link | | | | |
+| | Remove MFA factors | | | | |
+| Providers | View | | | | |
+| | Update | | | | |
+| Rate Limits | View | | | | |
+| | Update | | | | |
+| Email Templates | View | | | | |
+| | Update | | | | |
+| URL Configuration | View | | | | |
+| | Update | | | | |
+| Hooks | View | | | | |
+| | Create | | | | |
+| | Delete | | | | |
+| **Storage** | | | | | |
+| Buckets | Create | | | | |
+| | Update | | | | |
+| | Delete | | | | |
+| | View | | | | |
+| | List | | | | |
+| Files | Create (Upload) | | | | |
+| | Update | | | | |
+| | Delete | | | | |
+| | List | | | | |
+| **Edge Functions** | | | | | |
+| Edge Functions | Update | | | | |
+| | Delete | | | | |
+| | View | | | | |
+| | List | | | | |
+| **Reports** | | | | | |
+| Custom Report | Create | | | | |
+| | Update | | | | |
+| | Delete | | | | |
+| | View | | | | |
+| | List | | | | |
+| **Logs & Analytics** | | | | | |
+| Queries | Create | | | | |
+| | Update | | | | |
+| | Delete | | | | |
+| | View | | | | |
+| | List | | | | |
+| | Run | | | | |
+| Events Collections | Create | | | | |
+| | Update | | | | |
+| | Delete | | | | |
+| | View | | | | |
+| | List | | | | |
+| Warehouse Access Tokens | Create | | | | |
+| | Revoke | | | | |
+| | List | | | | |
+| **Branching** | | | | | |
+| Enable branching | - | | | | |
+| Disable branching | - | | | | |
+| | Create | | | | |
+| | Delete | | | | |
+| | List | | | | |
+
+[^1]: Available on the Team and Enterprise Plans.
+[^2]: Invites sent from a SSO account can only be accepted by another SSO account coming from the same identity provider. This is a security measure that prevents accidental invites to accounts not managed by your company's enterprise systems.
+[^3]: Available on the Enterprise Plan.
+[^4]: Read-Only role is able to access secrets.
+[^5]: Limited to executing SELECT queries.
diff --git a/apps/docs/content/guides/platform/backups.mdx b/apps/docs/content/guides/platform/backups.mdx
index 76cf6333bd5..fd24962eff8 100644
--- a/apps/docs/content/guides/platform/backups.mdx
+++ b/apps/docs/content/guides/platform/backups.mdx
@@ -11,6 +11,12 @@ The Supabase team regularly monitors the status of backups. In case of any issue
+
+
+Once a project is deleted all associated data will be permanently removed, including any backups stored in S3. This action is irreversible and should be carefully considered before proceeding.
+
+
+
## Types of backups
Database backups can be categorized into two types: **logical** and **physical**. You can learn more about them [here](https://supabase.com/blog/postgresql-physical-logical-backups).
@@ -51,7 +57,7 @@ Database backups do not include objects stored via the Storage API, as the datab
## Daily backups
-All Pro and Enterprise plan Supabase projects are backed up automatically on a daily basis. In terms of Recovery Point Objective (RPO), Daily Backups would be suitable for projects willing to lose up to 24 hours worth of data if disaster hits at the most inopportune time. If a lower RPO is required, enabling Point-in-Time Recovery should be considered.
+All Pro, Team and Enterprise Plan Supabase projects are backed up automatically on a daily basis. In terms of Recovery Point Objective (RPO), Daily Backups would be suitable for projects willing to lose up to 24 hours worth of data if disaster hits at the most inopportune time. If a lower RPO is required, enabling Point-in-Time Recovery should be considered.
@@ -63,7 +69,7 @@ For security purposes, passwords for custom roles are not stored in daily backup
The PostgreSQL utility [pg_dumpall](https://www.postgresql.org/docs/current/app-pg-dumpall.html) is used to perform daily backups. An SQL file is generated, zipped up, and sent to our storage servers for safe keeping.
-You can access daily backups in the [Scheduled backups](https://supabase.com/dashboard/project/_/database/backups/scheduled) settings in the Dashboard. Pro plan projects can access the last 7 days' worth of daily backups while Enterprise plan projects can access up to 30 days' worth of daily backups. Users can restore their project to any one of the backups. If you wish to generate a logical backup on your own, you can do so through the [Supabase CLI](/docs/reference/cli/supabase-db-dump).
+You can access daily backups in the [Scheduled backups](https://supabase.com/dashboard/project/_/database/backups/scheduled) settings in the Dashboard. Pro Plan projects can access the last 7 days' worth of daily backups. Team Plan projects can access the last 14 days' worth of daily backups, while Enterprise Plan projects can access up to 30 days' worth of daily backups. Users can restore their project to any one of the backups. If you wish to generate a logical backup on your own, you can do so through the [Supabase CLI](/docs/reference/cli/supabase-db-dump).
#### Backup process for large databases
@@ -93,7 +99,7 @@ Point-in-Time Recovery (PITR) allows a project to be backed up at much shorter i
-This feature is available to all Enterprise plan projects. Pro and Team plan projects can enable PITR as an add-on.
+Pro, Team and Enterprise Plan projects can enable PITR as an add-on.
Projects interested in PITR will also need to use at least a Small compute add-on, in order to ensure smooth functioning.
diff --git a/apps/docs/content/guides/platform/billing-faq.mdx b/apps/docs/content/guides/platform/billing-faq.mdx
index 4c29c53557b..9c7c8ce9626 100644
--- a/apps/docs/content/guides/platform/billing-faq.mdx
+++ b/apps/docs/content/guides/platform/billing-faq.mdx
@@ -10,16 +10,16 @@ subtitle: 'This documentation covers frequently asked questions around subscript
#### What are organizations and projects?
The Supabase Platform has "organizations" and "projects". An organization may contain multiple projects. Each project is a dedicated Supabase instance with all of its sub-services including Storage, Auth, Functions and Realtime.
-Each organization only has a single subscription with a single plan (Free, Pro, Team or Enterprise). Project addons such as [Compute](https://supabase.com/docs/guides/platform/compute-add-ons), [Custom Domains](https://supabase.com/docs/guides/platform/custom-domains) and [PITR](https://supabase.com/docs/guides/platform/backups#point-in-time-recovery) are configured per project and are added to your organization subscription.
+Each organization only has a single subscription with a single Plan (Free, Pro, Team or Enterprise). Project addons such as [Compute](https://supabase.com/docs/guides/platform/compute-add-ons), [Custom Domains](https://supabase.com/docs/guides/platform/custom-domains) and [PITR](https://supabase.com/docs/guides/platform/backups#point-in-time-recovery) are configured per project and are added to your organization subscription.
Read more on [how billing is organized](https://supabase.com/docs/guides/platform/org-based-billing#how-billing-is-organized).
#### How many free projects can I have?
-You are entitled to two active free projects. Paused projects do not count towards your quota. Note that within an organization, we count the free project limits from all members that are either Owner or Admin. If you’ve got another organization member with the Admin or Owner role that has already exhausted their free project quota, you won’t be able to launch another free project in that organization. You can create simply create another free plan organization or change the role of the affected member in your [organization’s team settings](https://supabase.com/dashboard/org/_/team).
+You are entitled to two active free projects. Paused projects do not count towards your quota. Note that within an organization, we count the free project limits from all members that are either Owner or Admin. If you’ve got another organization member with the Admin or Owner role that has already exhausted their free project quota, you won’t be able to launch another free project in that organization. You can create another Free Plan organization or change the role of the affected member in your [organization’s team settings](https://supabase.com/dashboard/org/_/team).
#### Can I mix free and paid projects in a single organization?
-The subscription plan is set on the organization level and it is not possible to mix paid and non-paid projects inside a single organization. However, you can have a paid and a free organization and make use of the [self-serve project transfers](https://supabase.com/docs/guides/platform/project-transfer) to organize your projects. All projects in an organization benefit from the subscription plan. If your organization is on the Pro plan, all projects within the organization benefit from no project pausing, automated backups and so on.
+The subscription plan is set on the organization level and it is not possible to mix paid and non-paid projects inside a single organization. However, you can have a paid and a free organization and make use of the [self-serve project transfers](https://supabase.com/docs/guides/platform/project-transfer) to organize your projects. All projects in an organization benefit from the subscription plan. If your organization is on the Pro Plan, all projects within the organization benefit from no project pausing, automated backups and so on.
#### Can I transfer my projects to another organization?
@@ -39,12 +39,12 @@ No, we do not charge for paused projects. Compute hours are only counted for act
#### How are multiple projects billed under a paid organization?
-We provide a dedicated server for every Supabase project. Each paid organization comes with $10 in Compute Credits to cover one project on the default instance size. Additional projects start at ~$10 a month (billed hourly). See how billing for compute works [here](https://supabase.com/docs/guides/platform/org-based-billing#usage-based-billing-for-compute).
+We provide a dedicated server for every Supabase project. Each paid organization comes with $10 in Compute Credits to cover one project on the default compute size. Additional projects start at ~$10 a month (billed hourly). See how billing for compute works [here](https://supabase.com/docs/guides/platform/org-based-billing#usage-based-billing-for-compute).
-Running 3 projects in a Pro plan organization on the default micro instance:
+Running 3 projects in a Pro Plan organization on the default micro instance:
-- $25 Pro plan
-- $30 for 3 projects on the default compute instance size
+- $25 Pro Plan
+- $30 for 3 projects on the default compute size
- $10 Compute credits
⇒ $45 / month
@@ -72,7 +72,7 @@ To learn more about unified egress and its details, please refer to the informat
#### How do I change my subscription plan?
-Change your subscription plan in your [organization's billing settings](https://supabase.com/dashboard/org/_/billing). To upgrade to an Enterprise plan, complete the [Enterprise request form](https://forms.supabase.com/enterprise).
+Change your subscription plan in your [organization's billing settings](https://supabase.com/dashboard/org/_/billing). To upgrade to an Enterprise Plan, complete the [Enterprise request form](https://forms.supabase.com/enterprise).
#### What happens if I cancel my subscription?
@@ -84,17 +84,47 @@ We can transfer the amount as credits to another organization of your choice. Yo
## Quotas and spend caps
-#### What will happen when I exceed the free plan quota?
+#### What will happen when I exceed the Free Plan quota?
-When you exceed the Free plan quota, we will monitor and notify you about the exceeding limits. It is important to take action at this point. If you continue to exceed the limits without reducing your usage, we will pause your projects. To avoid project pausing, you have two options: reduce your usage or upgrade to a paid plan.
+You will be notified when you exceed the Free Plan quota. It is important to take action at this point. If you continue to exceed the limits without reducing your usage, service restrictions will apply. To avoid service restrictions, you have two options: reduce your usage or upgrade to a paid plan. Learn more about restrictions in the [Fair Use Policy](#fair-use-policy) section.
-#### What will happen when I exceed the Pro plan quota and have the spend cap on?
+#### What will happen when I exceed the Pro Plan quota and have the spend cap on?
-When you exceed the Pro plan quota, we will monitor and notify you about the exceeding limits. To unblock yourself, you can simply toggle off your spend cap in your [organization’s billing settings](https://supabase.com/dashboard/org/_/billing) to pay for over-usage beyond the Pro plans limits. If you continue to exceed the limits without reducing your usage or turning off the spend cap, we will pause your projects.
+You will be notified when you exceed your Pro Plan quota. To unblock yourself, you can toggle off your spend cap in your [organization’s billing settings](https://supabase.com/dashboard/org/_/billing) to pay for over-usage beyond the Pro plans limits. If you continue to exceed the limits without reducing your usage or turning off the spend cap, restrictions will apply. Learn more about restrictions in the [Fair Use Policy](#fair-use-policy) section.
-#### How do I scale beyond the limits of my Pro plan?
+#### How do I scale beyond the limits of my Pro Plan?
-The Pro plan has a spend cap enabled by default to keep costs under control. If you want to scale beyond the plans included quota, ~~simply~~ switch off the spend cap to pay for additional usage beyond the plans included limits. You can toggle the spend cap in the [organization's billing settings](https://supabase.com/dashboard/org/_/billing). Read more about the [spend cap](https://supabase.com/docs/guides/platform/spend-cap).
+The Pro Plan has a spend cap enabled by default to keep costs under control. If you want to scale beyond the plan's included quota, switch off the spend cap to pay for additional usage beyond the plans included limits. You can toggle the spend cap in the [organization's billing settings](https://supabase.com/dashboard/org/_/billing). Read more about the [spend cap](https://supabase.com/docs/guides/platform/spend-cap).
+
+## Fair Use Policy
+
+#### What is the Fair Use Policy?
+
+Our Fair Use Policy gives developers the freedom to build and experiment with Supabase, while protecting our infrastructure. Under the Fair Use policy, service restrictions may apply to your organization if:
+
+- You continually exceed the Free Plan quota
+- You continually exceed Pro Plan quota and have the spend cap enabled
+- You have overdue invoices
+- You have an expired credit card
+
+You will receive a notification before Fair Use Policy restrictions are applied. However, in some cases, like suspected abuse of our services, restrictions may be applied without prior notice.
+
+#### How is the Fair Use Policy applied?
+
+The Fair Use Policy is applied through service restrictions. This could mean:
+
+- Pausing projects
+- Switching databases to read-only mode
+- Disabling new project launches/transfers
+- Responding with a [402 status code](/docs/guides/platform/http-status-codes#402-service-restriction) for all API requests
+
+The Fair Use Policy is generally applied to all projects of the restricted organization.
+
+#### How can I remove restrictions applied from the Fair Use Policy?
+
+To remove restrictions, you will need to address the issue that caused the restriction. This could be reducing your usage, paying overdue invoices, updating your payment method, or any other issue that caused the restriction. Once the issue is resolved, the restriction will be lifted.
+
+Restrictions due to usage limits are lifted with the next billing cycle as your quota refills at the beginning of each cycle. You can see when your current billing cycle ends on the [billing page](https://supabase.com/dashboard/org/_/usage) under "Billing Breakdown". If your organization is on the Free Plan, you can also lift restrictions immediately by [upgrading](https://supabase.com/dashboard/org/_/billing?panel=subscriptionPlan) to Pro.
## Reports and invoices
@@ -144,7 +174,7 @@ Please note that any changes made to your billing details will only be reflected
#### What happens if I am unable to make the payment?
-When an invoice becomes overdue, we will pause your projects and downgrade your organization to the Free plan. You will be able to restore your projects once you have paid all outstanding invoices.
+When an invoice becomes overdue, we will pause your projects and downgrade your organization to the Free Plan. You will be able to restore your projects once you have paid all outstanding invoices.
#### Why am I overdue?
diff --git a/apps/docs/content/guides/platform/branching.mdx b/apps/docs/content/guides/platform/branching.mdx
index 95c97aa20cf..f5a0086377e 100644
--- a/apps/docs/content/guides/platform/branching.mdx
+++ b/apps/docs/content/guides/platform/branching.mdx
@@ -24,19 +24,16 @@ Supabase Branching works with Git. You can test changes in a separate, temporary
You can run multiple Preview Branches for every Supabase project. Branches contain all the Supabase features with their own API credentials. Preview Environments pause automatically after branching.inactivity_period_in_minutes minutes of inactivity. Note that `pg_cron` executions will be impacted by inactivity related pausing.
-
-
-
- Each Branch is a separate environment.
-
+
### Branching workflow
@@ -58,21 +55,16 @@ The Preview Branch is also seeded with sample data based on `./supabase/seed.sql
Supabase Branching follows the [Trunk Based Development](https://trunkbaseddevelopment.com/) workflow, with one main Production branch and multiple development branches:
-
-
-
-
- Each GitHub branch can have its own Supabase preview branch.
-
-
+
### Production branch
@@ -84,21 +76,16 @@ After connecting your Supabase project to one of the supported [Git providers](#
The Git integration can read files from your Git provider, watching every commit and pull request. Each time a commit is pushed with new migrations in the `./supabase/migrations` directory, the migrations are run on the matching Supabase Preview environment:
-
-
-
-
- New migration files trigger migrations on the preview instance.
-
-
+
### Data changes
@@ -517,11 +504,13 @@ When you open a pull request on GitHub, the Supabase integration automatically c
A comment is added to your PR with the deployment status of your preview branch. Statuses are shown separately for Database, Services, and APIs.
-
-
- {/* prettier-ignore */}
- Supabase GitHub integration will comment on your PR with the status of your Preview Branch, including whether migrations have successfully run.
-
+
Every time a new commit is pushed that changes the migration files in `./supabase/migrations`, the new migrations are run against the preview branch. You can check the status of these runs in the comment's Tasks table.
@@ -529,11 +518,13 @@ Every time a new commit is pushed that changes the migration files in `./supabas
We highly recommend turning on a 'required check' for the Supabase integration. You can do this from your GitHub repository settings. This prevents PRs from being merged when migration checks fail, and stops invalid migrations from being merged into your production branch.
-
-
- {/* prettier-ignore */}
- Check the "Require status checks to pass before merging" option.
-
+
### Disable branching
diff --git a/apps/docs/content/guides/platform/compute-add-ons.mdx b/apps/docs/content/guides/platform/compute-add-ons.mdx
index a8a2e3ad4e6..f5eb3e0dfa0 100644
--- a/apps/docs/content/guides/platform/compute-add-ons.mdx
+++ b/apps/docs/content/guides/platform/compute-add-ons.mdx
@@ -8,23 +8,23 @@ Every project on the Supabase Platform comes with its own dedicated Postgres ins
-Free plan resources subject to changes.
+Free Plan resources subject to changes.
-| Plan | Hourly Price USD | Monthly Price USD | CPU | Memory | Connections: Direct | Connections: Pooler | Recommended Maximum DB Size |
-| ----------- | ---------------- | ----------------- | ----------------------- | ------------ | ------------------- | ------------------- | --------------------------- |
-| Nano (free) | $0 | $0 | Shared | Up to 0.5 GB | 60 | 200 | 500MB |
-| Micro | $0.01344 | ~$10 | 2-core ARM (shared) | 1 GB | 60 | 200 | 10GB |
-| Small | $0.0206 | ~$15 | 2-core ARM (shared) | 2 GB | 90 | 400 | 50GB |
-| Medium | $0.0822 | ~$60 | 2-core ARM (shared) | 4 GB | 120 | 600 | 100GB |
-| Large | $0.1517 | ~$110 | 2-core ARM (dedicated) | 8 GB | 160 | 800 | 200GB |
-| XL | $0.2877 | ~$210 | 4-core ARM (dedicated) | 16 GB | 240 | 1,000 | 500GB |
-| 2XL | $0.562 | ~$410 | 8-core ARM (dedicated) | 32 GB | 380 | 1,500 | 1TB |
-| 4XL | $1.32 | ~$960 | 16-core ARM (dedicated) | 64 GB | 480 | 3,000 | 2TB |
-| 8XL | $2.562 | ~$1,870 | 32-core ARM (dedicated) | 128 GB | 490 | 6,000 | 4TB |
-| 12XL | $3.836 | ~$2,800 | 48-core ARM (dedicated) | 192 GB | 500 | 9,000 | 6TB |
-| 16XL | $5.12 | ~$3,730 | 64-core ARM (dedicated) | 256 GB | 500 | 12,000 | 10TB |
+| Compute Size | Hourly Price USD | Monthly Price USD | CPU | Memory | Connections: Direct | Connections: Pooler | Recommended Maximum DB Size |
+| ------------ | ---------------- | ----------------- | ----------------------- | ------------ | ------------------- | ------------------- | --------------------------- |
+| Nano (free) | $0 | $0 | Shared | Up to 0.5 GB | 60 | 200 | 500MB |
+| Micro | $0.01344 | ~$10 | 2-core ARM (shared) | 1 GB | 60 | 200 | 10GB |
+| Small | $0.0206 | ~$15 | 2-core ARM (shared) | 2 GB | 90 | 400 | 50GB |
+| Medium | $0.0822 | ~$60 | 2-core ARM (shared) | 4 GB | 120 | 600 | 100GB |
+| Large | $0.1517 | ~$110 | 2-core ARM (dedicated) | 8 GB | 160 | 800 | 200GB |
+| XL | $0.2877 | ~$210 | 4-core ARM (dedicated) | 16 GB | 240 | 1,000 | 500GB |
+| 2XL | $0.562 | ~$410 | 8-core ARM (dedicated) | 32 GB | 380 | 1,500 | 1TB |
+| 4XL | $1.32 | ~$960 | 16-core ARM (dedicated) | 64 GB | 480 | 3,000 | 2TB |
+| 8XL | $2.562 | ~$1,870 | 32-core ARM (dedicated) | 128 GB | 490 | 6,000 | 4TB |
+| 12XL | $3.836 | ~$2,800 | 48-core ARM (dedicated) | 192 GB | 500 | 9,000 | 6TB |
+| 16XL | $5.12 | ~$3,730 | 64-core ARM (dedicated) | 256 GB | 500 | 12,000 | 10TB |
Number of connections above are recommended values.
diff --git a/apps/docs/content/guides/platform/custom-domains.mdx b/apps/docs/content/guides/platform/custom-domains.mdx
index fd8c6ec2a63..6ba6190c154 100644
--- a/apps/docs/content/guides/platform/custom-domains.mdx
+++ b/apps/docs/content/guides/platform/custom-domains.mdx
@@ -157,7 +157,7 @@ To get started:
1. [Install](/docs/guides/resources/supabase-cli) the latest version of the Supabase CLI.
1. [Log in](/docs/guides/cli/local-development#log-in-to-the-supabase-cli) to your Supabase account using the CLI.
1. Ensure that you have [Owner or Admin permissions](/docs/guides/platform/access-control#manage-team-members) for the project you'd like to set up a vanity subdomain for.
-1. Ensure that your organization is on a paid plan (Pro/Team/Enterprise plan) in the [Billing page of the Dashboard](https://supabase.com/dashboard/org/_/billing).
+1. Ensure that your organization is on a paid plan (Pro/Team/Enterprise Plan) in the [Billing page of the Dashboard](https://supabase.com/dashboard/org/_/billing).
### Configure a vanity subdomain
diff --git a/apps/docs/content/guides/platform/custom-postgres-config.mdx b/apps/docs/content/guides/platform/custom-postgres-config.mdx
index f9b77862f3f..069cb841593 100644
--- a/apps/docs/content/guides/platform/custom-postgres-config.mdx
+++ b/apps/docs/content/guides/platform/custom-postgres-config.mdx
@@ -64,6 +64,17 @@ max_parallel_workers |3 |
- End of Custom Postgres Config -
```
+When configuring parameters that require time units, such as `statement_timeout`, the CLI expects a string value with a time unit. Supported units include `ms`, `s`, and `min`.
+
+```bash
+$ supabase --experimental --project-ref postgres-config update --config statement_timeout=1000ms
+
+- Custom Postgres Config -
+Config |Value |
+statement_timeout |1000ms |
+- End of Custom Postgres Config -
+```
+
## Considerations
1. The Postgres cluster will be restarted in order to change the configuration being used. This will cause momentary disruption to existing database connections; in most cases this should not take more than a few seconds.
diff --git a/apps/docs/content/guides/platform/database-size.mdx b/apps/docs/content/guides/platform/database-size.mdx
index af8594c6a6e..45903ba8f56 100644
--- a/apps/docs/content/guides/platform/database-size.mdx
+++ b/apps/docs/content/guides/platform/database-size.mdx
@@ -36,16 +36,16 @@ Depending on your billing plan, your database can go into read-only mode which c
Postgres does not immediately reclaim the physical space used by dead tuples (i.e., deleted rows) in the DB. They are marked as "removed" until a [vacuum operation](https://www.postgresql.org/docs/current/routine-vacuuming.html) is executed. As a result, deleting data from your database may not immediately reduce the reported disk usage. You can use the [Supabase CLI](https://supabase.com/docs/guides/cli/getting-started) `inspect db bloat` command to view all dead tuples in your database. Alternatively, you can run the [query](https://github.com/supabase/cli/blob/c9cce58025fded16b4c332747f819a44f45c3b83/internal/inspect/bloat/bloat.go#L17) found in the CLI's GitHub repo in the [SQL Editor](https://supabase.com/dashboard/project/_/sql/)
```bash
-# login to the CLI
+# Login to the CLI
npx supabase login
-# initlize a local supabase directory
+# Initialize a local supabase directory
npx supabase init
-# link a project
+# Link a project
npx supabase link
-# detect bloat
+# Detect bloat
npx supabase inspect db bloat --linked
```
@@ -57,7 +57,7 @@ vacuum full ;
-Vacuum operations can temporarily increase resource utilization, which may adversely impact the observed performance of your project until the maintenance is completed.
+Vacuum operations can temporarily increase resource utilization, which may adversely impact the observed performance of your project until the maintenance is completed. The [vacuum full](https://www.postgresql.org/docs/current/sql-vacuum.html) command will lock the table until the operation concludes.
@@ -75,7 +75,7 @@ Supabase uses network-attached storage to balance performance with scalability.
### Paid plan behavior
-Projects on the Pro plan and above have auto-scaling Disk Storage.
+Projects on the Pro Plan and above have auto-scaling Disk Storage.
Disk Storage expands automatically when the database reaches 90% of the disk size. The disk is expanded to be 50% larger (e.g., 8GB -> 12GB). Auto-scaling can only take place once every 6 hours. If within those 6 hours you reach 95% of the disk space, your project will enter read-only mode.
@@ -101,13 +101,13 @@ Disks don't automatically downsize during normal operation. They _will_ automati
-The maximum Disk Storage Size for the Pro plan is 16TB. If you need more than this, [contact us](https://forms.supabase.com/enterprise) to learn more about the Enterprise plan.
+The maximum Disk Storage Size for the Pro/Team Plan is 16TB. If you need more than this, [contact us](https://forms.supabase.com/enterprise) to learn more about the Enterprise Plan.
-### Free plan behavior
+### Free Plan behavior
Free Plan projects enter [read-only](#read-only-mode) mode when you exceed the 500MB limit. Once in read-only mode, you have several options:
-- [Upgrade to the Pro plan](https://supabase.com/dashboard/org/_/billing) to increase the limit to 8GB. [Disable the Spend Cap](https://app.supabase.com/org/_/billing?panel=costControl) if you want your Pro instance to auto-scale and expand beyond the 8GB database size limit.
+- [Upgrade to the Pro Plan](https://supabase.com/dashboard/org/_/billing) to increase the limit to 8GB. [Disable the Spend Cap](https://app.supabase.com/org/_/billing?panel=costControl) if you want your Pro instance to auto-scale and expand beyond the 8GB database size limit.
- [Disable read-only mode](#disabling-read-only-mode) and reduce your database size.
### Read-only mode
diff --git a/apps/docs/content/guides/platform/enterprise-billing.mdx b/apps/docs/content/guides/platform/enterprise-billing.mdx
index 4229af1d756..8967e335479 100644
--- a/apps/docs/content/guides/platform/enterprise-billing.mdx
+++ b/apps/docs/content/guides/platform/enterprise-billing.mdx
@@ -7,7 +7,7 @@ subtitle: 'Multiple organizations using a single subscription for Enterprise cus
Enterprise customers can use Account-based Billing to simplify billing for multiple organizations.
-This is for users considering or on Enterprise plan only.
+This is for users considering or on Enterprise Plan only.
## Account-based billing
@@ -21,6 +21,6 @@ With Account-based Billing, all organizations and projects within the subscripti
For the usage-billing, we’ll sum up the usage from all organizations and projects. You can still break down the usage per organization or per project by going to the [organization billing page](/dashboard/org/_/billing).
-## Upgrading to the Enterprise plan
+## Upgrading to the Enterprise Plan
Account-based Billing is not self-serve. Please reach out to your customer success contact person to set this up.
diff --git a/apps/docs/content/guides/platform/exhaust-cpu.mdx b/apps/docs/content/guides/platform/exhaust-cpu.mdx
index b17673d7cdd..b056ec150d2 100644
--- a/apps/docs/content/guides/platform/exhaust-cpu.mdx
+++ b/apps/docs/content/guides/platform/exhaust-cpu.mdx
@@ -32,7 +32,7 @@ Everything you do with your Supabase project requires compute. Hence, there can
- **Query performance:** Queries that take a long time to complete (>1 second) as well as excessive amounts of querying can put a strain on the CPU. Check our guide on [examining query performance](https://supabase.com/docs/guides/platform/performance#examining-query-performance).
- **Missing indexes:** Your database might have to scan through a large amount of data to find the information it needs. Creating indexes helps your database find data faster. Learn more about indexes [here](https://supabase.com/docs/guides/database/postgres/indexes).
-- **Unsuitable compute:** The instance size of your Supabase project might not be suitable for your application as you might have more traffic or run resource-intensive operations.
+- **Unsuitable compute:** The compute size of your Supabase project might not be suitable for your application as you might have more traffic or run resource-intensive operations.
## Solving high CPU usage
diff --git a/apps/docs/pages/guides/platform/exhaust-swap.mdx b/apps/docs/content/guides/platform/exhaust-swap.mdx
similarity index 89%
rename from apps/docs/pages/guides/platform/exhaust-swap.mdx
rename to apps/docs/content/guides/platform/exhaust-swap.mdx
index adfb7a7a5ea..247e9466d36 100644
--- a/apps/docs/pages/guides/platform/exhaust-swap.mdx
+++ b/apps/docs/content/guides/platform/exhaust-swap.mdx
@@ -1,11 +1,8 @@
-import Layout from '~/layouts/DefaultGuideLayout'
-
-export const meta = {
- id: 'exhaust-swap',
- title: 'High swap usage',
- description:
- 'Learn what high Swap usage could mean for your Supabase instance and what could have caused it.',
-}
+---
+id: 'exhaust-swap'
+title: 'High swap usage'
+description: 'Learn what high Swap usage could mean for your Supabase instance and what could have caused it.'
+---
Learn what high Swap usage means, what can cause it, and how to solve it.
@@ -54,7 +51,7 @@ Everything you do with your Supabase project requires compute. Hence, there can
- **Query performance:** You might have high read traffic or queries that process a large amount of data on disk (this can happen even if you are returning a small amount of data).
- **Missing indexes:** Your database might have to scan through a large amount of data to find the information it needs. Creating indexes helps your database find data faster. See the [indexes guide](https://supabase.com/docs/guides/database/postgres/indexes) to learn more.
-- **Unsuitable compute:** The instance size of your Supabase project might not be suitable for your application as you might have more traffic or run resource-intensive operations.
+- **Unsuitable compute:** The compute size of your Supabase project might not be suitable for your application as you might have more traffic or run resource-intensive operations.
- **Workload style:** The usage pattern of your Supabase project might be more read heavy, or involve large amounts of data.
- **Extensions:** You might be using extensions that perform intensive operations on large datasets. This increases resource usage.
@@ -65,7 +62,3 @@ If you find that your RAM and Swap usage are high, you have three options:
1. **Optimize performance:** Get more out of your instance's resources by optimizing your usage. See the [performance tuning guide](https://supabase.com/docs/guides/platform/performance#examining-query-performance) and our [production readiness guide](https://supabase.com/docs/guides/platform/going-into-prod#performance).
2. **Upgrade your compute:** You can get a Compute Add-on for your project. Navigate to [the **Addons** section in project settings](https://supabase.com/dashboard/project/_/settings/addons?panel=computeInstance) to see your upgrade options.
3. **Read Replicas:** You can spread the load on your Supabase project by creating a Read Replica. See [the read replicas guide](https://supabase.com/docs/guides/platform/read-replicas) for more information.
-
-export const Page = ({ children }) =>
-
-export default Page
diff --git a/apps/docs/content/guides/platform/fly-postgres.mdx b/apps/docs/content/guides/platform/fly-postgres.mdx
index 763ef0fbbb9..fceb1d8cf8e 100644
--- a/apps/docs/content/guides/platform/fly-postgres.mdx
+++ b/apps/docs/content/guides/platform/fly-postgres.mdx
@@ -56,7 +56,7 @@ Each Fly user is entitled to one free Fly Postgres database. To create additiona
Fly Postgres databases are priced exactly the same as projects launched via Supabase. For detailed pricing information, visit the [Supabase pricing page](https://supabase.com/pricing).
-The [usage page](https://supabase.com/dashboard/org/_/usage) details the usage of your Fly Postgres databases. The usage information is sent to Fly and the billing is added to your Fly invoice. Supabase adheres to the Fly billing cycles, which start on the 1st of every month. Any upgrades or downgrades in between are prorated and billed on the 1st of the next month. This can lead to delayed charges. For example, if you upgrade to the Pro plan in the middle of a month, you will be charged the pro-rated amount on the first of the next month.
+The [usage page](https://supabase.com/dashboard/org/_/usage) details the usage of your Fly Postgres databases. The usage information is sent to Fly and the billing is added to your Fly invoice. Supabase adheres to the Fly billing cycles, which start on the 1st of every month. Any upgrades or downgrades in between are prorated and billed on the 1st of the next month. This can lead to delayed charges. For example, if you upgrade to the Pro Plan in the middle of a month, you will be charged the pro-rated amount on the first of the next month.
## Limitations
diff --git a/apps/docs/content/guides/platform/going-into-prod.mdx b/apps/docs/content/guides/platform/going-into-prod.mdx
index a8a3320ac14..f55771245b1 100644
--- a/apps/docs/content/guides/platform/going-into-prod.mdx
+++ b/apps/docs/content/guides/platform/going-into-prod.mdx
@@ -20,7 +20,10 @@ After developing your project and deciding it's Production Ready, you should run
- Go to the Database > Publications page in the Supabase Dashboard to manage replication tables.
- Turn on [SSL Enforcement](/docs/guides/platform/ssl-enforcement)
- Enable [Network Restrictions](/docs/guides/platform/network-restrictions) for your database.
-- Enable 2FA on GitHub. Since your GitHub account gives you administrative rights to your Supabase project, you should protect it with a strong password and 2FA using a U2F key or a TOTP app.
+- Ensure that your Supabase Account is protected with multi-factor authentication (MFA).
+ - If using a GitHub signin, [enable 2FA on GitHub](https://docs.github.com/en/authentication/securing-your-account-with-two-factor-authentication-2fa/configuring-two-factor-authentication). Since your GitHub account gives you administrative rights to your Supabase org, you should protect it with a strong password and 2FA using a U2F key or a TOTP app.
+ - If using email+password signin, set up [MFA for your Supabase account](https://supabase.com/docs/guides/platform/multi-factor-authentication#enable-mfa).
+- Consider [adding multiple owners on your Supabase org](https://supabase.com/dashboard/org/_/team). This ensures that if one of the owners is unreachable or loses access to their account, you still have Owner access to your org.
- Ensure email confirmations are [enabled](https://supabase.com/dashboard/project/_/auth/providers) in the `Settings > Auth` page.
- Ensure that you've [set the expiry](https://supabase.com/dashboard/project/_/auth/providers) for one-time passwords (OTPs) to a reasonable value that you are comfortable with. We recommend setting this to 3600 seconds (1 hour) or lower.
- Increase the length of the OTP if you need a higher level of entropy.
@@ -28,6 +31,7 @@ After developing your project and deciding it's Production Ready, you should run
- Use a custom SMTP server for auth emails so that your users can see that the mails are coming from a trusted domain (preferably the same domain that your app is hosted on). Grab SMTP credentials from any major email provider such as SendGrid, AWS SES, etc.
- Think hard about how _you_ would abuse your service as an attacker, and mitigate.
- Review these [common cybersecurity threats](https://auth0.com/docs/security/prevent-threats).
+- Check and review issues in your database using [Security Advisor](https://supabase.com/dashboard/project/_/database/security-advisor).
## Performance
@@ -37,27 +41,28 @@ After developing your project and deciding it's Production Ready, you should run
- Perform load testing (preferably on a staging env)
- Tools like [k6](https://k6.io/) can simulate traffic from many different users.
- Upgrade your database if you require more resources. If you need anything beyond what is listed, contact enterprise@supabase.io.
-- If you are expecting a surge in traffic (for a big launch) and are on a teams or enterprise plan, [contact support](https://supabase.com/dashboard/support/new) with more details about your launch and we'll help keep an eye on your project.
+- If you are expecting a surge in traffic (for a big launch) and are on a Team or Enterprise Plan, [contact support](https://supabase.com/dashboard/support/new) with more details about your launch and we'll help keep an eye on your project.
- If you expect your database size to be > 4 GB, [enable](https://supabase.com/dashboard/project/_/settings/addons?panel=pitr) the Point in Time Recovery (PITR) addon. Daily backups can take up resources from your database when the backup is in progress. PITR is more resource efficient, since only the changes to the database are backed up.
+- Check and review issues in your database using [Performance Advisor](https://supabase.com/dashboard/project/_/database/performance-advisor).
## Availability
- Use your own SMTP credentials so that you have full control over the deliverability of your transactional auth emails (see Settings > Auth)
- you can grab SMTP credentials from any major email provider such as SendGrid, AWS SES, etc. You can refer to our [SMTP guide](/docs/guides/auth/auth-smtp) for more details.
- The default rate limit for auth emails when using a custom SMTP provider is 30 new users per hour, if doing a major public announcement you will likely require more than this.
-- If your application is on the free plan and is **not** expected to be queried at least once every 7 days, then it may be paused by Supabase to save on server resources.
+- If your application is on the Free Plan and is **not** expected to be queried at least once every 7 days, then it may be paused by Supabase to save on server resources.
- You can restore paused projects from the Supabase dashboard.
- Upgrade to Pro to guarantee that your project will not be paused for inactivity.
-- Database backups are not available for download on the free plan.
+- Database backups are not available for download on the Free Plan.
- You can set up your own backup systems using tools like [pg_dump](https://www.postgresqltutorial.com/postgresql-backup-database/) or [wal-g](https://github.com/wal-g/wal-g).
- - Nightly backups for Pro plan projects are available on the Supabase dashboard for up to 7 days.
+ - Nightly backups for Pro Plan projects are available on the Supabase dashboard for up to 7 days.
- Point in Time Recovery (PITR) allows a project to be backed up at much shorter intervals. This provides users an option to restore to any chosen point of up to seconds in granularity. In terms of Recovery Point Objective (RPO), Daily Backups would be suitable for projects willing to lose up to 24 hours worth of data. If a lower RPO is required, enable PITR.
-- Upgrading to the Supabase Pro plan will give you [access to our support team](https://supabase.com/dashboard/support/new).
+- Upgrading to the Supabase Pro Plan will give you [access to our support team](https://supabase.com/dashboard/support/new).
## Rate limiting, resource allocation, & abuse prevention
- Supabase employs a number of safeguards against bursts of incoming traffic to prevent abuse and help maximize stability across the platform
- - If you're expecting high load events including production launches or heavy load testing, or prolonged high resource usage please give us at least 2 weeks notice. You can do this by opening a ticket via the [support form](https://supabase.com/dashboard/support/new).
+ - If you're on a Team or Enterprise Plan and expect high load events, such as production launches, heavy load testing, or prolonged high resource usage, open a ticket via the [support form](https://supabase.help) for help. Provide at least 2 weeks notice.
### Auth rate limits
diff --git a/apps/docs/content/guides/platform/http-status-codes.mdx b/apps/docs/content/guides/platform/http-status-codes.mdx
index fb560070b7c..5dcfec6e635 100644
--- a/apps/docs/content/guides/platform/http-status-codes.mdx
+++ b/apps/docs/content/guides/platform/http-status-codes.mdx
@@ -18,6 +18,17 @@ The Supabase platform offers several HTTP APIs for each project. These APIs can
4XX status codes indicate an issue on the client's end with the request being made. These could include missing or invalid auth information, a malformed request, making too many requests in too short a time period ("rate limiting"), or a network issue on the client's end.
+### 402 service restriction
+
+In case the Fair Use Policy is applied, the projects of your organization may be restricted from processing requests. If service restrictions are applied, projects will return a 402 status code together with a description of why the project is restricted. The description can contain one or more of the following codes:
+
+- `exceeded_*` indicates that the project has continued to exceeded the usage limits of its quota, e.g. `exceed_egress_quota`, `exceed_db_size_quota`.
+- `overdue_payment` indicates that the organization has overdue bills.
+
+You will still have access to your data through the Supabase dashboard when the Fair Use Policy is applied.
+
+See the [Fair Use Policy](/docs/guides/platform/billing-faq#fair-use-policy) section to learn more about the restrictions and how to remove them.
+
## 5XX server or project errors
5XX status codes indicate that the project was unable to process the request successfully, but not because of an issue with the client's request.
@@ -32,7 +43,7 @@ The Supabase platform offers several HTTP APIs for each project. These APIs can
The project the request was being made against has been paused. The project cannot process requests until it is un-paused by the owner.
-Free-plan projects may be paused due to inactivity, on request by the owner, or in rare instances, due to abuse.
+Free Plan projects may be paused due to inactivity, on request by the owner, or in rare instances, due to abuse.
#### 544 project API gateway timeout
diff --git a/apps/docs/content/guides/platform/log-drains.mdx b/apps/docs/content/guides/platform/log-drains.mdx
new file mode 100644
index 00000000000..92e6272bf3a
--- /dev/null
+++ b/apps/docs/content/guides/platform/log-drains.mdx
@@ -0,0 +1,49 @@
+---
+id: 'log-drains'
+title: 'Log Drains'
+description: 'Getting started with Supabase Log Drains'
+---
+
+Log drains will send all logs of the Supabase stack to one or more desired destinations. It is only available for customers on Team and Enterprise Plans.
+
+
+
+Log drains is in **Private Alpha**, and is not available in the dashboard yet. [Reach out to us](https://forms.supabase.com/logdrains) to get log drains enabled for your project.
+
+You can read about the initial announcement [here](https://github.com/orgs/supabase/discussions/26650).
+
+
+
+The following table lists the supported destinations and the required setup configuration:
+
+| Destination | Transport Method | Configuration |
+| ------------------ | ---------------- | ------------------------------------------------- |
+| Generic Webhook | HTTP | URL HTTP Version Gzip Headers |
+| Datadog | HTTP | API Key Region |
+| Elastic - Filebeat | HTTP | URL Username and Password |
+
+### Destinations And Behavior
+
+HTTP requests will be batched with a max of 250 items with at most 1 second intervals. Gzip compression will also be used if the 3rd party provider supports it.
+
+#### Generic Webhook
+
+Logs will be sent as a JSON payload. Both HTTP1 and HTTP2 are supported. A preset configuration of Headers can be supplied for all requests.
+
+Note that requests will be **unsigned**.
+
+:::note
+Unsigned webhook requests are temporary and all requests will be signed in the near future.
+:::
+
+#### Datadog
+
+Logs sent to Datadog will have the name of the log source set on the `service` field of the event.
+
+The payload message will be a stringified JSON of the raw log event, prefixed with the event timestamp.
+
+#### Elastic - Filebeat
+
+Logs will be sent to Filebeat server. See the [Filebeat documentation](https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-input-http_endpoint.html) on how to set up the Filebeat HTTP server.
+
+The Filebeat server only handles HTTP1 requests. Basic Auth can be provided for optional user authentication.
diff --git a/apps/docs/content/guides/platform/logs.mdx b/apps/docs/content/guides/platform/logs.mdx
index de7b42234f4..5b9184ffc6b 100644
--- a/apps/docs/content/guides/platform/logs.mdx
+++ b/apps/docs/content/guides/platform/logs.mdx
@@ -285,7 +285,7 @@ from
where h.x_real_ip is not null and r.method = "GET";
```
-### Log source reference
+### Logs field reference
Refer to the full field reference for each available source below. Do note that in order to access each nested key, you would need to perform the [necessary unnesting joins](#unnesting-arrays)
@@ -293,11 +293,13 @@ Refer to the full field reference for each available source below. Do note that
{(logConstants) => (
{logConstants.schemas.map((schema) => (
-
+
- Path
- Type
+
+ Path
+ Type
+
{schema.fields
diff --git a/apps/docs/content/guides/platform/metrics.mdx b/apps/docs/content/guides/platform/metrics.mdx
index dece498959f..f9d83c6ff08 100644
--- a/apps/docs/content/guides/platform/metrics.mdx
+++ b/apps/docs/content/guides/platform/metrics.mdx
@@ -28,4 +28,24 @@ Your project's metrics endpoint is accessible at `https://.supabase
> curl https://.supabase.co/customer/v1/privileged/metrics --user 'service_role:'
```
+## Configuring Prometheus
+
+For self-hosted prometheus, modify your `prometheus.yaml` file to add a Supabase job, and set the `metrics_path`, `scheme`, `basic_auth` and `targets` parameters. For example:
+
+```yaml
+scrape_configs:
+ - job_name: "MyJob"
+ metrics_path: "/customer/v1/privileged/metrics"
+ scheme: https
+ basic_auth:
+ username: "service_role"
+ password: ""
+ static_configs:
+ - targets: [
+ ".supabase.co:443"
+ ]
+ labels:
+ group: "MyGroupLabel"
+```
+
Additionally, we [maintain a guide](https://github.com/supabase/supabase-grafana) on quickly setting up a scraping agent to work with Grafana Cloud.
diff --git a/apps/docs/content/guides/platform/migrating-and-upgrading-projects.mdx b/apps/docs/content/guides/platform/migrating-and-upgrading-projects.mdx
index 429a1f43dad..bbeee6fda3b 100644
--- a/apps/docs/content/guides/platform/migrating-and-upgrading-projects.mdx
+++ b/apps/docs/content/guides/platform/migrating-and-upgrading-projects.mdx
@@ -65,36 +65,33 @@ If you are upgrading from a significantly older version, you will need to consid
#### Time Limits
-Starting from 2024-06-13, when a project is paused, users then have a 90-day window to restore the project on the platform from within Supabase Studio.
+Starting from 2024-06-24, when a project is paused, users then have a 90-day window to restore the project on the platform from within Supabase Studio.
The 90-day window allows Supabase to introduce platform changes that may not be backwards compatible with older backups. Unlike active projects, static backups can't be updated to accommodate such changes.
During the 90-day restore window a paused project can be restored to the platform with a single button click from [Studio's dashboard page](https://supabase.com/dashboard/projects).
-
-
-
+
After the 90-day restore window, you can download your project's backup file from the project dashboard. This backup is compatible with [pg_restore](https://www.postgresql.org/docs/current/app-pgrestore.html). You can extract your data from it, or attempt to manually restore the project.
-
-
-
+
If you upgrade to a paid plan while your project is paused, any expired one-click restore options are reenabled. Since the backup was taken outside the backwards compatibility window, it may fail to restore. If you have a problem restoring your backup after upgrading, contact [Support](/support).
-
-
-
+
#### Disk sizing
diff --git a/apps/docs/content/guides/platform/org-based-billing.mdx b/apps/docs/content/guides/platform/org-based-billing.mdx
index b001ea8620e..5a2e65f20a3 100644
--- a/apps/docs/content/guides/platform/org-based-billing.mdx
+++ b/apps/docs/content/guides/platform/org-based-billing.mdx
@@ -23,7 +23,7 @@ The Supabase Platform has "organizations" and "projects". An organization may co
- `Organization 2`
- `Project 3` (Database, Auth, Storage, Functions, Realtime)
-Each organization only has a single subscription with a single plan (Free, Pro, Team or Enterprise). Project addons such as [Compute](/docs/guides/platform/compute-add-ons), [Custom Domains](/docs/guides/platform/custom-domains) and [PITR](/docs/guides/platform/backups#point-in-time-recovery) are still configured per project and are added to your organization subscription.
+Each organization only has a single subscription with a single Plan (Free, Pro, Team or Enterprise). Project addons such as [Compute](/docs/guides/platform/compute-add-ons), [Custom Domains](/docs/guides/platform/custom-domains) and [PITR](/docs/guides/platform/backups#point-in-time-recovery) are still configured per project and are added to your organization subscription.

@@ -33,6 +33,8 @@ Quotas and features are applied to your entire organization, independent of how
Upgrading your organization to a paid plan means that you unlock the benefits of the paid plan for **all** projects within that organization - for example, no projects in your "Pro" organization will be paused. See [pricing page](https://supabase.com/pricing) for details on all plans.
+It is not possible to mix different plans inside a single organization. You cannot have one Pro Plan project and one Free Plan project inside a single organization. To have projects on different plans, you'll need to create different organizations. Also see [Project Transfers](/docs/guides/platform/project-transfer) in case you're looking to transfer a project to a different organization.
+
### Usage items
| Metric | Free | Pro/Team | Enterprise |
@@ -42,14 +44,14 @@ Upgrading your organization to a paid plan means that you unlock the benefits of
| Storage Size | 1GB | 100GB included, then $0.021 per GB | Custom |
| Monthly Active Users | 50,000 MAU | 100,000 MAU included, then $0.00325 per MAU | Custom |
| Function Invocations | 500K | 2 million included, then $2 per million | Custom |
-| Function Count | 10 | 100 included, then $10 per 100 | Custom |
-| Storage Images Transformed | Unavailable on Free plan | 100 included, then $5 per 1000 | Custom |
+| Function Count | 25 | 500/1000 | Unlimited |
+| Storage Images Transformed | Unavailable on Free Plan | 100 included, then $5 per 1000 | Custom |
| Realtime Message Count | 2 million | 5 million included, then $2.5 per million | Custom |
| Realtime Peak Connections | 200 | 500 included, then $10 per 1000 | Custom |
## Usage-based billing for compute
-We provide a dedicated server for every Supabase project. By default, your instance runs on the Micro Compute instance. You can upgrade your compute size in your [project settings](https://supabase.com/dashboard/project/_/settings/addons).
+Supabase provides a dedicated server and database for every project. By default, your instance runs on the Micro Compute instance. You can upgrade your compute size in your [project settings](https://supabase.com/dashboard/project/_/settings/addons).
You won't get an immediate charge upfront when changing compute, instead we'll bill you based on compute runtime hours when your billing cycle resets.
@@ -63,22 +65,24 @@ We only count compute hours for instances that are active. Paused projects do no
### Compute pricing
-| Instance Size | Hourly Price | Estimated Monthly Price |
-| ------------- | ------------ | ----------------------- |
-| Micro | $0.01344 | ~$10 |
-| Small | $0.0206 | ~$15 |
-| Medium | $0.0822 | ~$60 |
-| Large | $0.1517 | ~$110 |
-| XL | $0.2877 | ~$210 |
-| 2XL | $0.562 | ~$410 |
-| 4XL | $1.32 | ~$960 |
-| 8XL | $2.562 | ~$1870 |
-| 12XL | $3.836 | ~$2800 |
-| 16XL | $5.12 | ~$3730 |
+| Compute Size | Hourly Price | Estimated Monthly Price |
+| ------------ | ------------ | ----------------------- |
+| Micro | $0.01344 | ~$10 |
+| Small | $0.0206 | ~$15 |
+| Medium | $0.0822 | ~$60 |
+| Large | $0.1517 | ~$110 |
+| XL | $0.2877 | ~$210 |
+| 2XL | $0.562 | ~$410 |
+| 4XL | $1.32 | ~$960 |
+| 8XL | $2.562 | ~$1870 |
+| 12XL | $3.836 | ~$2800 |
+| 16XL | $5.12 | ~$3730 |
-### Free plan
+### Free Plan
-Supabase provides two "Free organizations". Each organization can run a `Nano` instance for free. This is a great way to get started with Supabase and try out the platform.
+Supabase provides two "Free projects". Each project can run a `Nano` instance for free. This is a great way to get started with Supabase and try out the platform.
+
+We count your total limit of 2 free projects across all organizations you're either an Owner or Administrator of. You could have two Free Plan organizations with one project each, or one Free Plan organization with two projects. Paused projects do not count towards your free project limit.
### Compute credits
@@ -94,13 +98,13 @@ Additionally, Compute Credits are given to you not only for the first month but
In case of deploying additional [Read Replicas](/docs/guides/platform/read-replicas), each replica is a dedicated database that adds additional compute runtime hours.
-Each replica incurs one compute hour on the given instance size. An example:
+Each replica incurs one compute hour on the given compute size. An example:
A primary database on XL compute and two read replicas on XL compute would incur ~2.190 XL compute hours (3x 730h) and cost ~$630/month.
## Unified egress
-Each organization receives a total egress quota (eg. 250GB on the Pro plan) which can be used for anything - Storage, Realtime, Auth, Functions, Supavisor or Database.
+Each organization receives a total egress quota (eg. 250GB on the Pro Plan) which can be used for anything - Storage, Realtime, Auth, Functions, Supavisor or Database.
### Included egress quota
@@ -131,27 +135,29 @@ You can see a breakdown of the different types of egress on your [organization u
Here are some examples on how the Billing affects you.
-### Multiple free plan projects
+### Multiple Free Plan projects
-Here are the quotas for the free plan:
+Here are the quotas for the Free Plan:
-| Usage Item | Free plan |
-| ------------------------- | --------------------------------------- |
-| Egress | 5GB across Database + Storage |
-| Database Space | 500MB |
-| Storage Space | 1GB |
-| Monthly Active Users | 50,000 MAU |
-| Edge Function Invocations | 500K |
-| Edge Function Count | 10 |
-| Realtime Message Count | 2 million |
-| Realtime Peak Connections | 200 |
-| | Max of 2 free orgs - 1 database per org |
+| Usage Item | Free Plan |
+| ------------------------- | ----------------------------- |
+| Egress | 5GB across Database + Storage |
+| Database Space | 500MB |
+| Storage Space | 1GB |
+| Monthly Active Users | 50,000 MAU |
+| Edge Function Invocations | 500K |
+| Edge Function Count | 25 |
+| Realtime Message Count | 2 million |
+| Realtime Peak Connections | 200 |
+| Max of 2 free projects\* |
-While we allow you to launch a total of two free projects, the quota applies to the entire organization, i.e. you can have a total of 4GB of database space.
+The quota applies to the entire organization, i.e. you can have a total of 5GB egress (sum of all projects egress combined).
-### Multiple pro plan projects
+\* All active projects in Free Plan organizations where you're either an Owner or Administrator count towards your total limit of 2 free projects. Paused projects do not count towards your limit.
-While you only pay for the $25 Pro plan once, launching additional projects at least incurs compute costs.
+### Multiple Pro Plan projects
+
+While you only pay for the $25 Pro Plan once, launching additional projects at least incurs compute costs.
**Invoice Breakdown**
@@ -171,11 +177,11 @@ Here's the quota for your entire organization:
| Storage Size | 100GB included, then $0.021 per GB |
| Monthly Active Users | 100K MAU included, then $0.00325 per MAU |
| Function Invocations | 2 million included, then $2 per million |
-| Function Count | 100 included, then $10 per 100 |
+| Function Count | 500 included |
| Storage Images Transformed | 100 included, then $5 per 1000 |
| Realtime Message Count | 5 million included, then $2.5 per million |
| Realtime Peak Connections | 500 included, then $10 per 1000 |
-If you wish to keep the same quota for each project, you can separate your projects into three organizations on the Pro plan each. You'd end up paying $25 for each project, so $75 instead of $45 in total, while getting more quota.
+If you wish to keep the same quota for each project, you can separate your projects into three organizations on the Pro Plan each. You'd end up paying $25 for each project, so $75 instead of $45 in total, while getting more quota.
See [Project Transfers](/docs/guides/platform/project-transfer) to move projects across organizations.
diff --git a/apps/docs/content/guides/platform/project-transfer.mdx b/apps/docs/content/guides/platform/project-transfer.mdx
index 5ac8c0d3425..72640479974 100644
--- a/apps/docs/content/guides/platform/project-transfer.mdx
+++ b/apps/docs/content/guides/platform/project-transfer.mdx
@@ -6,25 +6,25 @@ description: 'Transfer a project to another organization.'
With the introduction of [Organization-based Billing](/docs/guides/platform/org-based-billing), we’re adding the ability to freely transfer projects between different organizations. Head to your [projects' general settings](https://supabase.com/dashboard/project/_/settings/general) to initiate a project transfer.
-
-
-
+
-
-
-
+
Source organization - the organization the project currently belongs to
Target organization - the organization you want to move the project to
@@ -51,9 +51,9 @@ Similarly, for other usage metrics such as database size, egress, image transfor
## Things to watch out for
-- Transferring a project might come with a short 1-2 minute downtime if you're moving a project from a paid to a free plan.
-- You could lose access to certain project features depending on the plan of the target organization, i.e. moving a project from a Pro plan to a Free plan.
-- When moving your project to a Free plan, we also ensure you’re not exceeding your two free project limit. In these cases, it is best to upgrade your target organization to Pro plan first.
+- Transferring a project might come with a short 1-2 minute downtime if you're moving a project from a paid to a Free Plan.
+- You could lose access to certain project features depending on the plan of the target organization, i.e. moving a project from a Pro Plan to a Free Plan.
+- When moving your project to a Free Plan, we also ensure you’re not exceeding your two free project limit. In these cases, it is best to upgrade your target organization to Pro Plan first.
- You could have less rights on the project depending on your role in the target organization, i.e. you were an Owner in the previous organization and only have a Read-Only role in the target organization.
## Transfer to a different region
diff --git a/apps/docs/content/guides/platform/read-replicas.mdx b/apps/docs/content/guides/platform/read-replicas.mdx
index 882892700d6..e3c53a54a89 100644
--- a/apps/docs/content/guides/platform/read-replicas.mdx
+++ b/apps/docs/content/guides/platform/read-replicas.mdx
@@ -10,21 +10,12 @@ Read Replicas are additional databases that are kept in sync with your Primary d
- **Improved latency:** For projects with a global user base, additional databases can be deployed closer to users to reduce latency.
- **Redundancy:** Read Replicas provide data redundancy.
-
-
-
-
-
-
-
+
## About Read Replicas
@@ -84,14 +75,6 @@ Read Replicas offer the following features:
### Dedicated endpoints
-
-
-For Read Replicas deployed before May 24, 2024, there is a known bug that results in the [PostgREST schema cache](https://postgrest.org/en/v12/references/schema_cache.html) on Read Replicas not being reloaded correctly on DDL changes. A stale schema cache can result in PostgREST on Read Replicas not knowing about newly created functions, tables, changes to their structure, etc.
-
-A fix for this issue has already been deployed for newer Read Replicas but not fully applied for older ones as it requires a restart of the API service. You can perform a one-time restart of the service by [saving any trivial configuration change](https://supabase.com/dashboard/project/_/settings/api) to your PostgREST configuration (For example, changing the `Max Rows` by 1), which will result in the service being restarted.
-
-
-
Each Read Replica has its own dedicated database and API endpoints.
- Find the database endpoint on the [Database Settings page](/dashboard/project/_/settings/database) under **Connection Info**
@@ -127,21 +110,12 @@ If you use a [custom domain](/docs/guides/platform/custom-domains), requests wil
In the SQL editor, you can choose if you want to run the query on a particular Read Replica.
-
-
-
-
-
-
-
+
### Logging
@@ -195,13 +169,13 @@ In this replication method, the Primary continuously buffers WAL changes to a lo
### File-based log shipping 🤝 streaming replication
-
-
- Map view of Primary and Read Replica databases
-
+
We bring these two methods together to achieve quick, stable, and reliable replication. Each method addresses the limitations of the other. Streaming replication minimizes replication lag, while file-based log shipping provides a fallback. For file-based log shipping, we use our existing Point In Time Recovery (PITR) infrastructure. We regularly archive files from the Primary using [WAL-G](https://github.com/wal-g/wal-g), an open source archival and restoration tool, and ship the WAL files to S3.
diff --git a/apps/docs/content/guides/platform/regions.mdx b/apps/docs/content/guides/platform/regions.mdx
new file mode 100644
index 00000000000..99258244d14
--- /dev/null
+++ b/apps/docs/content/guides/platform/regions.mdx
@@ -0,0 +1,14 @@
+---
+title: Available regions
+subtitle: Spin up Supabase projects in our global regions
+---
+
+The following regions are available for your Supabase projects.
+
+## AWS
+
+
+
+## Fly
+
+Our [Fly Postgres](/docs/guides/platform/fly-postgres) offering (in private alpha) is supported in every region where Fly operates.
diff --git a/apps/docs/content/guides/platform/shared-responsibility-model.mdx b/apps/docs/content/guides/platform/shared-responsibility-model.mdx
index 27ff9b2cc08..98e19ad0f5f 100644
--- a/apps/docs/content/guides/platform/shared-responsibility-model.mdx
+++ b/apps/docs/content/guides/platform/shared-responsibility-model.mdx
@@ -6,6 +6,22 @@ description: 'Running databases is a shared responsibility between you and Supab
Running databases is a shared responsibility between you and Supabase. There are some things that we can take care of for you, and some things that you are responsible for. This is by design: we want to give you the freedom to use your database however you want. While we _could_ put many more restrictions in place to ensure that you can’t do anything wrong, you will eventually find those restrictions prohibitive.
+
+
+To summarize, you are always responsible for:
+
+- Your Supabase account
+- Access management (Supabase account, database, tables, etc)
+- Data
+- Applying security controls
+
Generally, we aim to reduce your burden of managing infrastructure and knowing about Postgres internals, minimizing configuration as much as we can. Here are a few things that you should know:
## You share the security responsibility
@@ -16,6 +32,10 @@ If you have an inexperienced member on your team, then you probably shouldn’t
You are also responsible for ensuring that tables with sensitive data have the right level of access. You are also responsible for managing your database secrets and API keys, storing them safely in an encrypted store.
+Supabase provides controls for [securing your data](/docs/guides/database/secure-data), and it is recommended that you always apply [Row Level Security](/docs/guides/database/postgres/row-level-security) (RLS).
+
+We will also provide you with security alerts through [Security Advisor](https://supabase.com/dashboard/project/_/database/security-advisor) and applying the recommendations are your responsibility.
+
## You decide your own workflow
There are _many_ ways to work with Supabase.
@@ -44,15 +64,22 @@ You are responsible for using best-practices to optimize and manage your databas
You are responsible of provisioning enough compute to run the workload that your application requires. The Supabase Dashboard provides [observability tooling](https://supabase.com/dashboard/project/_/reports/database) to help with this.
+## Before going to production
+
+We recommend reviewing and applying the recommendations offered in our [Production Checklist](/docs/guides/platform/going-into-prod). This checklist covers the responsibilities discussed here and a few additional general production readiness best practices.
+
## Managing healthcare data
You can use Supabase to store and process Protected Health Information (PHI). You are responsible for the following
-- Signing a Business Associate Agreement (BAA) with Supabase. Submit a [HIPAA add-on request](https://forms.supabase.com/hipaa2) to get started. You will need to be at least on the [Team plan](https://supabase.com/pricing) to sign a BAA with us.
+- Signing a Business Associate Agreement (BAA) with Supabase. Submit a [HIPAA add-on request](https://forms.supabase.com/hipaa2) to get started. You will need to be at least on the [Team Plan](https://supabase.com/pricing) to sign a BAA with us.
+- Ensuring [MFA is enabled](/docs/guides/platform/multi-factor-authentication) on all Supabase accounts.
- Enabling [Point in Time Recovery](/docs/guides/platform/backups#point-in-time-recovery) which requires at least a [small compute add-on](/docs/guides/platform/compute-add-ons).
- Turning on [SSL Enforcement](/docs/guides/platform/ssl-enforcement).
- Enabling [Network Restrictions](/docs/guides/platform/network-restrictions).
- Disabling [Supabase AI editor](https://supabase.com/dashboard/org/_/general) in our dashboard.
- Complying with encryption requirements in the HIPAA Security Rule. Data is encrypted at rest and in transit by Supabase. You can consider encrypting the data at your application layer.
- Not using [Edge functions](/docs/guides/functions) or [Fly Postgres](/docs/guides/platform/fly-postgres) to process PHI.
+- Not using [branching](/docs/guides/platform/branching) to process PHI.
- Not storing PHI in [public Storage buckets](/docs/guides/storage/buckets/fundamentals#public-buckets).
+- Not [transferring projects](/docs/guides/platform/project-transfer) to a non-HIPAA organization.
diff --git a/apps/docs/content/guides/platform/spend-cap.mdx b/apps/docs/content/guides/platform/spend-cap.mdx
index 359e4135e2b..f0b3861ceeb 100644
--- a/apps/docs/content/guides/platform/spend-cap.mdx
+++ b/apps/docs/content/guides/platform/spend-cap.mdx
@@ -19,7 +19,6 @@ Supabase charges for certain usage line items in your organization. Those line i
- Realtime concurrent peak connections
- Realtime messages
- Edge function invocations
-- Number of Edge functions
You can view the pricing, and free quota allowance of each line item on the [pricing page](/pricing).
@@ -28,7 +27,7 @@ This will show you how much you have spent so far in the current billing cycle,
## Can I use the spend cap to limit my compute costs?
-The spend cap does not apply to compute usage. Each project is a dedicated server and database and incurs compute costs depending on the selected instance size. Costs for compute are predictable, as the maximum amount is number of hours in month \* hourly compute price (per project).
+The spend cap does not apply to compute usage. Each project is a dedicated server and database and incurs compute costs depending on the selected compute size. Costs for compute are predictable, as the maximum amount is number of hours in month \* hourly compute price (per project).
Launching additional projects on a paid plan incurs compute costs, even if your spend cap is toggled on.
diff --git a/apps/docs/content/guides/platform/ssl-enforcement.mdx b/apps/docs/content/guides/platform/ssl-enforcement.mdx
index f104c6dfe7a..6512f254bfd 100644
--- a/apps/docs/content/guides/platform/ssl-enforcement.mdx
+++ b/apps/docs/content/guides/platform/ssl-enforcement.mdx
@@ -3,17 +3,17 @@ title: 'Postgres SSL Enforcement'
description: 'Enforce SSL usage for all Postgres connections'
---
+Your Supabase project supports connecting to the Postgres DB without SSL enabled to maximize client compatibility. For increased security, you can prevent clients from connecting if they're not using SSL.
+
+Disabling SSL enforcement only applies to connections to Postgres and Supavisor ("Connection Pooler"); all HTTP APIs offered by Supabase (e.g., PostgREST, Storage, Auth) automatically enforce SSL on all incoming connections.
+
-Postgres SSL Enforcement is currently in beta. Projects need to be at least on Postgres 13.3.0 to enable SSL enforcement. You can find the Postgres version of your project in the [Infrastructure Settings page](https://supabase.com/dashboard/project/_/settings/infrastructure). If your project is on an older version, you will need to
+Projects need to be at least on Postgres 13.3.0 to enable SSL enforcement. You can find the Postgres version of your project in the [Infrastructure Settings page](https://supabase.com/dashboard/project/_/settings/infrastructure). If your project is on an older version, you will need to
[upgrade](/docs/guides/platform/migrating-and-upgrading-projects#upgrade-your-project) to use this feature.
-Your Supabase project supports connecting to the Postgres DB without SSL enabled to maximize client compatibility. For increased security, you can prevent clients from connecting if they're not using SSL.
-
-SSL enforcement only applies to connections to both Postgres and Supavisor ("Connection Pooler"); all HTTP APIs offered by Supabase (e.g., PostgREST, Storage, Auth) automatically enforce SSL on all incoming connections.
-
## Manage SSL enforcement via the dashboard
SSL enforcement can be configured via the "Enforce SSL on incoming connections" setting under the SSL Configuration section in [Database Settings page](https://supabase.com/dashboard/project/_/settings/database) of the dashboard.
@@ -57,3 +57,21 @@ Similarly, to disable SSL enforcement:
> supabase ssl-enforcement --project-ref {ref} update --disable-db-ssl-enforcement --experimental
SSL is *NOT* being enforced.
```
+
+### A note about Postgres SSL modes
+
+Postgres supports [multiple SSL modes](https://www.postgresql.org/docs/current/libpq-ssl.html#LIBPQ-SSL-PROTECTION) on the client side. These modes provide different levels of protection. Depending on your needs, it is important to verify that the SSL mode in use is performing the required level of enforcement and verification of SSL connections.
+
+The strongest mode offered by Postgres is `verify-full` and this is the mode you most likely want to use when SSL enforcement is enabled. To use `verify-full` you will need to download the Supabase CA certificate for your database. The certificate is available through the dashboard under the SSL Configuration section in the [Database Settings page](/dashboard/project/_/settings/database).
+
+Once the CA certificate has been downloaded, add it to the certificate authority list used by Postgres.
+
+```bash
+> cat {location of downloaded prod-ca-2021.crt} >> ~/.postgres/root.crt
+```
+
+With the CA certificate added to the trusted certificate authorities list, use `psql` or your client library to connect to Supabase:
+
+```bash
+> psql "postgresql://aws-0-eu-central-1.pooler.supabase.com:6543/postgres?sslmode=verify-full" -U postgres.
+```
diff --git a/apps/docs/content/guides/platform/sso/azure.mdx b/apps/docs/content/guides/platform/sso/azure.mdx
index 9e48e47b4fe..6424bc746d7 100644
--- a/apps/docs/content/guides/platform/sso/azure.mdx
+++ b/apps/docs/content/guides/platform/sso/azure.mdx
@@ -5,7 +5,13 @@ description: 'Configure single sign-on with Azure AD (Microsoft Entra).'
-This feature is only available on the Teams and Enterprise tiers. Please contact [Sales](https://forms.supabase.com/enterprise) before doing these steps.
+This feature is only available on the Team and Enterprise Plans. Please contact [Sales](https://forms.supabase.com/enterprise) before doing these steps.
+
+
+
+
+
+Looking for docs on how to add Single Sign-On support in your Supabase project? Head on over to [Single Sign-On with SAML 2.0 for Projects](/docs/guides/auth/enterprise-sso/auth-sso-saml).
diff --git a/apps/docs/content/guides/platform/sso/gsuite.mdx b/apps/docs/content/guides/platform/sso/gsuite.mdx
index a7a7fa432b1..e34ea113337 100644
--- a/apps/docs/content/guides/platform/sso/gsuite.mdx
+++ b/apps/docs/content/guides/platform/sso/gsuite.mdx
@@ -5,7 +5,13 @@ description: 'Configure single sign-on with Google Workspace (GSuite).'
-This feature is only available on the Teams and Enterprise tiers. Please contact [Sales](https://forms.supabase.com/enterprise) before doing these steps.
+This feature is only available on the Team and Enterprise Plans. Please contact [Sales](https://forms.supabase.com/enterprise) before doing these steps.
+
+
+
+
+
+Looking for docs on how to add Single Sign-On support in your Supabase project? Head on over to [Single Sign-On with SAML 2.0 for Projects](/docs/guides/auth/enterprise-sso/auth-sso-saml).
diff --git a/apps/docs/content/guides/platform/sso/okta.mdx b/apps/docs/content/guides/platform/sso/okta.mdx
index 6134401cd67..3d39f4c1432 100644
--- a/apps/docs/content/guides/platform/sso/okta.mdx
+++ b/apps/docs/content/guides/platform/sso/okta.mdx
@@ -5,7 +5,13 @@ description: 'Configure single sign-on with Okta.'
-This feature is only available on the Teams and Enterprise tiers. Please contact [Sales](https://forms.supabase.com/enterprise) before doing these steps.
+This feature is only available on the Team and Enterprise Plans. Please contact [Sales](https://forms.supabase.com/enterprise) before doing these steps.
+
+
+
+
+
+Looking for docs on how to add Single Sign-On support in your Supabase project? Head on over to [Single Sign-On with SAML 2.0 for Projects](/docs/guides/auth/enterprise-sso/auth-sso-saml).
diff --git a/apps/docs/content/guides/realtime/authorization.mdx b/apps/docs/content/guides/realtime/authorization.mdx
new file mode 100644
index 00000000000..5e800762690
--- /dev/null
+++ b/apps/docs/content/guides/realtime/authorization.mdx
@@ -0,0 +1,314 @@
+---
+id: 'authorization'
+title: 'Realtime Authorization'
+description: 'Authorization for Supabase Realtime'
+sidebar_label: 'Authorization'
+---
+
+You can control client access to Realtime [Broadcast](/docs/guides/realtime/broadcast) and [Presence](/docs/guides/realtime/presence) by adding Row Level Security policies to the `realtime.messages` table. Each RLS policy can map to a specific action a client can take:
+
+- Control which clients can broadcast to a Channel
+- Control which clients can receive broadcasts from a Channel
+- Control which clients can publish their presence to a Channel
+- Control which clients can receive messages about the presence of other clients
+
+
+
+Realtime Authorization is in Public Alpha. To use Authorization for your Realtime Channels, use `supabase-js` version `v2.44.0` or later.
+
+
+
+## How it works
+
+Realtime uses the `messages` table in your database's `realtime` schema to generate access policies for your clients when they connect to a Channel topic.
+
+By creating RLS polices on the `realtime.messages` table you can control the access users have to a Channel topic, and features within a Channel topic.
+
+The validation is done when the user connects. When their WebSocket connection is established and a Channel topic is joined, their permissions are calculated based on:
+
+- The RLS policies on the `realtime.messages` table
+- The user information sent as part of their [Auth JWT](/docs/guides/auth/jwts)
+- The request headers
+- The Channel topic the user is trying to connect to
+
+When Realtime generates a policy for a client it performs a query on the `realtime.messages` table and then rolls it back. Realtime does not store any messages in your `realtime.messages` table.
+
+Using Realtime Authorization involves two steps:
+
+- In your database, create RLS policies on the `realtime.messages`
+- In your client, instantiate the Realtime Channel with the `config` option `private: true`
+
+
+
+Increased RLS complexity can impact database performance and connection time, leading to higher connection latency and decreased join rates.
+
+
+
+## Helper functions
+
+You can use the following helper functions when writing RLS policies:
+
+### `realtime.topic`
+
+Returns the Channel topic the user is attempting to connect to.
+
+```sql
+create policy "authenticated can read all messages on topic"
+on "realtime"."messages"
+for select
+to authenticated
+using (
+ (select realtime.topic()) = 'room-1'
+);
+```
+
+## Examples
+
+The following examples use this schema:
+
+```sql
+create table public.rooms (
+ id bigint generated by default as identity primary key,
+ topic text not null unique
+);
+
+alter table public.rooms enable row level security;
+
+create table public.profiles (
+ id uuid not null references auth.users on delete cascade,
+ email text NOT NULL,
+
+ primary key (id)
+);
+
+alter table public.profiles enable row level security;
+
+create table public.rooms_users (
+ user_id uuid references auth.users (id),
+ room_topic text references public.rooms (topic),
+ created_at timestamptz default current_timestamp
+);
+
+alter table public.rooms_users enable row level security;
+```
+
+### Broadcast
+
+The `extension` field on the `realtime.messages` table records the message type. For Broadcast messages, the value of `realtime.messages.extension` is `broadcast`. You can check for this in your RLS policies.
+
+#### Allow a user to join (and read) a Broadcast topic
+
+To join a Broadcast Channel, a user must have at least one read or write permission on the Channel topic.
+
+Here, we allow reads (`select`s) for users who are linked to the requested topic within the relationship table `public.room_users`:
+
+```sql
+create policy "authenticated can receive broadcast"
+on "realtime"."messages"
+for select
+to authenticated
+using (
+exists (
+ select
+ user_id
+ from
+ rooms_users
+ where
+ user_id = (select auth.uid())
+ and topic = (select realtime.topic())
+ and realtime.messages.extension in ('broadcast')
+ )
+);
+```
+
+Then, to join a topic with RLS enabled, instantiate the Channel with the `private` option set to `true`.
+
+
+
+ ```javascript
+ const channel = supabase.channel('room-1', {
+ config: { private: true },
+ })
+
+ channel
+ .on('broadcast', { event: 'test' }, (payload) => console.log(payload))
+ .subscribe((status, err) => {
+ if (status === 'SUBSCRIBED') {
+ console.log('Connected!')
+ } else {
+ console.error(err)
+ }
+ })
+ ```
+
+
+
+ ```dart
+ final channel = supabase.channel(
+ 'room-1',
+ opts: const RealtimeChannelConfig(private: true),
+ );
+
+ channel
+ .onBroadcast(event: 'test', callback: (payload) => print(payload))
+ .subscribe((status, err) {
+ if (status == RealtimeSubscribeStatus.subscribed) {
+ print('Connected!');
+ } else {
+ print(err);
+ }
+ });
+ ```
+
+
+
+
+#### Allow a user to send a Broadcast message
+
+To authorize sending Broadcast messages, create a policy for `insert` where the value of `realtime.messages.extension` is `broadcast`.
+
+Here, we allow writes (sends) for users who are linked to the requested topic within the relationship table `public.room_users`:
+
+```sql
+create policy "authenticated can send broadcast on topic"
+on "realtime"."messages"
+for insert
+to authenticated
+with check (
+ exists (
+ select
+ user_id
+ from
+ rooms_users
+ where
+ user_id = (select auth.uid())
+ and topic = (select realtime.topic())
+ and realtime.messages.extension in ('broadcast')
+ )
+);
+```
+
+### Presence
+
+The `extension` field on the `realtime.messages` table records the message type. For Presence messages, the value of `realtime.messages.extension` is `presence`. You can check for this in your RLS policies.
+
+#### Allow users to listen to Presence messages on a Channel
+
+Create a policy for `select` on `realtime.messages` where `realtime.messages.extension` is `presence`.
+
+```sql
+create policy "authenticated can listen to presence in topic"
+on "realtime"."messages"
+for select
+to authenticated
+using (
+ exists (
+ select
+ user_id
+ from
+ rooms_users
+ where
+ user_id = (select auth.uid())
+ and topic = (select realtime.topic())
+ and realtime.messages.extension in ('presence')
+ )
+);
+```
+
+#### Allow users to send Presence messages on a channel
+
+To update the Presence status for a user create a policy for `insert` on `realtime.messages` where the value of `realtime.messages.extension` is `presence`.
+
+```sql
+create policy "authenticated can track presence on topic"
+on "realtime"."messages"
+for insert
+to authenticated
+with check (
+ exists (
+ select
+ user_id
+ from
+ rooms_users
+ where
+ user_id = (select auth.uid())
+ and name = (select realtime.topic())
+ and realtime.messages.extension in ('presence')
+ )
+);
+```
+
+### Presence and Broadcast
+
+Authorize both Presence and Broadcast by including both extensions in the `where` filter.
+
+#### Broadcast and Presence read
+
+Authorize Presence and Broadcast read in one RLS policy.
+
+```sql
+create policy "authenticated can listen to broadcast and presence on topic"
+on "realtime"."messages"
+for select
+to authenticated
+using (
+ exists (
+ select
+ user_id
+ from
+ rooms_users
+ where
+ user_id = (select auth.uid())
+ and topic = (select realtime.topic())
+ and realtime.messages.extension in ('broadcast', 'presence')
+ )
+);
+```
+
+#### Broadcast and Presence write
+
+Authorize Presence and Broadcast write in one RLS policy.
+
+```sql
+create policy "authenticated can send broadcast and presence on topic"
+on "realtime"."messages"
+for insert
+to authenticated
+with check (
+ exists (
+ select
+ user_id
+ from
+ rooms_users
+ where
+ user_id = (select auth.uid())
+ and name = (select realtime.topic())
+ and realtime.messages.extension in ('broadcast', 'presence')
+ )
+);
+```
+
+## Interaction with Postgres Changes
+
+Realtime Postgres Changes are separate from Channel authorization. The `private` Channel option does not apply to Postgres Changes.
+
+When using Postgres Changes with RLS, database records are sent only to clients who are allowed to read them based on your RLS policies.
+
+## Updating RLS policies
+
+Client access polices are cached for the duration of the connection. Your database is not queried for every Channel message.
+
+Realtime updates the access policy cache for a client based on your RLS polices when:
+
+- A client connects to Realtime and subscribes to a Channel
+- A new JWT is sent to Realtime from a client via the [`access_token` message](docs/guides/realtime/protocol#access-token)
+
+If a new JWT is never received on the Channel, the client will be disconnected when the JWT expires.
+
+Make sure to keep the JWT expiration window short.
diff --git a/apps/docs/content/guides/realtime/broadcast.mdx b/apps/docs/content/guides/realtime/broadcast.mdx
index ae0ef21f32a..40d5cd2a34a 100644
--- a/apps/docs/content/guides/realtime/broadcast.mdx
+++ b/apps/docs/content/guides/realtime/broadcast.mdx
@@ -29,7 +29,7 @@ Go to your Supabase project's [API Settings](https://supabase.com/dashboard/proj
const SUPABASE_URL = 'https://.supabase.co'
const SUPABASE_KEY = ''
- const client = createClient(SUPABASE_URL, SUPABASE_KEY)
+ const supabase = createClient(SUPABASE_URL, SUPABASE_KEY)
```
@@ -58,7 +58,7 @@ Go to your Supabase project's [API Settings](https://supabase.com/dashboard/proj
let SUPABASE_URL = "https://.supabase.co"
let SUPABASE_KEY = ""
- let client = SupabaseClient(supabaseURL: URL(string: SUPABASE_URL)!, supabaseKey: SUPABASE_KEY)
+ let supabase = SupabaseClient(supabaseURL: URL(string: SUPABASE_URL)!, supabaseKey: SUPABASE_KEY)
```
@@ -91,7 +91,7 @@ You can provide a callback for the `broadcast` channel to receive message. In th
{/* prettier-ignore */}
```js
// Join a room/topic. Can be anything except for 'realtime'.
- const channelA = clientA.channel('room-1')
+ const channelA = supabase.channel('room-1')
// Simple function to log any messages we receive
function messageReceived(payload) {
@@ -112,6 +112,8 @@ You can provide a callback for the `broadcast` channel to receive message. In th
```dart
+ final channelA = supabase.channel('room-1');
+
// Simple function to log any messages we receive
void messageReceived(payload) {
print(payload);
@@ -128,7 +130,7 @@ You can provide a callback for the `broadcast` channel to receive message. In th
```swift
- let channelA = await clientA.channel("room-1")
+ let channelA = await supabase.channel("room-1")
// Listen for broadcast messages
let broadcastStream = await channelA.broadcast(event: "test")
@@ -144,7 +146,7 @@ You can provide a callback for the `broadcast` channel to receive message. In th
```kotlin
- val channelA = clientA.channel("room-1")
+ val channelA = supabase.channel("room-1")
//Listen for broadcast messages
val broadcastFlow: Flow = channelA.broadcastFlow("test")
@@ -175,7 +177,7 @@ You can provide a callback for the `broadcast` channel to receive message. In th
{/* prettier-ignore */}
```js
// Join a room/topic. Can be anything except for 'realtime'.
- const channelB = clientA.channel('room-1')
+ const channelB = supabase.channel('room-1')
channelB.subscribe((status) => {
// Wait for successful connection
@@ -195,6 +197,8 @@ You can provide a callback for the `broadcast` channel to receive message. In th
+ We can send Broadcast messages using `channelB.sendBroadcastMessage()`. Let's set up another client to send messages.
+
```dart
// Join a room/topic. Can be anything except for 'realtime'.
final channelB = supabase.channel('room-1');
@@ -219,7 +223,7 @@ You can provide a callback for the `broadcast` channel to receive message. In th
We can send Broadcast messages using `channelB.broadcast()`. Let's set up another client to send messages.
```swift
- let channelB = await clientA.channel("room-1")
+ let channelB = await supabase.channel("room-1")
await channelB.subscribe()
@@ -235,7 +239,7 @@ You can provide a callback for the `broadcast` channel to receive message. In th
We can send Broadcast messages using `channelB.broadcast()`. Let's set up another client to send messages.
```kotlin
- val channelB = clientA.channel("room-1")
+ val channelB = supabase.channel("room-1")
channelB.subscribe(blockUntilSubscribed = true) //You can also use the channelA.status flow instead, but this parameter will block the coroutine until the status is joined.
@@ -294,6 +298,8 @@ You can pass configuration options while initializing the Supabase Client.
+ By default, broadcast messages are only sent to other clients. You can broadcast messages back to the sender by setting Broadcast's `self` parameter to `true`.
+
```dart
final myChannel = supabase.channel(
'room-2',
@@ -385,7 +391,7 @@ You can pass configuration options while initializing the Supabase Client.
{/* prettier-ignore */}
```js
- const myChannel = clientD.channel('room-3', {
+ const myChannel = supabase.channel('room-3', {
config: {
broadcast: { ack: true },
},
@@ -433,7 +439,7 @@ You can pass configuration options while initializing the Supabase Client.
You can confirm that Realtime received your message by setting Broadcast's `acknowledgeBroadcasts` config to `true`.
```swift
- let myChannel = await clientD.channel("room-3") {
+ let myChannel = await supabase.channel("room-3") {
$0.broadcast.acknowledgeBroadcasts = true
}
@@ -483,21 +489,21 @@ You can also send a Broadcast message by making an HTTP request to Realtime serv
```js
- const channel = client.channel('test-channel')
+ const channel = supabase.channel('test-channel')
// No need to subscribe to channel
channel
- .send({
- type: 'broadcast',
- event: 'test',
- payload: { message: 'Hi' },
- })
- .then((resp) => console.log(resp))
+ .send({
+ type: 'broadcast',
+ event: 'test',
+ payload: { message: 'Hi' },
+ })
+ .then((resp) => console.log(resp))
// Remember to clean up the channel
- client.removeChannel(channel)
+ supabase.removeChannel(channel)
```
diff --git a/apps/docs/content/guides/realtime/concepts.mdx b/apps/docs/content/guides/realtime/concepts.mdx
index ca5a5672497..64bf45568a3 100644
--- a/apps/docs/content/guides/realtime/concepts.mdx
+++ b/apps/docs/content/guides/realtime/concepts.mdx
@@ -1,12 +1,12 @@
---
id: 'channels'
title: 'Realtime Concepts'
-description: 'Learn about channels and other features in Supabase Realtime'
-subtitle: 'Learn about channels and other features in Supabase Realtime'
+description: 'Learn about Channels and other extensions in Supabase Realtime'
+subtitle: 'Learn about Channels and other extensions in Supabase Realtime'
sidebar_label: 'Concepts'
---
-You can use Supabase Realtime to build real-time applications with collaborative/multiplayer functionality. It includes 3 core features:
+You can use Supabase Realtime to build real-time applications with collaborative/multiplayer functionality. It includes 3 core extensions:
- [Broadcast](/docs/guides/realtime/broadcast): sends rapid, ephemeral messages to other connected clients. You can use it to track mouse movements, for example.
- [Presence](/docs/guides/realtime/presence): sends user state between connected clients. You can use it to show an "online" status, which disappears when a user is disconnected.
@@ -21,9 +21,9 @@ When you initialize your Supabase Realtime client, you define a `topic` that uni
```js
import { createClient } from '@supabase/supabase-js'
-const client = createClient('https://.supabase.co', '')
+const supabase = createClient('https://.supabase.co', '')
-const roomOne = client.channel('room-one') // set your topic here
+const roomOne = supabase.channel('room-one') // set your topic here
```
## Broadcast
@@ -57,20 +57,12 @@ Each client maintains their own state, and this is then combined into a "shared
When a new client subscribes to a channel, it will immediately receive the channel's latest state in a single message because the state is held by the Realtime server.
-## Choosing between broadcast and presence
-
-We recommend using Broadcast by default, and then Presence when required. Presence utilizes an in-memory conflict-free replicated data type (CRDT) to track and synchronize shared state in an eventually consistent manner. It computes the difference between existing state and new state changes and sends the necessary updates to clients via Broadcast. This is computationally heavy, so you should use it sparingly. If you use Presence, it's best to throttle your changes so that you are sending updates less frequently.
-
-## Realtime extensions
-
-Channels provide a generic networking solution. Supabase Realtime is designed to leverage this networking primitive with "extensions". We currently support one extension: Postgres changes.
-
-### Postgres changes
+## Postgres Changes
The Postgres Changes extension listens for database changes and sends them to clients. Clients are required to subscribe with a JWT dictating which changes they are allowed to receive based on the database's [Row Level Security](/docs/guides/database/postgres/row-level-security).
```js
-const allChanges = client
+const allChanges = supabase
.channel('schema-db-changes')
.on(
'postgres_changes',
@@ -86,3 +78,7 @@ const allChanges = client
Anyone with access to a valid JWT signed with the project's JWT secret is able to listen to your database's changes, unless tables have [Row Level Security](/docs/guides/database/postgres/row-level-security) enabled and policies in place.
Clients can choose to receive `INSERT`, `UPDATE`, `DELETE`, or `*` (all) changes for all changes in a schema, a table in a schema, or a column's value in a table. Your clients should only listen to tables in the `public` schema and you must first enable the tables you want your clients to listen to.
+
+## Choosing between Broadcast and Presence
+
+We recommend using Broadcast by default, and then Presence when required. Presence utilizes an in-memory conflict-free replicated data type (CRDT) to track and synchronize shared state in an eventually consistent manner. It computes the difference between existing state and new state changes and sends the necessary updates to clients via Broadcast. This is computationally heavy, so you should use it sparingly. If you use Presence, it's best to throttle your changes so that you are sending updates less frequently.
diff --git a/apps/docs/content/guides/realtime/postgres-changes.mdx b/apps/docs/content/guides/realtime/postgres-changes.mdx
index 512d4b3b9fe..8ef18b661df 100644
--- a/apps/docs/content/guides/realtime/postgres-changes.mdx
+++ b/apps/docs/content/guides/realtime/postgres-changes.mdx
@@ -126,7 +126,7 @@ In this example we'll set up a database table, secure it with Row Level Security
```js
import { createClient } from '@supabase/supabase-js'
- const client = createClient(
+ const supabase = createClient(
'https://.supabase.co',
''
)
@@ -152,7 +152,7 @@ In this example we'll set up a database table, secure it with Row Level Security
```js
- const channelA = client
+ const channelA = supabase
.channel('schema-db-changes')
.on(
'postgres_changes',
@@ -209,7 +209,7 @@ Subscribe to specific schema events using the `schema` parameter:
{/* prettier-ignore */}
```js
-const changes = client
+const changes = supabase
.channel('schema-db-changes')
.on(
'postgres_changes',
@@ -296,7 +296,7 @@ The channel name can be any string except 'realtime'.
Use the `event` parameter to listen only to database `INSERT`s:
```js
-const changes = client
+const changes = supabase
.channel('schema-db-changes')
.on(
'postgres_changes',
@@ -377,7 +377,7 @@ The channel name can be any string except 'realtime'.
Use the `event` parameter to listen only to database `UPDATE`s:
```js
-const changes = client
+const changes = supabase
.channel('schema-db-changes')
.on(
'postgres_changes',
@@ -458,7 +458,7 @@ The channel name can be any string except 'realtime'.
Use the `event` parameter to listen only to database `DELETE`s:
```js
-const changes = client
+const changes = supabase
.channel('schema-db-changes')
.on(
'postgres_changes',
@@ -539,7 +539,7 @@ Subscribe to specific table events using the `table` parameter:
```js
-const changes = client
+const changes = supabase
.channel('table-db-changes')
.on(
'postgres_changes',
@@ -710,7 +710,7 @@ Use the `filter` parameter for granular changes:
```js
-const changes = client
+const changes = supabase
.channel('table-filter-changes')
.on(
'postgres_changes',
diff --git a/apps/docs/content/guides/realtime/quotas.mdx b/apps/docs/content/guides/realtime/quotas.mdx
index 2fc29c352e5..ff1eefea634 100644
--- a/apps/docs/content/guides/realtime/quotas.mdx
+++ b/apps/docs/content/guides/realtime/quotas.mdx
@@ -26,7 +26,7 @@ Upgrade your plan to increase your quotas. Without a spend cap, or on an Enterpr
| **Broadcast payload size KB** | 256 | 3,000 | 3,000 | 3,000 | 3,000 |
| **Postgres change payload size KB ([**read more**](#postgres-changes-payload-quota))** | 1,024 | 1,024 | 1,024 | 1,024 | 1,024 |
-Beyond the Free and Pro plan you can customize your quotas by [contacting support](https://supabase.com/dashboard/support/new).
+Beyond the Free and Pro Plan you can customize your quotas by [contacting support](https://supabase.com/dashboard/support/new).
## Quota errors
diff --git a/apps/docs/content/guides/realtime/realtime-listening-flutter.mdx b/apps/docs/content/guides/realtime/realtime-listening-flutter.mdx
new file mode 100644
index 00000000000..cc7eb48b947
--- /dev/null
+++ b/apps/docs/content/guides/realtime/realtime-listening-flutter.mdx
@@ -0,0 +1,17 @@
+---
+id: 'realtime-listening-flutter'
+title: 'Listening to Postgres Changes with Flutter'
+description: 'Listening to real-time changes on the database with Flutter'
+sidebar_label: 'Videos'
+---
+
+The Postgres Changes extension listens for database changes and sends them to clients which enables you to receive database changes in real-time.
+
+
+
+
diff --git a/apps/docs/content/guides/realtime/realtime-user-presence.mdx b/apps/docs/content/guides/realtime/realtime-user-presence.mdx
new file mode 100644
index 00000000000..2c8fcdc213c
--- /dev/null
+++ b/apps/docs/content/guides/realtime/realtime-user-presence.mdx
@@ -0,0 +1,19 @@
+---
+id: 'realtime-user-presence'
+title: 'Using Realtime Presence with Flutter'
+description: 'Track online users with Supabase Realtime Presence'
+sidebar_label: 'Videos'
+---
+
+Use Supabase Presence to display the currently online users on your Flutter application.
+
+Displaying the list of currently online users is a common feature for real-time collaborative applications. Supabase Presence makes it easy to track users joining and leaving the session so that you can easily make a collaborative app.
+
+
+
+
diff --git a/apps/docs/content/guides/resources.mdx b/apps/docs/content/guides/resources.mdx
index d69a46f7a1e..709f56a0ff2 100644
--- a/apps/docs/content/guides/resources.mdx
+++ b/apps/docs/content/guides/resources.mdx
@@ -56,6 +56,12 @@ hideToc: true
{
[
+ {
+ title: 'Auth0',
+ icon: '/docs/img/icons/auth0-icon',
+ href: '/guides/resources/migrating-to-supabase/auth0',
+ description: 'Move your auth users from Auth0 to a Supabase project.',
+ },
{
title: 'Firebase Auth',
icon: '/docs/img/icons/firebase-icon',
diff --git a/apps/docs/content/guides/resources/migrating-to-supabase/auth0.mdx b/apps/docs/content/guides/resources/migrating-to-supabase/auth0.mdx
new file mode 100644
index 00000000000..157b77e190c
--- /dev/null
+++ b/apps/docs/content/guides/resources/migrating-to-supabase/auth0.mdx
@@ -0,0 +1,257 @@
+---
+title: 'Migrate from Auth0 to Supabase Auth'
+subtitle: 'Learn how to migrate your users from Auth0'
+breadcrumb: 'Migrations'
+---
+
+You can migrate your users from Auth0 to Supabase Auth.
+
+Changing authentication providers for a production app is an important operation. It can affect most aspects of your application. Prepare in advance by reading this guide, and develop a plan for handling the key migration steps and possible problems.
+
+With advance planning, a smooth and safe Auth migration is possible.
+
+## Before you begin
+
+Before beginning, consider the answers to the following questions. They will help you need decide if you need to migrate, and which strategy to use:
+
+- How do Auth provider costs scale as your user base grows?
+- Does the new Auth provider provide all needed features? (for example, OAuth, password logins, Security Assertion Markup Language (SAML), Multi-Factor Authentication (MFA))
+- Is downtime acceptable during the migration?
+- What is your timeline to migrate before terminating the old Auth provider?
+
+## Migration strategies
+
+Depending on your evaluation, you may choose to go with one of the following strategies:
+
+1. Rolling migration
+2. One-off migration
+
+| Strategy | Advantages | Disadvantages |
+| -------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| Rolling |
0 downtime Users may need to log in again |
Need to maintain 2 different Auth services, which may be more costly in the short-term Need to maintain separate codepaths for the period of the migration Some existing users may be inactive and have not signed in with the new provider. This means that you eventually need to backfill these users. However, this is a much smaller-scale one-off migration with lower risks since these users are inactive. |
+| One-off |
No need to maintain 2 different auth services for an extended period of time |
Some downtime Users will need to log in again. Risky for active users. |
+
+## Migration steps
+
+Auth provider migrations require 2 main steps:
+
+1. Export your user data from the old provider (Auth0)
+1. Import the data into your new provider (Supabase Auth)
+
+### Step 1: Export your user data
+
+Auth0 provides two methods for exporting user data:
+
+1. Use the [Auth0 data export feature](https://auth0.com/docs/troubleshoot/customer-support/manage-subscriptions/export-data)
+1. Use the [Auth0 management API](https://auth0.com/docs/api/management/v2/users/get-users). This endpoint has a rate limit, so you may need to export your users in several batches.
+
+To export password hashes and MFA factors, contact Auth0 support.
+
+### Step 2: Import your users into Supabase Auth
+
+The steps for importing your users depends on the login methods that you support.
+
+See the following sections for how to import users with:
+
+- [Password-based login](#password-based-methods)
+- [Passwordless login](#passwordless-methods)
+- [OAuth](#oauth)
+
+#### Password-based methods
+
+For users who sign in with passwords, we recommend a hybrid approach to reduce downtime:
+
+1. For new users, use Supabase Auth for sign up.
+1. Migrate existing users in a one-off migration.
+
+##### Sign up new users
+
+Sign up new users using Supabase Auth's [signin methods](/docs/guides/auth/passwords#signing-up-with-an-email-and-password).
+
+##### Migrate existing users to Supabase Auth
+
+Migrate existing users to Supabase Auth. This requires two main steps: first, check which users need to be migrated, then create their accounts using the Supabase admin endpoints.
+
+1. Get your Auth 0 user export and password hash export lists.
+1. Filter for users who use password login.
+ - Under the `identities` field in the user object, these users will have `auth0` as a provider. In the same identity object, you can find their Auth0 `user_id`.
+ - Check that the user has a corresponding password hash by comapring their Auth0 `user_id` to the `oid` field in the password hash export.
+1. Use Supabase Auth's [admin create user](/docs/reference/javascript/auth-admin-createuser) method to recreate the user in Supabase Auth. If the user has a confirmed email address or phone number, set `email_confirm` or `phone_confirm` to `true`.
+
+ ```ts
+ const { data, error } = await supabase.auth.admin.createUser({
+ email: 'foo@example.com',
+ password_hash: '$2y$10$a9pghn27d7m0ltXvlX8LiOowy7XfFw0hW0G80OjKYQ1jaoejaA7NC',
+ email_confirm: true,
+ })
+ ```
+
+
+
+ Supabase supports BCrypt and Argon2 password hashes.
+
+
+
+ If you have a plaintext password instead of a hash, you can provide that instead. Supabase Auth will handle hashing the password for you. (Passwords are **always** stored hashed.)
+
+ ```ts
+ const { data, error } = await supabase.auth.admin.createUser({
+ email: 'foo@example.com',
+ password: 'supersecurepassword123!',
+ })
+ ```
+
+1. To sign in your migrated users, use the Supabase Auth [sign in methods](/docs/reference/javascript/auth-signinwithpassword).
+
+ To check for edge cases where users aren't successfully migrated, use a fallback strategy. This ensures that users can continue to sign in seamlessly:
+
+ 1. Try to sign in the user with Supabase Auth.
+ 1. If the signin fails, try to sign in with Auth0.
+ 1. If Auth0 signin succeeds, call the admin create user method again to create the user in Supabase Auth.
+
+#### Passwordless methods
+
+For passwordless signin via email or phone, check for users with verified email addresses or phone numbers. Create these users in Supabase Auth with `email_confirm` or `phone_confirm` set to `true`:
+
+```ts
+const { data, error } = await supabase.auth.admin.createUser({
+ email: 'foo@example.com',
+ email_confirm: true,
+})
+```
+
+Check your Supabase Auth [email configuration](/docs/guides/auth/auth-smtp) and configure your [email template](/dashboard/project/_/auth/templates) for use with magic links. See the [Email templates guide](/docs/guides/auth/auth-email-templates) to learn more.
+
+Once you have imported your users, you can sign them in using the [`signInWithOtp`](/docs/reference/javascript/auth-signinwithotp) method.
+
+#### OAuth
+
+Configure your OAuth providers in Supabase by following the [Social login guides](/docs/guides/auth/social-login).
+
+For both new and existing users, sign in the user using the [`signInWithOAuth`](https://supabase.com/docs/reference/javascript/auth-signinwithoauth) method. This works without pre-migrating existing users, since the user always needs to sign in through the OAuth provider before being redirected to your service.
+
+After the user has completed the OAuth flow successfully, you can check if the user is a new or existing user in Auth0 by mapping their social provider id to Auth0. Auth0 stores the social provider ID in the user ID, which has the format `provider_name|provider_id` (for example, `github|123456`). See the [Auth0 identity docs](https://auth0.com/docs/manage-users/user-accounts/identify-users) to learn more.
+
+## Mapping between Auth0 and Supabase Auth
+
+Each Auth provider has its own schema for tracking users and user information.
+
+In Supabase Auth, your users are stored in your project's database under the `auth` schema. Every user has an identity (unless the user is an anonymous user), which represents the signin method they can use with Supabase. This is represented by the `auth.users` and `auth.identities` table.
+
+See the [Users](/docs/guides/auth/users) and [Identities](/docs/guides/auth/identities) sections to learn more.
+
+### Mapping user metadata and custom claims
+
+Supabase Auth provides 2 fields which you can use to map user-specific metadata from Auth0:
+
+- `auth.users.raw_user_meta_data` : For storing non-sensitive user metadata that the user can update (e.g full name, age, favorite color).
+- `auth.users.raw_app_meta_data` : For storing non-sensitive user metadata that the user should not be able to update (e.g pricing plan, access control roles).
+
+Both columns are accessible from the admin user methods. To create a user with custom metadata, you can use the following method:
+
+```ts
+const { data, error } = await supabase.auth.admin.createUser({
+ email: 'foo@example.com',
+ user_metadata: {
+ full_name: 'Foo Bar',
+ },
+ app_metadata: {
+ role: 'admin',
+ },
+})
+```
+
+
+
+These fields will be exposed in the user's access token JWT so it is recommended not to store excessive metadata in these fields.
+
+
+
+These fields are stored as columns in the `auth.users` table using the `jsonb` type. Both fields can be updated by using the admin [`updateUserById` method](/docs/reference/javascript/auth-admin-updateuserbyid). If you want to allow the user to update their own `raw_user_meta_data` , you can use the [`updateUser` method](/docs/reference/javascript/auth-updateuser).
+
+If you have a lot of user-specific metadata to store, it is recommended to create your own table in a private schema that uses the user id as a foreign key:
+
+```sql
+create table private.user_metadata (
+ id int generated always as identity,
+ user_id uuid references auth.users(id) on delete cascade,
+ user_metadata jsonb
+);
+```
+
+## Frequently Asked Questions (FAQ)
+
+
+
+I have IDs assigned to existing users in my database, how can I maintain these IDs?}
+id="custom-user-id"
+>
+
+All users stored in Supabase Auth use the UUID V4 format as the ID. If your UUID format is identical, you can specify it in the admin create user method like this:
+
+
+
+New users in Supabase Auth will always be created with a UUID V4 ID by default.
+
+
+
+```ts
+// specify a custom id
+const { data, error } = await supabase.auth.admin.createUser({
+ id: 'e7f5ae65-376e-4d05-a18c-10a91295727a',
+ email: 'foo@example.com',
+})
+```
+
+
+
+How can I allow my users to retain their existing password?}
+id="existing-password"
+>
+
+Supabase Auth never stores passwords as plaintext. Since Supabase Auth supports reading BCrypt and argon2 password hashes, you can import your users passwords if they use the same hashing algorithm. New users in Supabase Auth who use password-based sign-in methods will always use a BCrypt hash. Passwords are stored in the `auth.users.encrypted_password` column.
+
+
+
+My users have multi-factor authentication (MFA) enabled, how do I make sure they don't have to set up MFA again?}
+id="mfa"
+>
+
+You can obtain an export of your users' MFA secrets by opening a support ticket with Auth0, similar to obtaining the export for password hashes. Supabase Auth only supports time-based one-time passwords (TOTP). Users who have TOTP-based factors may need to re-enroll using their choice of TOTP-based authenticator instead (e.g. 1Password / Google authenticator).
+
+
+
+How do I migrate existing SAML Single Sign-On (SSO) connections?}
+id="saml"
+>
+
+Customers may need to link their identity provider with Supabase Auth separately, but their users should still be able to sign-in as per-normal after authenticating with their identity provider. For more information about SSO with SAML 2.0, you can check out [this guide](/docs/guides/auth/enterprise-sso/auth-sso-saml). If you want to migrate your existing SAML SSO connections from Auth0 to Supabase Auth, please reach out to us via support.
+
+
+
+How do I migrate my Auth0 organizations to Supabase?}
+id="migrate-org"
+>
+
+This isn't supported by Supabase Auth yet.
+
+
+
+
+
+## Useful references
+
+- [Migrating 125k users from Auth0 to Supabase](https://kevcodez.medium.com/migrating-125-000-users-from-auth0-to-supabase-81c0568de307)
+- [Loper to Supabase migraton](https://eigen.sh/posts/auth-migration)
diff --git a/apps/docs/content/guides/self-hosting/docker.mdx b/apps/docs/content/guides/self-hosting/docker.mdx
index 4a73358c096..1102ab38de1 100644
--- a/apps/docs/content/guides/self-hosting/docker.mdx
+++ b/apps/docs/content/guides/self-hosting/docker.mdx
@@ -67,6 +67,8 @@ docker compose up -d
+If you are using rootless docker, edit `.env` and set `DOCKER_SOCKET_LOCATION` to your docker socket location. For example: `/run/user/1000/docker.sock`. Otherwise, you will see an error like `container supabase-vector exited (0)`.
+
After all the services have started you can see them running in the background:
```sh
diff --git a/apps/docs/content/guides/storage/cdn/smart-cdn.mdx b/apps/docs/content/guides/storage/cdn/smart-cdn.mdx
index e6b9f235cd9..dffa1f278af 100644
--- a/apps/docs/content/guides/storage/cdn/smart-cdn.mdx
+++ b/apps/docs/content/guides/storage/cdn/smart-cdn.mdx
@@ -11,7 +11,7 @@ Moreover, the Smart CDN achieves a greater cache hit rate by shielding the origi
-Smart CDN caching is automatically enabled for [Pro plan and above](https://supabase.com/pricing).
+Smart CDN caching is automatically enabled for [Pro Plan and above](https://supabase.com/pricing).
diff --git a/apps/docs/content/guides/storage/debugging/logs.mdx b/apps/docs/content/guides/storage/debugging/logs.mdx
index ddf0e93dabb..3139523d717 100644
--- a/apps/docs/content/guides/storage/debugging/logs.mdx
+++ b/apps/docs/content/guides/storage/debugging/logs.mdx
@@ -12,27 +12,41 @@ Accessing the [Storage Logs](/dashboard/project/__/logs/explorer?q=select+id%2C+
#### Filter by status 5XX error
```sql
-select id, storage_logs.timestamp, event_message, r.statusCode, e.message as errorMessage e.raw as rawError
- from storage_logs
+select
+ id,
+ storage_logs.timestamp,
+ event_message,
+ r.statusCode,
+ e.message as errorMessage,
+ e.raw as rawError
+from
+ storage_logs
cross join unnest(metadata) as m
cross join unnest(m.res) as r
cross join unnest(m.error) as e
- where r.statusCode >= 500
- order by timestamp desc
- limit 100
+where r.statusCode >= 500
+order by timestamp desc
+limit 100;
```
#### Filter by status 4XX error
```sql
-select id, storage_logs.timestamp, event_message, r.statusCode, e.message as errorMessage e.raw as rawError
- from storage_logs
+select
+ id,
+ storage_logs.timestamp,
+ event_message,
+ r.statusCode,
+ e.message as errorMessage,
+ e.raw as rawError
+from
+ storage_logs
cross join unnest(metadata) as m
cross join unnest(m.res) as r
cross join unnest(m.error) as e
- where r.statusCode >= 400 and r.statusCode < 500
- order by timestamp desc
- limit 100
+where r.statusCode >= 400 and r.statusCode < 500
+order by timestamp desc
+limit 100;
```
#### Filter by method
diff --git a/apps/docs/content/guides/storage/s3/authentication.mdx b/apps/docs/content/guides/storage/s3/authentication.mdx
index ab127a2d1a4..b6a09be5555 100644
--- a/apps/docs/content/guides/storage/s3/authentication.mdx
+++ b/apps/docs/content/guides/storage/s3/authentication.mdx
@@ -42,7 +42,7 @@ This is all the information you need to connect to Supabase Storage using any S3
endpoint: 'https://project_ref.supabase.co/storage/v1/s3',
credentials: {
accessKeyId: 'your_access_key_id',
- accessSecretKey: 'your_secret_access_key',
+ secretAccessKey: 'your_secret_access_key',
}
})
```
@@ -71,7 +71,7 @@ All S3 operations performed with the Session Token are scoped to the authenticat
To authenticate with S3 using a Session Token, use the following credentials:
- access_key_id: `project_ref`
-- access_secret_key: `anonKey`
+- secret_access_key: `anonKey`
- session_token: `valid jwt token`
For example, using the `aws-sdk` library:
@@ -89,7 +89,7 @@ const client = new S3Client({
endpoint: 'https://project_ref.supabase.co/storage/v1/s3',
credentials: {
accessKeyId: 'project_ref',
- accessSecretKey: 'anonKey',
+ secretAccessKey: 'anonKey',
sessionToken: session.access_token,
},
})
diff --git a/apps/docs/content/guides/storage/schema/custom-roles.mdx b/apps/docs/content/guides/storage/schema/custom-roles.mdx
index 8d2b86cc8dc..dcb1a72b497 100644
--- a/apps/docs/content/guides/storage/schema/custom-roles.mdx
+++ b/apps/docs/content/guides/storage/schema/custom-roles.mdx
@@ -32,7 +32,7 @@ on storage.objects
for select
to manager
using (
- bucker_id = 'teams'
+ bucket_id = 'teams'
);
```
diff --git a/apps/docs/content/guides/storage/schema/helper-functions.mdx b/apps/docs/content/guides/storage/schema/helper-functions.mdx
index a29ab4bb17a..b8fef508159 100644
--- a/apps/docs/content/guides/storage/schema/helper-functions.mdx
+++ b/apps/docs/content/guides/storage/schema/helper-functions.mdx
@@ -17,7 +17,7 @@ Returns the name of a file. For example, if your file is stored in `public/subfo
This example demonstrates how you would allow any user to download a file called `favicon.ico`:
```sql
-create policy "Allow authenticated uploads"
+create policy "Allow public downloads"
on storage.objects
for select
to public
diff --git a/apps/docs/content/guides/storage/serving/bandwidth.mdx b/apps/docs/content/guides/storage/serving/bandwidth.mdx
index 4c0049ed0db..b2153fbb91c 100644
--- a/apps/docs/content/guides/storage/serving/bandwidth.mdx
+++ b/apps/docs/content/guides/storage/serving/bandwidth.mdx
@@ -8,7 +8,7 @@ sidebar_label: 'Bandwidth & Storage Egress'
## Bandwidth & Storage Egress
-Free plan Organizations in Supabase have a limit of 5 GB of bandwidth. This limit is calculated by the sum of all the data transferred from the Supabase servers to the client. This includes all the data transferred from the database, storage, and functions.
+Free Plan Organizations in Supabase have a limit of 5 GB of bandwidth. This limit is calculated by the sum of all the data transferred from the Supabase servers to the client. This includes all the data transferred from the database, storage, and functions.
### Checking Storage Egress Requests in Log Explorer:
@@ -69,4 +69,4 @@ You can see that these values can get quite large, so it's important to keep tra
### Optimizing Egress:
-If you are on the pro plan, you can use the [Supabase Image Transformations](/docs/guides/storage/image-transformations) to optimize the images and reduce the egress.
+If you are on the Pro Plan, you can use the [Supabase Image Transformations](/docs/guides/storage/image-transformations) to optimize the images and reduce the egress.
diff --git a/apps/docs/content/guides/storage/serving/image-transformations.mdx b/apps/docs/content/guides/storage/serving/image-transformations.mdx
index aa1e1ebfb67..cf445bf65bb 100644
--- a/apps/docs/content/guides/storage/serving/image-transformations.mdx
+++ b/apps/docs/content/guides/storage/serving/image-transformations.mdx
@@ -11,7 +11,7 @@ Supabase Storage offers the functionality to optimize and resize images on the f
-Image Resizing is currently enabled for [Pro plan and above](https://supabase.com/pricing).
+Image Resizing is currently enabled for [Pro Plan and above](https://supabase.com/pricing).
@@ -303,7 +303,7 @@ To get started, create a `supabase-image-loader.js` file in your Next.js project
const projectId = '' // your supabase project id
export default function supabaseLoader({ src, width, quality }) {
- return `https://${projectId}.supabase.co/storage/v1/object/public/${src}?width=${width}&quality=${quality || 75}`
+ return `https://${projectId}.supabase.co/storage/v1/render/image/public/${src}?width=${width}&quality=${quality || 75}`
}
```
diff --git a/apps/docs/docs/ref/javascript/installing.mdx b/apps/docs/docs/ref/javascript/installing.mdx
index eb133446abf..3a5d4cbe44d 100644
--- a/apps/docs/docs/ref/javascript/installing.mdx
+++ b/apps/docs/docs/ref/javascript/installing.mdx
@@ -73,14 +73,14 @@ custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supab
- You can use supabase-js in the Deno runtime via esm.sh:
+ You can use supabase-js in the Deno runtime via [JSR](https://jsr.io/@supabase/supabase-js):
```ts
- import { createClient } from 'https://esm.sh/@supabase/supabase-js@2'
+ import { createClient } from 'jsr:@supabase/supabase-js@2'
```
diff --git a/apps/docs/docs/ref/javascript/typescript-support.mdx b/apps/docs/docs/ref/javascript/typescript-support.mdx
index 101350b24d5..3818dddca9f 100644
--- a/apps/docs/docs/ref/javascript/typescript-support.mdx
+++ b/apps/docs/docs/ref/javascript/typescript-support.mdx
@@ -14,7 +14,7 @@ With TypeScript, `supabase-js` detects things like `not null` constraints and [g
- You can use the Supabase CLI to [generate the types](/docs/reference/cli/supabase-gen-types-typescript). You can also generate the types [from the dashboard](https://supabase.com/dashboard/project/_/api?page=tables-intro).
+ You can use the Supabase CLI to [generate the types](/docs/reference/cli/supabase-gen-types). You can also generate the types [from the dashboard](https://supabase.com/dashboard/project/_/api?page=tables-intro).
diff --git a/apps/docs/docs/ref/kotlin/installing.mdx b/apps/docs/docs/ref/kotlin/installing.mdx
index e8e7c65b15f..f6e5c9ba8b3 100644
--- a/apps/docs/docs/ref/kotlin/installing.mdx
+++ b/apps/docs/docs/ref/kotlin/installing.mdx
@@ -8,7 +8,7 @@ custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supab
### Add one or more modules to your project
-
+
- Add dependency to your build file:
-
-
- ```kotlin
- implementation("io.github.jan-tennert.supabase:[module]:VERSION")
- ```
-
-
-
-
- ```groovy
- implementation 'io.github.jan-tennert.supabase:[module]:VERSION'
- ```
-
-
-
-
- ```xml
-
- io.github.jan-tennert.supabase
- [module]
- VERSION
-
- ```
-
-
-
+ Add dependency to your build file using the BOM.
The available modules are:
- [**gotrue-kt**](https://github.com/supabase-community/supabase-kt/tree/master/GoTrue)
@@ -57,14 +26,10 @@ custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supab
- [**storage-kt**](https://github.com/supabase-community/supabase-kt/tree/master/Storage)
- [**functions-kt**](https://github.com/supabase-community/supabase-kt/tree/master/Functions)
- [**postgrest-kt**](https://github.com/supabase-community/supabase-kt/tree/master/Postgrest)
- - [apollo-graphql](https://github.com/supabase-community/supabase-kt/tree/master/plugins/ApolloGraphQL) - Creates an [Apollo GraphQL Client](https://github.com/apollographql/apollo-kotlin) for interacting with the Supabase API.
- - [compose-auth](https://github.com/supabase-community/supabase-kt/tree/master/plugins/ComposeAuth) - Provides easy Native Google & Apple Auth for Compose Multiplatform targets.
- - [compose-auth-ui](https://github.com/supabase-community/supabase-kt/tree/master/plugins/ComposeAuthUI) - Provides UI Components for Compose Multiplatform.
- - [coil-integration](https://github.com/supabase-community/supabase-kt/tree/master/plugins/CoilIntegration) - Provides a [Coil](https://github.com/coil-kt/coil) Integration for displaying images stored in Supabase Storage.
- - [imageloader-integration](https://github.com/supabase-community/supabase-kt/tree/master/plugins/ImageLoaderIntegration) - Provides a [Compose ImageLoader](https://github.com/qdsfdhvh/compose-imageloader) Integration for displaying images stored in Supabase Storage.
-
- When using multiple modules, you can also use the BOM dependency to ensure that all modules use the same version:
+ - Other plugins also available [here](https://github.com/supabase-community/supabase-kt/tree/master/plugins)
+
+
io.github.jan-tennert.supabase
postgrest-kt
+
+ io.github.jan-tennert.supabase
+ gotrue-kt
+
io.github.jan-tennert.supabase
realtime-kt
@@ -111,7 +82,6 @@ custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supab
-
@@ -119,10 +89,12 @@ custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supab
### Add Ktor Client Engine to each of your Kotlin targets (required)
-
+
You can find a list of engines [here](https://ktor.io/docs/http-client-engines.html)
+
+
+
+
+
Multiplatform example:
+
+
+
Python Client Library
- @supabase-community/supabase-py
+ @supabase/supabase-py
{/* prettier-ignore */}
-
This reference documents every object and method available in the [supabase-py](https://github.com/supabase-community/supabase-py) library from the Supabase community. You can use `supabase-py` to test with your Postgres database, listen to database changes, invoke Deno Edge Functions, build login and user management functionality, and manage large files.
-
-
-
-
-The Python client library is created and maintained by the Supabase community, and is not an official library. Please be tolerant of areas where the library is still being developed, and — as with all the libraries — feel free to contribute wherever you find issues.
-
-Huge thanks to official maintainers, [anand2312](https://github.com/anand2312/), [dreinon](https://github.com/dreinon), [J0](https://github.com/j0), and [Leynier](https://github.com/leynier).
-
-Shoutout to [timkpaine](https://github.com/timkpaine) for maintaining our Conda libraries as well.
-
+
This reference documents every object and method available in Supabase's Python library, [supabase-py](https://github.com/supabase/supabase-py). You can use supabase-py to interact with your Postgres database, listen to database changes, invoke Deno Edge Functions, build login and user management functionality, and manage large files.
diff --git a/apps/docs/docs/ref/shared/auth-error-codes.mdx b/apps/docs/docs/ref/shared/auth-error-codes.mdx
index 74f268d99d2..06e63a9fb24 100644
--- a/apps/docs/docs/ref/shared/auth-error-codes.mdx
+++ b/apps/docs/docs/ref/shared/auth-error-codes.mdx
@@ -84,7 +84,7 @@ To supplement HTTP status codes, Supabase Auth returns a string error code which
| `user_not_found` | User to which the API request relates no longer exists. |
| `user_sso_managed` | When a user comes from SSO, certain fields of the user cannot be updated (like `email`). |
| `validation_failed` | Provided parameters are not in the expected format. |
-| `weak_password` | User is signing up or changing their password without meeting the password strength criteria. Use the `AuthWeakPasswordError` class to access more information about what they need to do to make the assword pass. |
+| `weak_password` | User is signing up or changing their password without meeting the password strength criteria. Use the `AuthWeakPasswordError` class to access more information about what they need to do to make the password pass. |
### Tips for better error handling
diff --git a/apps/docs/features/app.providers.tsx b/apps/docs/features/app.providers.tsx
new file mode 100644
index 00000000000..9a40768434c
--- /dev/null
+++ b/apps/docs/features/app.providers.tsx
@@ -0,0 +1,41 @@
+import { CommandMenuProvider } from '@ui-patterns/Cmdk'
+import { ThemeProvider } from 'common'
+import { PortalToast } from 'ui'
+import { type PropsWithChildren } from 'react'
+
+import SiteLayout from '~/layouts/SiteLayout'
+import { AuthContainer } from './auth/auth.client'
+import { QueryClientProvider } from './data/queryClient.client'
+import { ShortcutPreviewBuild } from './envs/staging.client'
+import { PageTelemetry } from './telemetry/telemetry.client'
+import { ScrollRestoration } from './ui/helpers.scroll.client'
+import { ThemeSandbox } from './ui/theme.client'
+
+/**
+ * Global providers that wrap the entire app
+ */
+function GlobalProviders({ children }: PropsWithChildren) {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+export { GlobalProviders }
diff --git a/apps/docs/features/docs/GuidesMdx.client.tsx b/apps/docs/features/docs/GuidesMdx.client.tsx
new file mode 100644
index 00000000000..b0bc609650b
--- /dev/null
+++ b/apps/docs/features/docs/GuidesMdx.client.tsx
@@ -0,0 +1,16 @@
+'use client'
+
+/**
+ * The MDXProvider is necessary so that MDX partials will have access
+ * to components.
+ */
+
+import { MDXProvider } from '@mdx-js/react'
+import { type PropsWithChildren } from 'react'
+import { components } from '~/features/docs/MdxBase.shared'
+
+const MDXProviderGuides = ({ children }: PropsWithChildren) => (
+ {children}
+)
+
+export { MDXProviderGuides }
diff --git a/apps/docs/features/docs/GuidesMdx.template.tsx b/apps/docs/features/docs/GuidesMdx.template.tsx
new file mode 100644
index 00000000000..7e5bf96871e
--- /dev/null
+++ b/apps/docs/features/docs/GuidesMdx.template.tsx
@@ -0,0 +1,131 @@
+import { ExternalLink } from 'lucide-react'
+import { type SerializeOptions } from 'next-mdx-remote/dist/types'
+import { type ReactNode } from 'react'
+
+import { cn } from 'ui'
+
+import Breadcrumbs from '~/components/Breadcrumbs'
+import GuidesTableOfContents from '~/components/GuidesTableOfContents'
+import { MDXProviderGuides } from '~/features/docs/GuidesMdx.client'
+import { MDXRemoteBase } from '~/features/docs/MdxBase'
+import type { WithRequired } from '~/features/helpers.types'
+import { type GuideFrontmatter } from '~/lib/docs'
+
+const EDIT_LINK_SYMBOL = Symbol('edit link')
+interface EditLink {
+ [EDIT_LINK_SYMBOL]: true
+ link: string
+ includesProtocol: boolean
+}
+
+/**
+ * Create an object representing a link where the original content can be
+ * edited.
+ *
+ * Takes either a relative path, which will be prefixed with
+ * `https://github.com/`, or a full URL including protocol.
+ */
+const newEditLink = (str: string): EditLink => {
+ if (str.startsWith('/')) {
+ throw Error(`Edit links cannot start with slashes. Received: ${str}`)
+ }
+
+ /**
+ * Catch strings that provide FQDNS without https?:
+ *
+ * At the start of a string, before the first slash, there is a dot
+ * surrounded by non-slash characters.
+ */
+ if (/^[^\/]+\.[^\/]+\//.test(str)) {
+ throw Error(`Fully qualified domain names must start with 'https?'. Received: ${str}`)
+ }
+
+ return {
+ [EDIT_LINK_SYMBOL]: true,
+ link: str,
+ includesProtocol: str.startsWith('http://') || str.startsWith('https://'),
+ }
+}
+
+interface BaseGuideTemplateProps {
+ meta?: GuideFrontmatter
+ content?: string
+ children?: ReactNode
+ editLink: EditLink
+ mdxOptions?: SerializeOptions
+}
+
+type GuideTemplateProps =
+ | WithRequired
+ | WithRequired
+
+const GuideTemplate = ({ meta, content, children, editLink, mdxOptions }: GuideTemplateProps) => {
+ const hideToc = meta?.hideToc || meta?.hide_table_of_contents
+
+ return (
+
+
+
+
+ {meta?.title || 'Supabase Docs'}
+ {meta?.subtitle && (
+ {meta.subtitle}
+ )}
+
+
+ {content && }
+
+ {children}
+
+
+
+ {!hideToc && (
+
+ )}
+
+ )
+}
+
+export { GuideTemplate, newEditLink }
diff --git a/apps/docs/features/docs/GuidesMdx.utils.tsx b/apps/docs/features/docs/GuidesMdx.utils.tsx
new file mode 100644
index 00000000000..dc3b05f13c6
--- /dev/null
+++ b/apps/docs/features/docs/GuidesMdx.utils.tsx
@@ -0,0 +1,149 @@
+import matter from 'gray-matter'
+import { type Metadata, type ResolvingMetadata } from 'next'
+import { redirect } from 'next/navigation'
+import { readFile, readdir } from 'node:fs/promises'
+import { extname, join, sep } from 'node:path'
+
+import { cache_fullProcess_withDevCacheBust, existsFile } from '~/features/helpers.fs'
+import type { OrPromise } from '~/features/helpers.types'
+import { notFoundLink } from '~/features/recommendations/NotFound.utils'
+import { BASE_PATH, MISC_URL } from '~/lib/constants'
+import { GUIDES_DIRECTORY, isValidGuideFrontmatter, type GuideFrontmatter } from '~/lib/docs'
+import { newEditLink } from './GuidesMdx.template'
+
+/**
+ * [TODO Charis]
+ *
+ * This is kind of a dumb place for this to be, clean up later as part of
+ * cleaning up navigation menus.
+ */
+const PUBLISHED_SECTIONS = [
+ 'ai',
+ 'api',
+ 'auth',
+ 'cli',
+ 'database',
+ 'functions',
+ 'getting-started',
+ // 'graphql', -- technically published, but completely federated
+ 'platform',
+ 'realtime',
+ 'resources',
+ 'self-hosting',
+ 'storage',
+] as const
+
+const getGuidesMarkdownInternal = async ({ slug }: { slug: string[] }) => {
+ const relPath = slug.join(sep).replace(/\/$/, '')
+ const fullPath = join(GUIDES_DIRECTORY, relPath + '.mdx')
+ /**
+ * SAFETY CHECK:
+ * Prevent accessing anything outside of published sections and GUIDES_DIRECTORY
+ */
+ if (
+ !fullPath.startsWith(GUIDES_DIRECTORY) ||
+ !PUBLISHED_SECTIONS.some((section) => relPath.startsWith(section))
+ ) {
+ redirect(notFoundLink(slug.join('/')))
+ }
+
+ let mdx: string
+ try {
+ mdx = await readFile(fullPath, 'utf-8')
+ } catch {
+ redirect(notFoundLink(slug.join('/')))
+ }
+
+ const editLink = newEditLink(
+ `supabase/supabase/blob/master/apps/docs/content/guides/${relPath}.mdx`
+ )
+
+ const { data: meta, content } = matter(mdx)
+ if (!isValidGuideFrontmatter(meta)) {
+ throw Error('Type of frontmatter is not valid')
+ }
+
+ return {
+ pathname: `/guides/${slug.join('/')}` satisfies `/${string}`,
+ meta,
+ content,
+ editLink,
+ }
+}
+
+/**
+ * Caching this for the entire process is fine because the Markdown content is
+ * baked into each deployment and cannot change. There's also nothing sensitive
+ * here: this is just reading the public MDX files from the codebase.
+ */
+const getGuidesMarkdown = cache_fullProcess_withDevCacheBust(
+ getGuidesMarkdownInternal,
+ GUIDES_DIRECTORY,
+ (filename: string) => JSON.stringify([{ slug: filename.replace(/\.mdx$/, '').split(sep) }])
+)
+
+const genGuidesStaticParams = (directory?: string) => async () => {
+ const promises = directory
+ ? (await readdir(join(GUIDES_DIRECTORY, directory), { recursive: true }))
+ .filter((file) => extname(file) === '.mdx' && !file.split(sep).at(-1).startsWith('_'))
+ .map((file) => ({ slug: file.replace(/\.mdx$/, '').split(sep) }))
+ : PUBLISHED_SECTIONS.map(async (section) =>
+ (await readdir(join(GUIDES_DIRECTORY, section), { recursive: true }))
+ .filter((file) => extname(file) === '.mdx' && !file.split(sep).at(-1).startsWith('_'))
+ .map((file) => ({
+ slug: [section, ...file.replace(/\.mdx$/, '').split(sep)],
+ }))
+ .concat(
+ (await existsFile(join(GUIDES_DIRECTORY, `${section}.mdx`)))
+ ? [{ slug: [section] }]
+ : []
+ )
+ )
+
+ /**
+ * Flattening earlier will not work because there is nothing to flatten
+ * until the promises resolve.
+ */
+ const result = (await Promise.all(promises)).flat()
+ return result
+}
+
+const pluckPromise = (promise: Promise, key: K) =>
+ promise.then((data) => data[key])
+
+const genGuideMeta =
+ (
+ generate: (params: Params) => OrPromise<{ meta: GuideFrontmatter; pathname: `/${string}` }>
+ ) =>
+ async ({ params }: { params: Params }, parent: ResolvingMetadata): Promise => {
+ const [parentAlternates, parentOg, { meta, pathname }] = await Promise.all([
+ pluckPromise(parent, 'alternates'),
+ pluckPromise(parent, 'openGraph'),
+ generate(params),
+ ])
+
+ // Pathname has form `/guides/(section)/**`
+ const ogType = pathname.split('/')[2]
+
+ return {
+ title: `${meta.title} | Supabase Docs`,
+ description: meta.description || meta.subtitle,
+ // @ts-ignore
+ alternates: {
+ ...parentAlternates,
+ canonical: meta.canonical || `${BASE_PATH}${pathname}`,
+ },
+ openGraph: {
+ ...parentOg,
+ url: `${BASE_PATH}${pathname}`,
+ images: {
+ url: `${MISC_URL}/functions/v1/og-images?site=docs&type=${encodeURIComponent(ogType)}&title=${encodeURIComponent(meta.title)}&description=${encodeURIComponent(meta.description ?? 'undefined')}`,
+ width: 800,
+ height: 600,
+ alt: meta.title,
+ },
+ },
+ }
+ }
+
+export { getGuidesMarkdown, genGuidesStaticParams, genGuideMeta }
diff --git a/apps/docs/features/docs/MdxBase.shared.tsx b/apps/docs/features/docs/MdxBase.shared.tsx
new file mode 100644
index 00000000000..e8adc4606cb
--- /dev/null
+++ b/apps/docs/features/docs/MdxBase.shared.tsx
@@ -0,0 +1,97 @@
+import { ArrowDown, Check, X } from 'lucide-react'
+import Link from 'next/link'
+import { GlassPanel } from 'ui-patterns/GlassPanel'
+import { IconPanel } from 'ui-patterns/IconPanel'
+import SqlToRest from 'ui-patterns/SqlToRest'
+import { Admonition, Button, Image } from 'ui'
+import { Heading } from 'ui/src/components/CustomHTMLElements'
+import { AppleSecretGenerator } from '~/components/AppleSecretGenerator'
+import AuthProviders from '~/components/AuthProviders'
+import { AuthSmsProviderConfig } from '~/components/AuthSmsProviderConfig'
+import { CostWarning } from '~/components/AuthSmsProviderConfig/AuthSmsProviderConfig.Warnings'
+import ButtonCard from '~/components/ButtonCard'
+import { Extensions } from '~/components/Extensions'
+import { JwtGenerator } from '~/components/JwtGenerator'
+import {
+ AuthRateLimits,
+ CreateClientSnippet,
+ DatabaseSetup,
+ GetSessionWarning,
+ HuggingFaceDeployment,
+ KotlinProjectSetup,
+ MigrationWarnings,
+ ProjectSetup,
+ OAuthPkceFlow,
+ QuickstartIntro,
+ SocialProviderSettingsSupabase,
+ SocialProviderSetup,
+} from '~/components/MDX/partials'
+import { NavData } from '~/components/NavData'
+import { ProjectConfigVariables } from '~/components/ProjectConfigVariables'
+import { RealtimeLimitsEstimator } from '~/components/RealtimeLimitsEstimator'
+import { RegionsList } from '~/components/RegionsList'
+import { SharedData } from '~/components/SharedData'
+import StepHikeCompact from '~/components/StepHikeCompact'
+import { Accordion, AccordionItem } from '~/features/ui/Accordion'
+import * as CH from '~/features/ui/CodeHike'
+import { Tabs, TabPanel } from '~/features/ui/Tabs'
+
+const components = {
+ Accordion,
+ AccordionItem,
+ Admonition,
+ AuthRateLimits,
+ AuthSmsProviderConfig,
+ AppleSecretGenerator,
+ AuthProviders,
+ Button,
+ ButtonCard,
+ CH,
+ CostWarning,
+ CreateClientSnippet,
+ DatabaseSetup,
+ Extensions,
+ GetSessionWarning,
+ GlassPanel,
+ HuggingFaceDeployment,
+ IconArrowDown: ArrowDown,
+ IconCheck: Check,
+ IconPanel,
+ IconX: X,
+ Image: (props: any) => ,
+ JwtGenerator,
+ KotlinProjectSetup,
+ Link,
+ MigrationWarnings,
+ NavData,
+ OAuthPkceFlow,
+ ProjectConfigVariables,
+ ProjectSetup,
+ QuickstartIntro,
+ RealtimeLimitsEstimator,
+ RegionsList,
+ SharedData,
+ SocialProviderSettingsSupabase,
+ SocialProviderSetup,
+ SqlToRest,
+ StepHikeCompact,
+ Tabs,
+ TabPanel,
+ h2: (props: any) => (
+
+ {props.children}
+
+ ),
+ h3: (props: any) => (
+
+ {props.children}
+
+ ),
+ h4: (props: any) => (
+
+ {props.children}
+
+ ),
+}
+
+export { components }
diff --git a/apps/docs/features/docs/MdxBase.tsx b/apps/docs/features/docs/MdxBase.tsx
new file mode 100644
index 00000000000..9cb1e104ced
--- /dev/null
+++ b/apps/docs/features/docs/MdxBase.tsx
@@ -0,0 +1,57 @@
+import codeHikeTheme from 'config/code-hike.theme.json' assert { type: 'json' }
+import { remarkCodeHike, type CodeHikeConfig } from '@code-hike/mdx'
+import { type SerializeOptions } from 'next-mdx-remote/dist/types'
+import { MDXRemote } from 'next-mdx-remote/rsc'
+import { type ComponentProps } from 'react'
+import remarkGfm from 'remark-gfm'
+import rehypeKatex from 'rehype-katex'
+import remarkMath from 'remark-math'
+
+import { components } from '~/features/docs/MdxBase.shared'
+
+const codeHikeOptions: CodeHikeConfig = {
+ theme: codeHikeTheme,
+ lineNumbers: true,
+ showCopyButton: true,
+ skipLanguages: [],
+ autoImport: false,
+}
+
+const mdxOptions: SerializeOptions = {
+ mdxOptions: {
+ useDynamicImport: true,
+ remarkPlugins: [
+ [remarkMath, { singleDollarTextMath: false }],
+ remarkGfm,
+ [remarkCodeHike, codeHikeOptions],
+ ],
+ rehypePlugins: [rehypeKatex as any],
+ },
+}
+
+const MDXRemoteBase = ({ options = {}, ...props }: ComponentProps) => {
+ const { mdxOptions: { remarkPlugins, rehypePlugins, ...otherMdxOptions } = {}, ...otherOptions } =
+ options
+ const {
+ mdxOptions: {
+ remarkPlugins: originalRemarkPlugins,
+ rehypePlugins: originalRehypePlugins,
+ ...originalMdxOptions
+ } = {},
+ } = mdxOptions
+
+ const finalOptions = {
+ ...mdxOptions,
+ ...otherOptions,
+ mdxOptions: {
+ ...originalMdxOptions,
+ ...otherMdxOptions,
+ remarkPlugins: [...(originalRemarkPlugins ?? []), ...(remarkPlugins ?? [])],
+ rehypePlugins: [...(originalRehypePlugins ?? []), ...(rehypePlugins ?? [])],
+ },
+ } as SerializeOptions
+
+ return
+}
+
+export { MDXRemoteBase }
diff --git a/apps/docs/features/docs/Reference.typeSpec.test.ts b/apps/docs/features/docs/Reference.typeSpec.test.ts
new file mode 100644
index 00000000000..77eca1a1a74
--- /dev/null
+++ b/apps/docs/features/docs/Reference.typeSpec.test.ts
@@ -0,0 +1,21 @@
+import { describe, expect, it } from 'vitest'
+
+import { __parseTypeSpec } from './Reference.typeSpec'
+
+describe('TS type spec parsing', () => {
+ it('matches snapshot', async () => {
+ const parsed = await __parseTypeSpec()
+ const json = JSON.stringify(
+ parsed,
+ (key, value) => {
+ if (key === 'methods') {
+ return Object.fromEntries(value.entries())
+ } else {
+ return value
+ }
+ },
+ 2
+ )
+ expect(json).toMatchSnapshot()
+ })
+})
diff --git a/apps/docs/features/docs/Reference.typeSpec.ts b/apps/docs/features/docs/Reference.typeSpec.ts
new file mode 100644
index 00000000000..b7dc475a6de
--- /dev/null
+++ b/apps/docs/features/docs/Reference.typeSpec.ts
@@ -0,0 +1,655 @@
+/**
+ * Types and additional comments for the JavaScript library are found in the
+ * auto-generated TS typespec.
+ *
+ * The format of this typespec is difficult to walk, so we re-shape it for easy
+ * access to a function's type definition, given its name and module.
+ */
+
+import { join } from 'node:path'
+
+import { cache_fullProcess_withDevCacheBust } from '~/features/helpers.fs'
+import { SPEC_DIRECTORY } from '~/lib/docs'
+import _typeSpec from '~/spec/enrichments/tsdoc_v2/combined.json' assert { type: 'json' }
+
+// [Charis] 2024-07-10
+// Types are more trouble than they're worth here: manually defining the types
+// (correctly) is tedious, and inferring them will throw up a lot of type
+// errors. As long as everything is typed on the way out, and we code
+// defensively, it should be fine. Keep any unsafe type shenanigans isolated
+// to this file.
+const typeSpec = _typeSpec as any
+
+export const TYPESPEC_NODE_ANONYMOUS = Symbol('anonymous')
+
+/**
+ * Definitions for the methods and types defined in each Supabase JS client
+ * library.
+ */
+interface ModuleTypes {
+ name: string
+ methods: Map
+}
+
+/**
+ * Type definitions for a method (a function).
+ */
+export interface MethodTypes {
+ name: string | typeof TYPESPEC_NODE_ANONYMOUS
+ comment?: Comment
+ params: Array
+ ret: ReturnType | undefined
+}
+
+interface Comment {
+ shortText?: string
+ text?: string
+}
+
+interface ParamType {
+ name: string | typeof TYPESPEC_NODE_ANONYMOUS
+ comment?: Comment
+ isOptional?: boolean
+ type: Type | undefined
+}
+
+interface ReturnType {
+ type: Type | undefined
+}
+
+type Type = IntrinsicType | LiteralType | CustomType
+
+/**
+ * Type definition for an intrinsic (built-in) TypeScript type, for example,
+ * `string`, `boolean`.
+ */
+interface IntrinsicType {
+ type: 'intrinsic'
+ name?: string | typeof TYPESPEC_NODE_ANONYMOUS
+ comment?: Comment
+}
+
+interface LiteralType {
+ type: 'literal'
+ name?: string | typeof TYPESPEC_NODE_ANONYMOUS
+ comment?: Comment
+}
+
+type CustomType =
+ | NameOnlyType
+ | CustomObjectType
+ | CustomUnionType
+ | CustomFunctionType
+ | ArrayType
+ | RecordType
+ | IndexSignatureType
+ | PromiseType
+
+interface NameOnlyType {
+ type: 'nameOnly'
+ name: string | typeof TYPESPEC_NODE_ANONYMOUS
+}
+
+interface CustomObjectType {
+ type: 'customObject'
+ name?: string | typeof TYPESPEC_NODE_ANONYMOUS
+ comment?: Comment
+ properties: Array
+}
+
+interface CustomUnionType {
+ type: 'customUnion'
+ name?: string | typeof TYPESPEC_NODE_ANONYMOUS
+ comment?: Comment
+ subTypes: Array
+}
+
+interface CustomFunctionType {
+ type: 'function'
+ name?: string | typeof TYPESPEC_NODE_ANONYMOUS
+ comment?: Comment
+ params: Array
+ ret: ReturnType | undefined
+}
+
+interface ArrayType {
+ type: 'array'
+ name?: string | typeof TYPESPEC_NODE_ANONYMOUS
+ comment?: Comment
+ elemType: Type | undefined
+}
+
+interface RecordType {
+ type: 'record'
+ name?: string | typeof TYPESPEC_NODE_ANONYMOUS
+ comment?: Comment
+ keyType: Type | undefined
+ valueType: Type | undefined
+}
+
+interface IndexSignatureType {
+ type: 'index signature'
+ name?: string | typeof TYPESPEC_NODE_ANONYMOUS
+ comment?: Comment
+ keyType: Type | undefined
+ valueType: Type | undefined
+}
+
+interface PromiseType {
+ type: 'promise'
+ name?: string | typeof TYPESPEC_NODE_ANONYMOUS
+ comment?: Comment
+ awaited: Type | undefined
+}
+
+/**
+ * Type definition for a property on a custom type definition.
+ */
+interface PropertyType {
+ name?: string | typeof TYPESPEC_NODE_ANONYMOUS
+ comment?: Comment
+ isOptional?: boolean
+ type: Type | undefined
+}
+
+// The following is the API of this module, and the only externally exposed
+// piece. Given a reference to a function (method), return its type definition.
+
+/**
+ * Get the type definition for a function (a method).
+ *
+ * @param ref The method identifier, in the form `@supabase/supabase-js.index.SupabaseClient.constructor`.
+ */
+export async function getTypeSpec(ref: string) {
+ const modules = await parseTypeSpec()
+
+ const delimiter = ref.indexOf('.')
+ const refMod = ref.substring(0, delimiter)
+
+ const mod = modules.find((mod) => mod.name === refMod)
+ return mod?.methods.get(ref)
+}
+
+const parseTypeSpec = cache_fullProcess_withDevCacheBust(
+ __parseTypeSpec,
+ join(SPEC_DIRECTORY, 'enrichments/tsdoc_v2/combined.json'),
+ () => JSON.stringify([])
+)
+
+/**
+ * @private
+ * Exposed for testing purposes only, PRIVATE DO NOT USE externally.
+ */
+export function __parseTypeSpec() {
+ const modules = (typeSpec.children ?? []).map(parseMod)
+ return modules as Array
+}
+
+// Reading the type spec happens in several layers. The first layer is the
+// module: this corresponds roughly to the JS libraries for each product:
+// database, auth, storage, etc.
+
+function parseMod(mod: (typeof typeSpec)['children'][number]) {
+ const res: ModuleTypes = {
+ name: mod.name,
+ methods: new Map(),
+ }
+
+ // Build a map of nodes by their IDs for easy cross-referencing.
+ const targetMap = new Map()
+ buildMap(mod, targetMap)
+
+ parseModInternal(mod, targetMap, [], res)
+
+ return res
+}
+
+function buildMap(node: any, map: Map) {
+ if ('id' in node) {
+ map.set(node.id, node)
+ }
+ if ('children' in node) {
+ node.children.forEach((child: any) => buildMap(child, map))
+ }
+}
+
+// This layer is the top level of a module. Paths are tracked in this layer,
+// because they are needed to construct the $ref that will be used to reference
+// a specific type definition.
+
+function parseModInternal(
+ node: any,
+ map: Map,
+ currentPath: Array,
+ res: ModuleTypes
+) {
+ let updatedPath: Array
+
+ switch (node.kindString) {
+ case 'Module':
+ updatedPath = [...currentPath, node.name]
+ node.children?.forEach((child: any) => parseModInternal(child, map, updatedPath, res))
+ return
+ // Some libraries have undefined where others have Project for the same type
+ // of top-level node.
+ case 'Project':
+ case undefined:
+ updatedPath = [...currentPath, node.name]
+ node.children?.forEach((child: any) => parseModInternal(child, map, updatedPath, res))
+ case 'Class':
+ updatedPath = [...currentPath, node.name]
+ node.children?.forEach((child: any) => parseModInternal(child, map, updatedPath, res))
+ return
+ case 'Constructor':
+ parseConstructor(node, map, currentPath, res)
+ case 'Method':
+ parseMethod(node, map, currentPath, res)
+ case 'Interface':
+ updatedPath = [...currentPath, node.name]
+ node.children?.forEach((child: any) => parseModInternal(child, map, updatedPath, res))
+ case 'Property':
+ case 'Reference':
+ default:
+ return undefined
+ }
+}
+
+/**
+ * Get the name for a node, which may be delegated or missing (placeholders
+ * are prefaced by two `__` in the type spec). If missing, use the anonymous
+ * symbol.
+ */
+function nameOrAnonymous(nodes: any) {
+ if (!Array.isArray(nodes)) {
+ nodes = [nodes]
+ }
+
+ for (const node of nodes) {
+ if (node.name && !node.name.startsWith('__')) {
+ return node.name
+ }
+ }
+
+ return TYPESPEC_NODE_ANONYMOUS
+}
+
+function parseConstructor(
+ node: any,
+ map: Map,
+ currentPath: Array,
+ res: ModuleTypes
+) {
+ const $ref = `${currentPath.join('.')}.constructor`
+
+ const signature = node.signatures[0]
+ if (!signature) return
+
+ const { params, ret, comment } = parseSignature(signature, map)
+
+ const types: MethodTypes = {
+ name: $ref,
+ params,
+ ret,
+ comment,
+ }
+
+ res.methods.set($ref, types)
+}
+
+function parseMethod(
+ node: any,
+ map: Map,
+ currentPath: Array,
+ res: ModuleTypes
+) {
+ const $ref = `${currentPath.join('.')}.${node.name}`
+
+ const signature = node.signatures[0]
+ if (!signature) return
+
+ const { params, ret, comment } = parseSignature(signature, map)
+
+ const types: MethodTypes = {
+ name: $ref,
+ params,
+ ret,
+ comment,
+ }
+
+ res.methods.set($ref, types)
+}
+
+function parseSignature(
+ signature: any,
+ map: Map
+): { params: Array; ret: ReturnType; comment?: Comment } {
+ const params: Array = (signature.parameters ?? []).map((param: any) => {
+ const type = parseType(param.type, map)
+
+ const res: ParamType = {
+ name: nameOrAnonymous(param),
+ type,
+ }
+
+ if (param.flags?.isOptional) {
+ res.isOptional = true
+ }
+
+ if (param.comment) {
+ res.comment = param.comment
+ }
+
+ return res
+ })
+
+ let ret: ReturnType
+ if ('type' in signature) {
+ const retType = parseType(signature.type, map)
+ if (retType) {
+ ret = {
+ type: retType,
+ }
+ }
+ }
+
+ return {
+ params,
+ ret,
+ comment: signature.comment,
+ }
+}
+
+// This layer parses type definitions from the original typespec: these have
+// the format:
+//
+// ```
+// "type": {
+// "type": string,
+// "name": string
+// }
+// ```
+//
+// with additional properties depending on the type.
+
+function parseType(type: any, map: Map) {
+ switch (type.type) {
+ case 'literal':
+ return type
+ case 'intrinsic':
+ return type
+ case 'reference':
+ return parseReferenceType(type, map)
+ case 'array':
+ return parseArrayType(type, map)
+ case 'union':
+ return parseUnionType(type, map)
+ case 'reflection':
+ return parseReflectionType(type, map)
+ case 'indexedAccess':
+ return parseIndexedAccessType(type, map)
+ case 'typeOperator':
+ return parseTypeOperatorType(type, map)
+ default:
+ break
+ }
+
+ // Some nested types are wrapped in a kind node
+ switch (type.kindString) {
+ case 'Type alias':
+ if (typeof type.type === 'object') {
+ return parseType(type.type, map)
+ }
+ case 'Interface':
+ return parseInterface(type, map)
+ default:
+ break
+ }
+
+ return undefined
+}
+
+/**
+ * For a type that aliases its type definition to another node, delegate
+ * parsing to the referenced node, but use the name and comment from the
+ * original type.
+ */
+function delegateParsing(original: any, referenced: any, map: Map) {
+ const dereferencedType = parseType(referenced, map)
+
+ if (dereferencedType) {
+ dereferencedType.name = nameOrAnonymous([original, dereferencedType])
+ }
+
+ if (original.comment) {
+ dereferencedType.comment = {
+ ...dereferencedType.comment,
+ ...original.comment,
+ }
+ }
+
+ return dereferencedType
+}
+
+function parseReferenceType(type: any, map: Map) {
+ if (type.dereferenced?.type) {
+ return delegateParsing(type, type.dereferenced.type, map)
+ }
+
+ if (type.dereferenced?.kindString) {
+ return delegateParsing(type, type.dereferenced, map)
+ }
+
+ if (type.package === 'typescript' && type.qualifiedName === 'Record') {
+ return parseRecordType(type, map)
+ }
+
+ if (type.package === 'typescript' && type.qualifiedName === 'Promise') {
+ return parsePromiseType(type, map)
+ }
+
+ if (type.package && type.qualifiedName) {
+ return {
+ type: 'nameOnly',
+ name:
+ type.package === 'typescript'
+ ? type.qualifiedName
+ : `${type.package}.${type.qualifiedName}`,
+ }
+ }
+
+ if (type.name === 'default' && type.typeArguments?.[0]) {
+ return parseType(type.typeArguments[0], map)
+ }
+
+ // If we still haven't produced a meaningful type, try looking up the reference
+ const referenced = map.get(type.id)
+ if (referenced) {
+ const maybeType =
+ typeof referenced.type === 'object' && 'type' in referenced.type
+ ? /* need to go down a level */ delegateParsing(type, referenced.type, map)
+ : delegateParsing(type, referenced, map)
+
+ if (maybeType) {
+ return maybeType
+ }
+ }
+
+ // Final fallback
+ if (type.name && type.name !== 'default' /* Not particularly meaningful */) {
+ return {
+ type: 'nameOnly',
+ name: type.name,
+ }
+ }
+
+ return undefined
+}
+
+function parseArrayType(type: any, map: Map): ArrayType {
+ const elemType = parseType(type.elementType, map)
+
+ return {
+ type: 'array',
+ name: nameOrAnonymous(type),
+ elemType,
+ }
+}
+
+function parseUnionType(type: any, map: Map): CustomUnionType {
+ // Need the Boolean filter because there are nulls in some of the nodes
+ const subTypes = type.types.filter(Boolean).map((type) => parseType(type, map))
+
+ return {
+ type: 'customUnion',
+ name: nameOrAnonymous(type),
+ subTypes,
+ }
+}
+
+function parseRecordType(type: any, map: Map): RecordType {
+ const [keyType, valueType] = (type.typeArguments ?? []).map((type) => parseType(type, map))
+
+ return {
+ type: 'record',
+ name: nameOrAnonymous(type),
+ keyType,
+ valueType,
+ }
+}
+
+function parsePromiseType(type: any, map: Map): PromiseType {
+ return {
+ type: 'promise',
+ name: nameOrAnonymous(type),
+ awaited: type.typeArguments?.[0] ? parseType(type.typeArguments[0], map) : undefined,
+ }
+}
+
+function parseReflectionType(type: any, map: Map) {
+ if (!type.declaration) return undefined
+
+ let res: Type
+ switch (type.declaration.kindString) {
+ case 'Type literal':
+ res = parseTypeLiteral(type, map)
+ break
+ default:
+ break
+ }
+
+ return res
+}
+
+function parseTypeLiteral(type: any, map: Map): Type {
+ const name = nameOrAnonymous(type)
+
+ if ('children' in type.declaration) {
+ const properties = type.declaration.children.map((child: any) => parseTypeInternals(child, map))
+ return {
+ name,
+ type: 'customObject',
+ properties,
+ } satisfies CustomObjectType
+ }
+
+ if ('signatures' in type.declaration && type.declaration.signatures[0]) {
+ const { params, ret, comment } = parseSignature(type.declaration.signatures[0], map)
+ return {
+ name,
+ type: 'function',
+ params,
+ ret,
+ comment,
+ }
+ }
+
+ if ('indexSignature' in type.declaration) {
+ const signature = type.declaration.indexSignature
+
+ return {
+ name,
+ type: 'index signature',
+ keyType: signature.parameters?.[0]
+ ? parseType(signature.parameters?.[0].type, map)
+ : undefined,
+ valueType: signature.type ? parseType(signature.type, map) : undefined,
+ }
+ }
+
+ return undefined
+}
+
+function parseIndexedAccessType(type: any, map: Map) {
+ return {
+ type: 'nameOnly',
+ name: `${type.objectType?.name ?? ''}[${type.indexType.value ?? type.indexType.name ?? ''}]`,
+ }
+}
+
+function parseTypeOperatorType(type: any, map: Map) {
+ switch (type.operator) {
+ case 'readonly':
+ return parseType(type.target, map)
+ default:
+ return undefined
+ }
+}
+
+function parseInterface(type: any, map: Map): CustomObjectType {
+ const properties = (type.children ?? []).map((child) => parseTypeInternals(child, map))
+
+ return {
+ type: 'customObject',
+ name: nameOrAnonymous(type),
+ properties,
+ }
+}
+
+// This layer is for the sub-types that define a custom type, for example, the
+// properties of an interface.
+
+function parseTypeInternals(elem: any, map: Map) {
+ switch (elem.kindString) {
+ case 'Property':
+ return parseInternalProperty(elem, map)
+ case 'Method':
+ if (elem.signatures?.[0]) {
+ const { params, ret, comment } = parseSignature(elem.signatures?.[0], map)
+ const res = {
+ type: 'function',
+ name: nameOrAnonymous(elem),
+ params,
+ ret,
+ comment,
+ } as CustomFunctionType
+
+ if (elem.comment) {
+ res.comment = { ...res.comment, ...elem.comment }
+ }
+
+ return res
+ }
+ default:
+ return undefined
+ }
+}
+
+function parseInternalProperty(elem: any, map: Map) {
+ const name = nameOrAnonymous(elem)
+ const type = parseType(elem.type, map)
+
+ const res = {
+ name,
+ type,
+ } as PropertyType
+
+ if (elem.flags?.isOptional) {
+ res.isOptional = true
+ }
+
+ if (elem.comment) {
+ res.comment = elem.comment
+ }
+
+ return res
+}
diff --git a/apps/docs/features/docs/__snapshots__/Reference.typeSpec.test.ts.snap b/apps/docs/features/docs/__snapshots__/Reference.typeSpec.test.ts.snap
new file mode 100644
index 00000000000..1d02bea96e6
--- /dev/null
+++ b/apps/docs/features/docs/__snapshots__/Reference.typeSpec.test.ts.snap
@@ -0,0 +1,28574 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`TS type spec parsing > matches snapshot 1`] = `
+"[
+ {
+ "name": "@supabase/supabase-js",
+ "methods": {
+ "@supabase/supabase-js.index.SupabaseClient.constructor": {
+ "name": "@supabase/supabase-js.index.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": "customObject",
+ "properties": [
+ {
+ "name": "auth",
+ "type": {
+ "type": "customObject",
+ "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": "intrinsic",
+ "name": "boolean"
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "Detect a session from the URL. Used for OAuth login callbacks. Defaults to true."
+ }
+ },
+ {
+ "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 no locking is done at this time.",
+ "tags": [
+ {
+ "tag": "experimental",
+ "text": "\\n"
+ }
+ ]
+ }
+ },
+ {
+ "name": "persistSession",
+ "type": {
+ "type": "intrinsic",
+ "name": "boolean"
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "Whether to persist a logged-in session to storage. Defaults to true."
+ }
+ },
+ {
+ "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."
+ }
+ }
+ ]
+ },
+ "isOptional": true
+ },
+ {
+ "name": "db",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "schema",
+ "type": {
+ "type": "nameOnly",
+ "name": "SchemaName"
+ },
+ "isOptional": true
+ }
+ ]
+ },
+ "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": "customObject",
+ "properties": [
+ {
+ "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": {
+ "type": "nameOnly",
+ "name": "@supabase/realtime-js.RealtimeClientOptions"
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "Options passed to the realtime-js instance"
+ }
+ }
+ ]
+ },
+ "isOptional": true
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Database"
+ }
+ },
+ "comment": {
+ "shortText": "Create a new client for use in the browser."
+ }
+ },
+ "@supabase/supabase-js.index.SupabaseClient._getAccessToken": {
+ "name": "@supabase/supabase-js.index.SupabaseClient._getAccessToken",
+ "params": [],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": null
+ },
+ {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ ]
+ }
+ }
+ }
+ },
+ "@supabase/supabase-js.index.SupabaseClient._handleTokenChanged": {
+ "name": "@supabase/supabase-js.index.SupabaseClient._handleTokenChanged",
+ "params": [
+ {
+ "name": "event",
+ "type": {
+ "type": "nameOnly",
+ "name": "@supabase/auth-js.AuthChangeEvent"
+ }
+ },
+ {
+ "name": "source",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "CLIENT"
+ },
+ {
+ "type": "literal",
+ "value": "STORAGE"
+ }
+ ]
+ }
+ },
+ {
+ "name": "token",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "intrinsic",
+ "name": "void"
+ }
+ }
+ },
+ "@supabase/supabase-js.index.SupabaseClient._initRealtimeClient": {
+ "name": "@supabase/supabase-js.index.SupabaseClient._initRealtimeClient",
+ "params": [
+ {
+ "name": "options",
+ "type": {
+ "type": "nameOnly",
+ "name": "@supabase/realtime-js.RealtimeClientOptions"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "@supabase/realtime-js.RealtimeClient"
+ }
+ }
+ },
+ "@supabase/supabase-js.index.SupabaseClient._initSupabaseAuthClient": {
+ "name": "@supabase/supabase-js.index.SupabaseClient._initSupabaseAuthClient",
+ "params": [
+ {
+ "type": {
+ "type": "customObject",
+ "name": "SupabaseAuthClientOptions",
+ "properties": []
+ }
+ },
+ {
+ "name": "headers",
+ "type": {
+ "type": "record",
+ "name": "Record",
+ "keyType": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "valueType": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ "isOptional": true
+ },
+ {
+ "name": "fetch",
+ "type": {
+ "type": "function",
+ "params": [
+ {
+ "name": "input",
+ "type": {
+ "type": "customUnion",
+ "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"
+ }
+ }
+ }
+ },
+ "isOptional": true
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "SupabaseAuthClient"
+ }
+ }
+ },
+ "@supabase/supabase-js.index.SupabaseClient._listenForAuthEvents": {
+ "name": "@supabase/supabase-js.index.SupabaseClient._listenForAuthEvents",
+ "params": []
+ },
+ "@supabase/supabase-js.index.SupabaseClient.channel": {
+ "name": "@supabase/supabase-js.index.SupabaseClient.channel",
+ "params": [
+ {
+ "name": "name",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "The name of the Realtime channel."
+ }
+ },
+ {
+ "name": "opts",
+ "type": {
+ "type": "nameOnly",
+ "name": "@supabase/realtime-js.RealtimeChannelOptions"
+ },
+ "comment": {
+ "shortText": "The options to pass to the Realtime channel.\\n\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "@supabase/realtime-js.RealtimeChannel"
+ }
+ },
+ "comment": {
+ "shortText": "Creates a Realtime channel with Broadcast, Presence, and Postgres Changes."
+ }
+ },
+ "@supabase/supabase-js.index.SupabaseClient.from": {
+ "name": "@supabase/supabase-js.index.SupabaseClient.from",
+ "params": [
+ {
+ "name": "relation",
+ "type": {
+ "type": "nameOnly",
+ "name": "TableName"
+ },
+ "comment": {
+ "shortText": "The table or view name to query\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "@supabase/postgrest-js.PostgrestQueryBuilder"
+ }
+ },
+ "comment": {
+ "shortText": "Perform a query on a table or a view."
+ }
+ },
+ "@supabase/supabase-js.index.SupabaseClient.getChannels": {
+ "name": "@supabase/supabase-js.index.SupabaseClient.getChannels",
+ "params": [],
+ "ret": {
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "nameOnly",
+ "name": "@supabase/realtime-js.RealtimeChannel"
+ }
+ }
+ },
+ "comment": {
+ "shortText": "Returns all Realtime channels."
+ }
+ },
+ "@supabase/supabase-js.index.SupabaseClient.removeAllChannels": {
+ "name": "@supabase/supabase-js.index.SupabaseClient.removeAllChannels",
+ "params": [],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "array",
+ "elemType": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "error"
+ },
+ {
+ "type": "literal",
+ "value": "ok"
+ },
+ {
+ "type": "literal",
+ "value": "timed out"
+ }
+ ]
+ }
+ }
+ }
+ },
+ "comment": {
+ "shortText": "Unsubscribes and removes all Realtime channels from Realtime client."
+ }
+ },
+ "@supabase/supabase-js.index.SupabaseClient.removeChannel": {
+ "name": "@supabase/supabase-js.index.SupabaseClient.removeChannel",
+ "params": [
+ {
+ "name": "channel",
+ "type": {
+ "type": "nameOnly",
+ "name": "@supabase/realtime-js.RealtimeChannel"
+ },
+ "comment": {
+ "shortText": "The name of the Realtime channel.\\n\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "error"
+ },
+ {
+ "type": "literal",
+ "value": "ok"
+ },
+ {
+ "type": "literal",
+ "value": "timed out"
+ }
+ ]
+ }
+ }
+ },
+ "comment": {
+ "shortText": "Unsubscribes and removes Realtime channel from Realtime client."
+ }
+ },
+ "@supabase/supabase-js.index.SupabaseClient.rpc": {
+ "name": "@supabase/supabase-js.index.SupabaseClient.rpc",
+ "params": [
+ {
+ "name": "fn",
+ "type": {
+ "type": "nameOnly",
+ "name": "FnName"
+ },
+ "comment": {
+ "shortText": "The function name to call"
+ }
+ },
+ {
+ "name": "args",
+ "type": {
+ "type": "nameOnly",
+ "name": "Fn[Args]"
+ },
+ "comment": {
+ "shortText": "The arguments to pass to the function call"
+ }
+ },
+ {
+ "name": "options",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "count",
+ "type": {
+ "type": "customUnion",
+ "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.\\n"
+ }
+ },
+ {
+ "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": "@supabase/postgrest-js.PostgrestFilterBuilder"
+ }
+ },
+ "comment": {
+ "shortText": "Perform a function call."
+ }
+ },
+ "@supabase/supabase-js.index.SupabaseClient.schema": {
+ "name": "@supabase/supabase-js.index.SupabaseClient.schema",
+ "params": [
+ {
+ "name": "schema",
+ "type": {
+ "type": "nameOnly",
+ "name": "DynamicSchema"
+ },
+ "comment": {
+ "shortText": "The schema to query\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "@supabase/postgrest-js.PostgrestClient"
+ }
+ },
+ "comment": {
+ "shortText": "Select a schema to query or perform an function (rpc) call.",
+ "text": "The schema needs to be on the list of exposed schemas inside Supabase.\\n"
+ }
+ }
+ }
+ },
+ {
+ "name": "@supabase/auth-js",
+ "methods": {
+ "@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"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "AuthApiError"
+ }
+ }
+ },
+ "@supabase/auth-js.AuthApiError.toJSON": {
+ "name": "@supabase/auth-js.AuthApiError.toJSON",
+ "params": [],
+ "ret": {
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "message",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "name",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "status",
+ "type": {
+ "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
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "AuthError"
+ }
+ }
+ },
+ "@supabase/auth-js.AuthImplicitGrantRedirectError.constructor": {
+ "name": "@supabase/auth-js.AuthImplicitGrantRedirectError.constructor",
+ "params": [
+ {
+ "name": "message",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "details",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": null
+ },
+ {
+ "type": "customObject",
+ "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": "customObject",
+ "properties": [
+ {
+ "name": "details",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": null
+ },
+ {
+ "type": "customObject",
+ "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": "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": "customObject",
+ "properties": [
+ {
+ "name": "message",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "name",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "status",
+ "type": {
+ "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": "customObject",
+ "properties": [
+ {
+ "name": "message",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "name",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "status",
+ "type": {
+ "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": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": null
+ },
+ {
+ "type": "customObject",
+ "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": "customObject",
+ "properties": [
+ {
+ "name": "details",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": null
+ },
+ {
+ "type": "customObject",
+ "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": "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": "customObject",
+ "properties": [
+ {
+ "name": "message",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "name",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "status",
+ "type": {
+ "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": "customObject",
+ "properties": [
+ {
+ "name": "message",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "name",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "status",
+ "type": {
+ "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.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": "intrinsic",
+ "name": "string"
+ }
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "AuthWeakPasswordError"
+ }
+ }
+ },
+ "@supabase/auth-js.AuthWeakPasswordError.toJSON": {
+ "name": "@supabase/auth-js.AuthWeakPasswordError.toJSON",
+ "params": [],
+ "ret": {
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "message",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "name",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "status",
+ "type": {
+ "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"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "CustomAuthError"
+ }
+ }
+ },
+ "@supabase/auth-js.CustomAuthError.toJSON": {
+ "name": "@supabase/auth-js.CustomAuthError.toJSON",
+ "params": [],
+ "ret": {
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "message",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "name",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "status",
+ "type": {
+ "type": "intrinsic",
+ "name": "number"
+ }
+ }
+ ]
+ }
+ }
+ },
+ "@supabase/auth-js.GoTrueAdminApi.constructor": {
+ "name": "@supabase/auth-js.GoTrueAdminApi.constructor",
+ "params": [
+ {
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "fetch",
+ "type": {
+ "type": "function",
+ "params": [
+ {
+ "name": "input",
+ "type": {
+ "type": "customUnion",
+ "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"
+ }
+ }
+ }
+ },
+ "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"
+ }
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "@supabase/auth-js.GoTrueAdminApi.createUser": {
+ "name": "@supabase/auth-js.GoTrueAdminApi.createUser",
+ "params": [
+ {
+ "name": "attributes",
+ "type": {
+ "type": "customObject",
+ "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.",
+ "text": "Only 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.\\n"
+ }
+ },
+ {
+ "name": "ban_duration",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "Determines how long a user is banned for.",
+ "text": "The 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.\\n"
+ }
+ },
+ {
+ "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": "Confirms the user's email address if set to true.",
+ "text": "Only a service role can modify.\\n"
+ }
+ },
+ {
+ "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.",
+ "text": "Call reauthenticate() to obtain the nonce first.\\n"
+ }
+ },
+ {
+ "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": "phone_confirm",
+ "type": {
+ "type": "intrinsic",
+ "name": "boolean"
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "Confirms the user's phone number if set to true.",
+ "text": "Only a service role can modify.\\n"
+ }
+ },
+ {
+ "name": "role",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "The \`role\` claim set in the user's access token JWT.",
+ "text": "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.\\n\\nSetting this role to \`service_role\` is not recommended as it grants the user admin privileges.\\n"
+ }
+ },
+ {
+ "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.",
+ "text": "The \`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.\\n\\n"
+ }
+ }
+ ]
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "name": "UserResponse",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "user",
+ "type": {
+ "type": "customObject",
+ "name": "User",
+ "properties": [
+ {
+ "name": "action_link",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "app_metadata",
+ "type": {
+ "type": "customObject",
+ "name": "UserAppMetadata",
+ "properties": [
+ {
+ "name": "provider",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "aud",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "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": "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": "customObject",
+ "name": "Factor",
+ "properties": [
+ {
+ "name": "created_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "factor_type",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "Type of factor. Only \`totp\` supported with this version but may change in\\nfuture versions."
+ }
+ },
+ {
+ "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": "status",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "verified"
+ },
+ {
+ "type": "literal",
+ "value": "unverified"
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "Factor's status."
+ }
+ },
+ {
+ "name": "updated_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ "isOptional": true
+ },
+ {
+ "name": "id",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "identities",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "customObject",
+ "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": "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": "customObject",
+ "name": "UserMetadata",
+ "properties": []
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "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."
+ }
+ },
+ "@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 (setting \`deleted_at\` to the current timestamp and disabling their account while preserving their data) from the auth schema.\\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.\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "name": "UserResponse",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "user",
+ "type": {
+ "type": "customObject",
+ "name": "User",
+ "properties": [
+ {
+ "name": "action_link",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "app_metadata",
+ "type": {
+ "type": "customObject",
+ "name": "UserAppMetadata",
+ "properties": [
+ {
+ "name": "provider",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "aud",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "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": "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": "customObject",
+ "name": "Factor",
+ "properties": [
+ {
+ "name": "created_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "factor_type",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "Type of factor. Only \`totp\` supported with this version but may change in\\nfuture versions."
+ }
+ },
+ {
+ "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": "status",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "verified"
+ },
+ {
+ "type": "literal",
+ "value": "unverified"
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "Factor's status."
+ }
+ },
+ {
+ "name": "updated_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ "isOptional": true
+ },
+ {
+ "name": "id",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "identities",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "customObject",
+ "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": "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": "customObject",
+ "name": "UserMetadata",
+ "properties": []
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "user",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "nameOnly",
+ "name": "AuthError"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ "comment": {
+ "shortText": "Delete a user. Requires a \`service_role\` key."
+ }
+ },
+ "@supabase/auth-js.GoTrueAdminApi.generateLink": {
+ "name": "@supabase/auth-js.GoTrueAdminApi.generateLink",
+ "params": [
+ {
+ "name": "params",
+ "type": {
+ "type": "customUnion",
+ "name": "GenerateLinkParams",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "email",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "options",
+ "type": {
+ "type": "nameOnly",
+ "name": "Pick"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "password",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "type",
+ "type": {
+ "type": "literal",
+ "value": "signup"
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "email",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "The user's email"
+ }
+ },
+ {
+ "name": "options",
+ "type": {
+ "type": "nameOnly",
+ "name": "Pick"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "type",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "invite"
+ },
+ {
+ "type": "literal",
+ "value": "magiclink"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "email",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "The user's email"
+ }
+ },
+ {
+ "name": "options",
+ "type": {
+ "type": "nameOnly",
+ "name": "Pick"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "type",
+ "type": {
+ "type": "literal",
+ "value": "recovery"
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "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",
+ "type": {
+ "type": "nameOnly",
+ "name": "Pick"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "type",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "email_change_current"
+ },
+ {
+ "type": "literal",
+ "value": "email_change_new"
+ }
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "name": "GenerateLinkResponse",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "properties",
+ "type": {
+ "name": "GenerateLinkProperties",
+ "type": "customObject",
+ "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": "customUnion",
+ "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": "customObject",
+ "name": "User",
+ "properties": [
+ {
+ "name": "action_link",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "app_metadata",
+ "type": {
+ "type": "customObject",
+ "name": "UserAppMetadata",
+ "properties": [
+ {
+ "name": "provider",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "aud",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "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": "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": "customObject",
+ "name": "Factor",
+ "properties": [
+ {
+ "name": "created_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "factor_type",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "Type of factor. Only \`totp\` supported with this version but may change in\\nfuture versions."
+ }
+ },
+ {
+ "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": "status",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "verified"
+ },
+ {
+ "type": "literal",
+ "value": "unverified"
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "Factor's status."
+ }
+ },
+ {
+ "name": "updated_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ "isOptional": true
+ },
+ {
+ "name": "id",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "identities",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "customObject",
+ "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": "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": "customObject",
+ "name": "UserMetadata",
+ "properties": []
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "properties",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ },
+ {
+ "name": "user",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "nameOnly",
+ "name": "AuthError"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ "comment": {
+ "shortText": "Generates email links and OTPs to be sent via a custom email provider."
+ }
+ },
+ "@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.\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "name": "UserResponse",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "user",
+ "type": {
+ "type": "customObject",
+ "name": "User",
+ "properties": [
+ {
+ "name": "action_link",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "app_metadata",
+ "type": {
+ "type": "customObject",
+ "name": "UserAppMetadata",
+ "properties": [
+ {
+ "name": "provider",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "aud",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "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": "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": "customObject",
+ "name": "Factor",
+ "properties": [
+ {
+ "name": "created_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "factor_type",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "Type of factor. Only \`totp\` supported with this version but may change in\\nfuture versions."
+ }
+ },
+ {
+ "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": "status",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "verified"
+ },
+ {
+ "type": "literal",
+ "value": "unverified"
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "Factor's status."
+ }
+ },
+ {
+ "name": "updated_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ "isOptional": true
+ },
+ {
+ "name": "id",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "identities",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "customObject",
+ "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": "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": "customObject",
+ "name": "UserMetadata",
+ "properties": []
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "user",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "nameOnly",
+ "name": "AuthError"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ "comment": {
+ "shortText": "Get user by id."
+ }
+ },
+ "@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": "customObject",
+ "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.\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "name": "UserResponse",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "user",
+ "type": {
+ "type": "customObject",
+ "name": "User",
+ "properties": [
+ {
+ "name": "action_link",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "app_metadata",
+ "type": {
+ "type": "customObject",
+ "name": "UserAppMetadata",
+ "properties": [
+ {
+ "name": "provider",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "aud",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "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": "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": "customObject",
+ "name": "Factor",
+ "properties": [
+ {
+ "name": "created_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "factor_type",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "Type of factor. Only \`totp\` supported with this version but may change in\\nfuture versions."
+ }
+ },
+ {
+ "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": "status",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "verified"
+ },
+ {
+ "type": "literal",
+ "value": "unverified"
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "Factor's status."
+ }
+ },
+ {
+ "name": "updated_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ "isOptional": true
+ },
+ {
+ "name": "id",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "identities",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "customObject",
+ "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": "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": "customObject",
+ "name": "UserMetadata",
+ "properties": []
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "user",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "nameOnly",
+ "name": "AuthError"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ "comment": {
+ "shortText": "Sends an invite link to an email address."
+ }
+ },
+ "@supabase/auth-js.GoTrueAdminApi.listUsers": {
+ "name": "@supabase/auth-js.GoTrueAdminApi.listUsers",
+ "params": [
+ {
+ "name": "params",
+ "type": {
+ "name": "PageParams",
+ "type": "customObject",
+ "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.\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data"
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "users"
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "nameOnly",
+ "name": "AuthError"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ "comment": {
+ "shortText": "Get a list of users.",
+ "text": "This function should only be called on a server. Never expose your \`service_role\` key in the browser."
+ }
+ },
+ "@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": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "global"
+ },
+ {
+ "type": "literal",
+ "value": "local"
+ },
+ {
+ "type": "literal",
+ "value": "others"
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "The logout sope.\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "customUnion",
+ "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"
+ }
+ },
+ {
+ "name": "attributes",
+ "type": {
+ "type": "customObject",
+ "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.",
+ "text": "Only 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.\\n"
+ }
+ },
+ {
+ "name": "ban_duration",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "Determines how long a user is banned for.",
+ "text": "The 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.\\n"
+ }
+ },
+ {
+ "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": "Confirms the user's email address if set to true.",
+ "text": "Only a service role can modify.\\n"
+ }
+ },
+ {
+ "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.",
+ "text": "Call reauthenticate() to obtain the nonce first.\\n"
+ }
+ },
+ {
+ "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": "phone_confirm",
+ "type": {
+ "type": "intrinsic",
+ "name": "boolean"
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "Confirms the user's phone number if set to true.",
+ "text": "Only a service role can modify.\\n"
+ }
+ },
+ {
+ "name": "role",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "The \`role\` claim set in the user's access token JWT.",
+ "text": "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.\\n\\nSetting this role to \`service_role\` is not recommended as it grants the user admin privileges.\\n"
+ }
+ },
+ {
+ "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.",
+ "text": "The \`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.\\n\\n"
+ }
+ }
+ ]
+ },
+ "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.\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "name": "UserResponse",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "user",
+ "type": {
+ "type": "customObject",
+ "name": "User",
+ "properties": [
+ {
+ "name": "action_link",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "app_metadata",
+ "type": {
+ "type": "customObject",
+ "name": "UserAppMetadata",
+ "properties": [
+ {
+ "name": "provider",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "aud",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "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": "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": "customObject",
+ "name": "Factor",
+ "properties": [
+ {
+ "name": "created_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "factor_type",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "Type of factor. Only \`totp\` supported with this version but may change in\\nfuture versions."
+ }
+ },
+ {
+ "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": "status",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "verified"
+ },
+ {
+ "type": "literal",
+ "value": "unverified"
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "Factor's status."
+ }
+ },
+ {
+ "name": "updated_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ "isOptional": true
+ },
+ {
+ "name": "id",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "identities",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "customObject",
+ "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": "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": "customObject",
+ "name": "UserMetadata",
+ "properties": []
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "user",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "nameOnly",
+ "name": "AuthError"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ "comment": {
+ "shortText": "Updates the user data."
+ }
+ },
+ "@supabase/auth-js.GoTrueClient.constructor": {
+ "name": "@supabase/auth-js.GoTrueClient.constructor",
+ "params": [
+ {
+ "name": "options",
+ "type": {
+ "name": "GoTrueClientOptions",
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "autoRefreshToken",
+ "type": {
+ "type": "intrinsic",
+ "name": "boolean"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "debug",
+ "type": {
+ "type": "customUnion",
+ "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": "intrinsic",
+ "name": "boolean"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "fetch",
+ "type": {
+ "type": "nameOnly",
+ "name": "Fetch"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "flowType",
+ "type": {
+ "type": "customUnion",
+ "name": "AuthFlowType",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "implicit"
+ },
+ {
+ "type": "literal",
+ "value": "pkce"
+ }
+ ]
+ },
+ "isOptional": true
+ },
+ {
+ "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.\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "nameOnly",
+ "name": "R"
+ }
+ }
+ },
+ "comment": {
+ "shortText": "Provide your own global lock implementation instead of the default\\nimplementation. The function should acquire a lock for the duration of the\\n\`fn\` async function, such that no other client instances will be able to\\nhold it at the same time.",
+ "tags": [
+ {
+ "tag": "experimental",
+ "text": "\\n"
+ }
+ ]
+ }
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "Provide your own locking mechanism based on the environment. By default no locking is done at this time.",
+ "tags": [
+ {
+ "tag": "experimental",
+ "text": "\\n"
+ }
+ ]
+ }
+ },
+ {
+ "name": "persistSession",
+ "type": {
+ "type": "intrinsic",
+ "name": "boolean"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "storage",
+ "isOptional": true
+ },
+ {
+ "name": "storageKey",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "url",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ }
+ ]
+ }
+ }
+ ],
+ "comment": {
+ "shortText": "Create a new client for use in the browser."
+ }
+ },
+ "@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": "customUnion",
+ "name": "AuthTokenResponse",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "session",
+ "type": {
+ "type": "customObject",
+ "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": "customUnion",
+ "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": "customUnion",
+ "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": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "user",
+ "type": {
+ "type": "customObject",
+ "name": "User",
+ "properties": [
+ {
+ "name": "action_link",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "app_metadata",
+ "type": {
+ "type": "customObject",
+ "name": "UserAppMetadata",
+ "properties": [
+ {
+ "name": "provider",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "aud",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "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": "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": "customObject",
+ "name": "Factor",
+ "properties": [
+ {
+ "name": "created_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "factor_type",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "Type of factor. Only \`totp\` supported with this version but may change in\\nfuture versions."
+ }
+ },
+ {
+ "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": "status",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "verified"
+ },
+ {
+ "type": "literal",
+ "value": "unverified"
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "Factor's status."
+ }
+ },
+ {
+ "name": "updated_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ "isOptional": true
+ },
+ {
+ "name": "id",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "identities",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "customObject",
+ "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": "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": "customObject",
+ "name": "UserMetadata",
+ "properties": []
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "user",
+ "type": {
+ "type": "customObject",
+ "name": "User",
+ "properties": [
+ {
+ "name": "action_link",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "app_metadata",
+ "type": {
+ "type": "customObject",
+ "name": "UserAppMetadata",
+ "properties": [
+ {
+ "name": "provider",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "aud",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "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": "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": "customObject",
+ "name": "Factor",
+ "properties": [
+ {
+ "name": "created_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "factor_type",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "Type of factor. Only \`totp\` supported with this version but may change in\\nfuture versions."
+ }
+ },
+ {
+ "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": "status",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "verified"
+ },
+ {
+ "type": "literal",
+ "value": "unverified"
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "Factor's status."
+ }
+ },
+ {
+ "name": "updated_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ "isOptional": true
+ },
+ {
+ "name": "id",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "identities",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "customObject",
+ "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": "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": "customObject",
+ "name": "UserMetadata",
+ "properties": []
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "session",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ },
+ {
+ "name": "user",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "nameOnly",
+ "name": "AuthError"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ "comment": {
+ "shortText": "Log in an existing user by exchanging an Auth Code issued during the PKCE flow."
+ }
+ },
+ "@supabase/auth-js.GoTrueClient.getSession": {
+ "name": "@supabase/auth-js.GoTrueClient.getSession",
+ "params": [],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "session",
+ "type": {
+ "type": "customObject",
+ "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": "customUnion",
+ "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": "customUnion",
+ "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": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "user",
+ "type": {
+ "type": "customObject",
+ "name": "User",
+ "properties": [
+ {
+ "name": "action_link",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "app_metadata",
+ "type": {
+ "type": "customObject",
+ "name": "UserAppMetadata",
+ "properties": [
+ {
+ "name": "provider",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "aud",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "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": "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": "customObject",
+ "name": "Factor",
+ "properties": [
+ {
+ "name": "created_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "factor_type",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "Type of factor. Only \`totp\` supported with this version but may change in\\nfuture versions."
+ }
+ },
+ {
+ "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": "status",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "verified"
+ },
+ {
+ "type": "literal",
+ "value": "unverified"
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "Factor's status."
+ }
+ },
+ {
+ "name": "updated_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ "isOptional": true
+ },
+ {
+ "name": "id",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "identities",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "customObject",
+ "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": "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": "customObject",
+ "name": "UserMetadata",
+ "properties": []
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "session",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "nameOnly",
+ "name": "AuthError"
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "session",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ "comment": {
+ "shortText": "Returns the session, refreshing it if necessary.",
+ "text": "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.\\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 {@link #getUser()} instead.\\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.\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "name": "UserResponse",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "user",
+ "type": {
+ "type": "customObject",
+ "name": "User",
+ "properties": [
+ {
+ "name": "action_link",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "app_metadata",
+ "type": {
+ "type": "customObject",
+ "name": "UserAppMetadata",
+ "properties": [
+ {
+ "name": "provider",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "aud",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "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": "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": "customObject",
+ "name": "Factor",
+ "properties": [
+ {
+ "name": "created_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "factor_type",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "Type of factor. Only \`totp\` supported with this version but may change in\\nfuture versions."
+ }
+ },
+ {
+ "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": "status",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "verified"
+ },
+ {
+ "type": "literal",
+ "value": "unverified"
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "Factor's status."
+ }
+ },
+ {
+ "name": "updated_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ "isOptional": true
+ },
+ {
+ "name": "id",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "identities",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "customObject",
+ "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": "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": "customObject",
+ "name": "UserMetadata",
+ "properties": []
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "user",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ }
+ },
+ {
+ "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."
+ }
+ },
+ "@supabase/auth-js.GoTrueClient.getUserIdentities": {
+ "name": "@supabase/auth-js.GoTrueClient.getUserIdentities",
+ "params": [],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "identities",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "customObject",
+ "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"
+ }
+ }
+ ]
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "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."
+ }
+ },
+ "@supabase/auth-js.GoTrueClient.initialize": {
+ "name": "@supabase/auth-js.GoTrueClient.initialize",
+ "params": [],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "name": "InitializeResult",
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "error",
+ "type": {
+ "type": "customUnion",
+ "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.linkIdentity": {
+ "name": "@supabase/auth-js.GoTrueClient.linkIdentity",
+ "params": [
+ {
+ "name": "credentials",
+ "type": {
+ "name": "SignInWithOAuthCredentials",
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "options",
+ "type": {
+ "type": "customObject",
+ "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": "customUnion",
+ "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": "spotify"
+ },
+ {
+ "type": "literal",
+ "value": "twitch"
+ },
+ {
+ "type": "literal",
+ "value": "twitter"
+ },
+ {
+ "type": "literal",
+ "value": "workos"
+ },
+ {
+ "type": "literal",
+ "value": "zoom"
+ },
+ {
+ "type": "literal",
+ "value": "fly"
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "One of the providers supported by GoTrue."
+ }
+ }
+ ]
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "name": "OAuthResponse",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "provider",
+ "type": {
+ "type": "customUnion",
+ "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": "spotify"
+ },
+ {
+ "type": "literal",
+ "value": "twitch"
+ },
+ {
+ "type": "literal",
+ "value": "twitter"
+ },
+ {
+ "type": "literal",
+ "value": "workos"
+ },
+ {
+ "type": "literal",
+ "value": "zoom"
+ },
+ {
+ "type": "literal",
+ "value": "fly"
+ }
+ ]
+ }
+ },
+ {
+ "name": "url",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "provider",
+ "type": {
+ "type": "customUnion",
+ "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": "spotify"
+ },
+ {
+ "type": "literal",
+ "value": "twitch"
+ },
+ {
+ "type": "literal",
+ "value": "twitter"
+ },
+ {
+ "type": "literal",
+ "value": "workos"
+ },
+ {
+ "type": "literal",
+ "value": "zoom"
+ },
+ {
+ "type": "literal",
+ "value": "fly"
+ }
+ ]
+ }
+ },
+ {
+ "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."
+ }
+ },
+ "@supabase/auth-js.GoTrueClient.onAuthStateChange": {
+ "name": "@supabase/auth-js.GoTrueClient.onAuthStateChange",
+ "params": [
+ {
+ "name": "callback",
+ "type": {
+ "type": "function",
+ "params": [
+ {
+ "name": "event",
+ "type": {
+ "type": "customUnion",
+ "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": "session",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": null
+ },
+ {
+ "type": "customObject",
+ "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": "customUnion",
+ "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": "customUnion",
+ "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": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "user",
+ "type": {
+ "type": "customObject",
+ "name": "User",
+ "properties": [
+ {
+ "name": "action_link",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "app_metadata",
+ "type": {
+ "type": "customObject",
+ "name": "UserAppMetadata",
+ "properties": [
+ {
+ "name": "provider",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "aud",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "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": "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": "customObject",
+ "name": "Factor",
+ "properties": [
+ {
+ "name": "created_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "factor_type",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "Type of factor. Only \`totp\` supported with this version but may change in\\nfuture versions."
+ }
+ },
+ {
+ "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": "status",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "verified"
+ },
+ {
+ "type": "literal",
+ "value": "unverified"
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "Factor's status."
+ }
+ },
+ {
+ "name": "updated_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ "isOptional": true
+ },
+ {
+ "name": "id",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "identities",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "customObject",
+ "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": "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": "customObject",
+ "name": "UserMetadata",
+ "properties": []
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "intrinsic",
+ "name": "void"
+ },
+ {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "intrinsic",
+ "name": "void"
+ }
+ }
+ ]
+ }
+ }
+ },
+ "comment": {
+ "shortText": "A callback function to be invoked when an auth event happens.\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "subscription",
+ "type": {
+ "type": "customObject",
+ "name": "Subscription",
+ "properties": [
+ {
+ "name": "id",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "The subscriber UUID. This will be set by the client."
+ }
+ },
+ {
+ "type": "function",
+ "name": "callback",
+ "params": [
+ {
+ "name": "event",
+ "type": {
+ "type": "customUnion",
+ "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": "session",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": null
+ },
+ {
+ "type": "customObject",
+ "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": "customUnion",
+ "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": "customUnion",
+ "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": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "user",
+ "type": {
+ "type": "customObject",
+ "name": "User",
+ "properties": [
+ {
+ "name": "action_link",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "app_metadata",
+ "type": {
+ "type": "customObject",
+ "name": "UserAppMetadata",
+ "properties": [
+ {
+ "name": "provider",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "aud",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "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": "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": "customObject",
+ "name": "Factor",
+ "properties": [
+ {
+ "name": "created_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "factor_type",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "Type of factor. Only \`totp\` supported with this version but may change in\\nfuture versions."
+ }
+ },
+ {
+ "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": "status",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "verified"
+ },
+ {
+ "type": "literal",
+ "value": "unverified"
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "Factor's status."
+ }
+ },
+ {
+ "name": "updated_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ "isOptional": true
+ },
+ {
+ "name": "id",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "identities",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "customObject",
+ "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": "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": "customObject",
+ "name": "UserMetadata",
+ "properties": []
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "intrinsic",
+ "name": "void"
+ }
+ },
+ "comment": {
+ "shortText": "The function to call every time there is an event. eg: (eventName) => {}"
+ }
+ },
+ {
+ "type": "function",
+ "name": "unsubscribe",
+ "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."
+ }
+ },
+ "@supabase/auth-js.GoTrueClient.reauthenticate": {
+ "name": "@supabase/auth-js.GoTrueClient.reauthenticate",
+ "params": [],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "name": "AuthResponse",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "session",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "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": "customUnion",
+ "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": "customUnion",
+ "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": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "user",
+ "type": {
+ "type": "customObject",
+ "name": "User",
+ "properties": [
+ {
+ "name": "action_link",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "app_metadata",
+ "type": {
+ "type": "customObject",
+ "name": "UserAppMetadata",
+ "properties": [
+ {
+ "name": "provider",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "aud",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "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": "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": "customObject",
+ "name": "Factor",
+ "properties": [
+ {
+ "name": "created_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "factor_type",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "Type of factor. Only \`totp\` supported with this version but may change in\\nfuture versions."
+ }
+ },
+ {
+ "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": "status",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "verified"
+ },
+ {
+ "type": "literal",
+ "value": "unverified"
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "Factor's status."
+ }
+ },
+ {
+ "name": "updated_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ "isOptional": true
+ },
+ {
+ "name": "id",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "identities",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "customObject",
+ "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": "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": "customObject",
+ "name": "UserMetadata",
+ "properties": []
+ }
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "type": "literal",
+ "value": null
+ }
+ ]
+ }
+ },
+ {
+ "name": "user",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "name": "User",
+ "properties": [
+ {
+ "name": "action_link",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "app_metadata",
+ "type": {
+ "type": "customObject",
+ "name": "UserAppMetadata",
+ "properties": [
+ {
+ "name": "provider",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "aud",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "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": "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": "customObject",
+ "name": "Factor",
+ "properties": [
+ {
+ "name": "created_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "factor_type",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "Type of factor. Only \`totp\` supported with this version but may change in\\nfuture versions."
+ }
+ },
+ {
+ "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": "status",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "verified"
+ },
+ {
+ "type": "literal",
+ "value": "unverified"
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "Factor's status."
+ }
+ },
+ {
+ "name": "updated_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ "isOptional": true
+ },
+ {
+ "name": "id",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "identities",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "customObject",
+ "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": "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": "customObject",
+ "name": "UserMetadata",
+ "properties": []
+ }
+ }
+ ]
+ },
+ {
+ "type": "literal",
+ "value": null
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "session",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ },
+ {
+ "name": "user",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ }
+ },
+ {
+ "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."
+ }
+ },
+ "@supabase/auth-js.GoTrueClient.refreshSession": {
+ "name": "@supabase/auth-js.GoTrueClient.refreshSession",
+ "params": [
+ {
+ "name": "currentSession",
+ "type": {
+ "type": "customObject",
+ "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.\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "name": "AuthResponse",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "session",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "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": "customUnion",
+ "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": "customUnion",
+ "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": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "user",
+ "type": {
+ "type": "customObject",
+ "name": "User",
+ "properties": [
+ {
+ "name": "action_link",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "app_metadata",
+ "type": {
+ "type": "customObject",
+ "name": "UserAppMetadata",
+ "properties": [
+ {
+ "name": "provider",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "aud",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "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": "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": "customObject",
+ "name": "Factor",
+ "properties": [
+ {
+ "name": "created_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "factor_type",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "Type of factor. Only \`totp\` supported with this version but may change in\\nfuture versions."
+ }
+ },
+ {
+ "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": "status",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "verified"
+ },
+ {
+ "type": "literal",
+ "value": "unverified"
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "Factor's status."
+ }
+ },
+ {
+ "name": "updated_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ "isOptional": true
+ },
+ {
+ "name": "id",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "identities",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "customObject",
+ "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": "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": "customObject",
+ "name": "UserMetadata",
+ "properties": []
+ }
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "type": "literal",
+ "value": null
+ }
+ ]
+ }
+ },
+ {
+ "name": "user",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "name": "User",
+ "properties": [
+ {
+ "name": "action_link",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "app_metadata",
+ "type": {
+ "type": "customObject",
+ "name": "UserAppMetadata",
+ "properties": [
+ {
+ "name": "provider",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "aud",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "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": "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": "customObject",
+ "name": "Factor",
+ "properties": [
+ {
+ "name": "created_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "factor_type",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "Type of factor. Only \`totp\` supported with this version but may change in\\nfuture versions."
+ }
+ },
+ {
+ "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": "status",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "verified"
+ },
+ {
+ "type": "literal",
+ "value": "unverified"
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "Factor's status."
+ }
+ },
+ {
+ "name": "updated_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ "isOptional": true
+ },
+ {
+ "name": "id",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "identities",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "customObject",
+ "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": "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": "customObject",
+ "name": "UserMetadata",
+ "properties": []
+ }
+ }
+ ]
+ },
+ {
+ "type": "literal",
+ "value": null
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "session",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ },
+ {
+ "name": "user",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ }
+ },
+ {
+ "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."
+ }
+ },
+ "@supabase/auth-js.GoTrueClient.resend": {
+ "name": "@supabase/auth-js.GoTrueClient.resend",
+ "params": [
+ {
+ "name": "credentials",
+ "type": {
+ "type": "customUnion",
+ "name": "ResendParams",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "email",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "options",
+ "type": {
+ "type": "customObject",
+ "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": "nameOnly",
+ "name": "Extract"
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "options",
+ "type": {
+ "type": "customObject",
+ "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": "nameOnly",
+ "name": "Extract"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "name": "AuthOtpResponse",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "messageId",
+ "type": {
+ "type": "customUnion",
+ "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": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "messageId",
+ "type": {
+ "type": "customUnion",
+ "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": {
+ "type": "nameOnly",
+ "name": "AuthError"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ "comment": {
+ "shortText": "Resends an existing signup confirmation email, email change email, SMS OTP or phone change OTP."
+ }
+ },
+ "@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": "customObject",
+ "properties": [
+ {
+ "name": "captchaToken",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "Verification token received when the user completes the captcha on the site.\\n"
+ }
+ },
+ {
+ "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": "customUnion",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data"
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "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."
+ }
+ },
+ "@supabase/auth-js.GoTrueClient.setSession": {
+ "name": "@supabase/auth-js.GoTrueClient.setSession",
+ "params": [
+ {
+ "name": "currentSession",
+ "type": {
+ "type": "customObject",
+ "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.\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "name": "AuthResponse",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "session",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "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": "customUnion",
+ "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": "customUnion",
+ "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": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "user",
+ "type": {
+ "type": "customObject",
+ "name": "User",
+ "properties": [
+ {
+ "name": "action_link",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "app_metadata",
+ "type": {
+ "type": "customObject",
+ "name": "UserAppMetadata",
+ "properties": [
+ {
+ "name": "provider",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "aud",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "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": "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": "customObject",
+ "name": "Factor",
+ "properties": [
+ {
+ "name": "created_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "factor_type",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "Type of factor. Only \`totp\` supported with this version but may change in\\nfuture versions."
+ }
+ },
+ {
+ "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": "status",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "verified"
+ },
+ {
+ "type": "literal",
+ "value": "unverified"
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "Factor's status."
+ }
+ },
+ {
+ "name": "updated_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ "isOptional": true
+ },
+ {
+ "name": "id",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "identities",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "customObject",
+ "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": "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": "customObject",
+ "name": "UserMetadata",
+ "properties": []
+ }
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "type": "literal",
+ "value": null
+ }
+ ]
+ }
+ },
+ {
+ "name": "user",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "name": "User",
+ "properties": [
+ {
+ "name": "action_link",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "app_metadata",
+ "type": {
+ "type": "customObject",
+ "name": "UserAppMetadata",
+ "properties": [
+ {
+ "name": "provider",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "aud",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "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": "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": "customObject",
+ "name": "Factor",
+ "properties": [
+ {
+ "name": "created_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "factor_type",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "Type of factor. Only \`totp\` supported with this version but may change in\\nfuture versions."
+ }
+ },
+ {
+ "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": "status",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "verified"
+ },
+ {
+ "type": "literal",
+ "value": "unverified"
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "Factor's status."
+ }
+ },
+ {
+ "name": "updated_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ "isOptional": true
+ },
+ {
+ "name": "id",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "identities",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "customObject",
+ "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": "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": "customObject",
+ "name": "UserMetadata",
+ "properties": []
+ }
+ }
+ ]
+ },
+ {
+ "type": "literal",
+ "value": null
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "session",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ },
+ {
+ "name": "user",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ }
+ },
+ {
+ "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."
+ }
+ },
+ "@supabase/auth-js.GoTrueClient.signInAnonymously": {
+ "name": "@supabase/auth-js.GoTrueClient.signInAnonymously",
+ "params": [
+ {
+ "name": "credentials",
+ "type": {
+ "name": "SignInAnonymouslyCredentials",
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "options",
+ "type": {
+ "type": "customObject",
+ "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.",
+ "text": "The \`data\` should be a JSON object that includes user-specific info, such as their first and last name.\\n"
+ }
+ }
+ ]
+ },
+ "isOptional": true
+ }
+ ]
+ },
+ "isOptional": true
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "name": "AuthResponse",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "session",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "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": "customUnion",
+ "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": "customUnion",
+ "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": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "user",
+ "type": {
+ "type": "customObject",
+ "name": "User",
+ "properties": [
+ {
+ "name": "action_link",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "app_metadata",
+ "type": {
+ "type": "customObject",
+ "name": "UserAppMetadata",
+ "properties": [
+ {
+ "name": "provider",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "aud",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "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": "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": "customObject",
+ "name": "Factor",
+ "properties": [
+ {
+ "name": "created_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "factor_type",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "Type of factor. Only \`totp\` supported with this version but may change in\\nfuture versions."
+ }
+ },
+ {
+ "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": "status",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "verified"
+ },
+ {
+ "type": "literal",
+ "value": "unverified"
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "Factor's status."
+ }
+ },
+ {
+ "name": "updated_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ "isOptional": true
+ },
+ {
+ "name": "id",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "identities",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "customObject",
+ "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": "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": "customObject",
+ "name": "UserMetadata",
+ "properties": []
+ }
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "type": "literal",
+ "value": null
+ }
+ ]
+ }
+ },
+ {
+ "name": "user",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "name": "User",
+ "properties": [
+ {
+ "name": "action_link",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "app_metadata",
+ "type": {
+ "type": "customObject",
+ "name": "UserAppMetadata",
+ "properties": [
+ {
+ "name": "provider",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "aud",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "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": "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": "customObject",
+ "name": "Factor",
+ "properties": [
+ {
+ "name": "created_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "factor_type",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "Type of factor. Only \`totp\` supported with this version but may change in\\nfuture versions."
+ }
+ },
+ {
+ "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": "status",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "verified"
+ },
+ {
+ "type": "literal",
+ "value": "unverified"
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "Factor's status."
+ }
+ },
+ {
+ "name": "updated_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ "isOptional": true
+ },
+ {
+ "name": "id",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "identities",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "customObject",
+ "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": "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": "customObject",
+ "name": "UserMetadata",
+ "properties": []
+ }
+ }
+ ]
+ },
+ {
+ "type": "literal",
+ "value": null
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "session",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ },
+ {
+ "name": "user",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "nameOnly",
+ "name": "AuthError"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ "comment": {
+ "shortText": "Creates a new anonymous user.",
+ "returns": "A session where the is_anonymous claim in the access token JWT set to true\\n"
+ }
+ },
+ "@supabase/auth-js.GoTrueClient.signInWithIdToken": {
+ "name": "@supabase/auth-js.GoTrueClient.signInWithIdToken",
+ "params": [
+ {
+ "name": "credentials",
+ "type": {
+ "name": "SignInWithIdTokenCredentials",
+ "type": "customObject",
+ "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": "customObject",
+ "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": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "google"
+ },
+ {
+ "type": "literal",
+ "value": "apple"
+ },
+ {
+ "type": "literal",
+ "value": "azure"
+ },
+ {
+ "type": "literal",
+ "value": "facebook"
+ },
+ {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ ]
+ },
+ "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\`, \`keycloak\` (deprecated)."
+ }
+ },
+ {
+ "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": "customUnion",
+ "name": "AuthTokenResponse",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "session",
+ "type": {
+ "type": "customObject",
+ "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": "customUnion",
+ "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": "customUnion",
+ "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": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "user",
+ "type": {
+ "type": "customObject",
+ "name": "User",
+ "properties": [
+ {
+ "name": "action_link",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "app_metadata",
+ "type": {
+ "type": "customObject",
+ "name": "UserAppMetadata",
+ "properties": [
+ {
+ "name": "provider",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "aud",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "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": "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": "customObject",
+ "name": "Factor",
+ "properties": [
+ {
+ "name": "created_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "factor_type",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "Type of factor. Only \`totp\` supported with this version but may change in\\nfuture versions."
+ }
+ },
+ {
+ "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": "status",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "verified"
+ },
+ {
+ "type": "literal",
+ "value": "unverified"
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "Factor's status."
+ }
+ },
+ {
+ "name": "updated_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ "isOptional": true
+ },
+ {
+ "name": "id",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "identities",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "customObject",
+ "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": "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": "customObject",
+ "name": "UserMetadata",
+ "properties": []
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "user",
+ "type": {
+ "type": "customObject",
+ "name": "User",
+ "properties": [
+ {
+ "name": "action_link",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "app_metadata",
+ "type": {
+ "type": "customObject",
+ "name": "UserAppMetadata",
+ "properties": [
+ {
+ "name": "provider",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "aud",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "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": "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": "customObject",
+ "name": "Factor",
+ "properties": [
+ {
+ "name": "created_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "factor_type",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "Type of factor. Only \`totp\` supported with this version but may change in\\nfuture versions."
+ }
+ },
+ {
+ "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": "status",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "verified"
+ },
+ {
+ "type": "literal",
+ "value": "unverified"
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "Factor's status."
+ }
+ },
+ {
+ "name": "updated_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ "isOptional": true
+ },
+ {
+ "name": "id",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "identities",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "customObject",
+ "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": "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": "customObject",
+ "name": "UserMetadata",
+ "properties": []
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "session",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ },
+ {
+ "name": "user",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ }
+ },
+ {
+ "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."
+ }
+ },
+ "@supabase/auth-js.GoTrueClient.signInWithOAuth": {
+ "name": "@supabase/auth-js.GoTrueClient.signInWithOAuth",
+ "params": [
+ {
+ "name": "credentials",
+ "type": {
+ "name": "SignInWithOAuthCredentials",
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "options",
+ "type": {
+ "type": "customObject",
+ "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": "customUnion",
+ "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": "spotify"
+ },
+ {
+ "type": "literal",
+ "value": "twitch"
+ },
+ {
+ "type": "literal",
+ "value": "twitter"
+ },
+ {
+ "type": "literal",
+ "value": "workos"
+ },
+ {
+ "type": "literal",
+ "value": "zoom"
+ },
+ {
+ "type": "literal",
+ "value": "fly"
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "One of the providers supported by GoTrue."
+ }
+ }
+ ]
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "name": "OAuthResponse",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "provider",
+ "type": {
+ "type": "customUnion",
+ "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": "spotify"
+ },
+ {
+ "type": "literal",
+ "value": "twitch"
+ },
+ {
+ "type": "literal",
+ "value": "twitter"
+ },
+ {
+ "type": "literal",
+ "value": "workos"
+ },
+ {
+ "type": "literal",
+ "value": "zoom"
+ },
+ {
+ "type": "literal",
+ "value": "fly"
+ }
+ ]
+ }
+ },
+ {
+ "name": "url",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "provider",
+ "type": {
+ "type": "customUnion",
+ "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": "spotify"
+ },
+ {
+ "type": "literal",
+ "value": "twitch"
+ },
+ {
+ "type": "literal",
+ "value": "twitter"
+ },
+ {
+ "type": "literal",
+ "value": "workos"
+ },
+ {
+ "type": "literal",
+ "value": "zoom"
+ },
+ {
+ "type": "literal",
+ "value": "fly"
+ }
+ ]
+ }
+ },
+ {
+ "name": "url",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ }
+ },
+ {
+ "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."
+ }
+ },
+ "@supabase/auth-js.GoTrueClient.signInWithOtp": {
+ "name": "@supabase/auth-js.GoTrueClient.signInWithOtp",
+ "params": [
+ {
+ "name": "credentials",
+ "type": {
+ "type": "customUnion",
+ "name": "SignInWithPasswordlessCredentials",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "email",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "The user's email address."
+ }
+ },
+ {
+ "name": "options",
+ "type": {
+ "type": "customObject",
+ "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.",
+ "text": "The \`data\` should be a JSON object that includes user-specific info, such as their first and last name.\\n"
+ }
+ },
+ {
+ "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": "customObject",
+ "properties": [
+ {
+ "name": "options",
+ "type": {
+ "type": "customObject",
+ "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": "customUnion",
+ "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.",
+ "text": "The \`data\` should be a JSON object that includes user-specific info, such as their first and last name.\\n"
+ }
+ },
+ {
+ "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": "customUnion",
+ "name": "AuthOtpResponse",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "messageId",
+ "type": {
+ "type": "customUnion",
+ "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": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "messageId",
+ "type": {
+ "type": "customUnion",
+ "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": {
+ "type": "nameOnly",
+ "name": "AuthError"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ "comment": {
+ "shortText": "Log in a user using magiclink or a one-time password (OTP).",
+ "text": "If 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.\\n"
+ }
+ },
+ "@supabase/auth-js.GoTrueClient.signInWithPassword": {
+ "name": "@supabase/auth-js.GoTrueClient.signInWithPassword",
+ "params": [
+ {
+ "name": "credentials",
+ "type": {
+ "type": "customUnion",
+ "name": "SignInWithPasswordCredentials",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "email",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "The user's email address."
+ }
+ },
+ {
+ "name": "options",
+ "type": {
+ "type": "customObject",
+ "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": "password",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "The user's password."
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "options",
+ "type": {
+ "type": "customObject",
+ "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": "password",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "The user's password."
+ }
+ },
+ {
+ "name": "phone",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "The user's phone number."
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "name": "AuthTokenResponsePassword",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "session",
+ "type": {
+ "type": "customObject",
+ "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": "customUnion",
+ "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": "customUnion",
+ "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": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "user",
+ "type": {
+ "type": "customObject",
+ "name": "User",
+ "properties": [
+ {
+ "name": "action_link",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "app_metadata",
+ "type": {
+ "type": "customObject",
+ "name": "UserAppMetadata",
+ "properties": [
+ {
+ "name": "provider",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "aud",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "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": "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": "customObject",
+ "name": "Factor",
+ "properties": [
+ {
+ "name": "created_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "factor_type",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "Type of factor. Only \`totp\` supported with this version but may change in\\nfuture versions."
+ }
+ },
+ {
+ "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": "status",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "verified"
+ },
+ {
+ "type": "literal",
+ "value": "unverified"
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "Factor's status."
+ }
+ },
+ {
+ "name": "updated_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ "isOptional": true
+ },
+ {
+ "name": "id",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "identities",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "customObject",
+ "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": "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": "customObject",
+ "name": "UserMetadata",
+ "properties": []
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "user",
+ "type": {
+ "type": "customObject",
+ "name": "User",
+ "properties": [
+ {
+ "name": "action_link",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "app_metadata",
+ "type": {
+ "type": "customObject",
+ "name": "UserAppMetadata",
+ "properties": [
+ {
+ "name": "provider",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "aud",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "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": "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": "customObject",
+ "name": "Factor",
+ "properties": [
+ {
+ "name": "created_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "factor_type",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "Type of factor. Only \`totp\` supported with this version but may change in\\nfuture versions."
+ }
+ },
+ {
+ "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": "status",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "verified"
+ },
+ {
+ "type": "literal",
+ "value": "unverified"
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "Factor's status."
+ }
+ },
+ {
+ "name": "updated_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ "isOptional": true
+ },
+ {
+ "name": "id",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "identities",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "customObject",
+ "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": "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": "customObject",
+ "name": "UserMetadata",
+ "properties": []
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "weakPassword",
+ "type": {
+ "name": "WeakPassword",
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "message",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "reasons",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "customUnion",
+ "name": "WeakPasswordReasons",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "length"
+ },
+ {
+ "type": "literal",
+ "value": "characters"
+ },
+ {
+ "type": "literal",
+ "value": "pwned"
+ },
+ {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ ]
+ }
+ }
+ }
+ ]
+ },
+ "isOptional": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "session",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ },
+ {
+ "name": "user",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ },
+ {
+ "name": "weakPassword",
+ "type": {
+ "type": "literal",
+ "value": null
+ },
+ "isOptional": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "nameOnly",
+ "name": "AuthError"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ "comment": {
+ "shortText": "Log in an existing user with an email and password or phone and password.",
+ "text": "Be 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.\\n"
+ }
+ },
+ "@supabase/auth-js.GoTrueClient.signInWithSSO": {
+ "name": "@supabase/auth-js.GoTrueClient.signInWithSSO",
+ "params": [
+ {
+ "name": "params",
+ "type": {
+ "type": "customUnion",
+ "name": "SignInWithSSO",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "options",
+ "type": {
+ "type": "customObject",
+ "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."
+ }
+ }
+ ]
+ },
+ "isOptional": true
+ },
+ {
+ "name": "providerId",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "UUID of the SSO provider to invoke single-sign on to."
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "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": "customObject",
+ "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."
+ }
+ }
+ ]
+ },
+ "isOptional": true
+ }
+ ]
+ }
+ ]
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "name": "SSOResponse",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "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.",
+ "text": "On browsers you can set the URL to \`window.location.href\` to take\\nthe user to the authentication flow.\\n"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "nameOnly",
+ "name": "AuthError"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ "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.",
+ "text": "You 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.\\n"
+ }
+ },
+ "@supabase/auth-js.GoTrueClient.signOut": {
+ "name": "@supabase/auth-js.GoTrueClient.signOut",
+ "params": [
+ {
+ "name": "options",
+ "type": {
+ "name": "SignOut",
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "scope",
+ "type": {
+ "type": "customUnion",
+ "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": "customObject",
+ "properties": [
+ {
+ "name": "error",
+ "type": {
+ "type": "customUnion",
+ "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.",
+ "text": "For 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"
+ }
+ },
+ "@supabase/auth-js.GoTrueClient.signUp": {
+ "name": "@supabase/auth-js.GoTrueClient.signUp",
+ "params": [
+ {
+ "name": "credentials",
+ "type": {
+ "type": "customUnion",
+ "name": "SignUpWithPasswordCredentials",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "email",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "The user's email address."
+ }
+ },
+ {
+ "name": "options",
+ "type": {
+ "type": "customObject",
+ "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.",
+ "text": "The \`data\` should be a JSON object that includes user-specific info, such as their first and last name.\\n"
+ }
+ },
+ {
+ "name": "emailRedirectTo",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "The redirect url embedded in the email link"
+ }
+ }
+ ]
+ },
+ "isOptional": true
+ },
+ {
+ "name": "password",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "The user's password."
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "options",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "captchaToken",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "Verification token received when the user completes the captcha on the site. Requires a configured WhatsApp sender on Twilio"
+ }
+ },
+ {
+ "name": "channel",
+ "type": {
+ "type": "customUnion",
+ "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.",
+ "text": "The \`data\` should be a JSON object that includes user-specific info, such as their first and last name.\\n"
+ }
+ }
+ ]
+ },
+ "isOptional": true
+ },
+ {
+ "name": "password",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "The user's password."
+ }
+ },
+ {
+ "name": "phone",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "The user's phone number."
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "name": "AuthResponse",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "session",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "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": "customUnion",
+ "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": "customUnion",
+ "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": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "user",
+ "type": {
+ "type": "customObject",
+ "name": "User",
+ "properties": [
+ {
+ "name": "action_link",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "app_metadata",
+ "type": {
+ "type": "customObject",
+ "name": "UserAppMetadata",
+ "properties": [
+ {
+ "name": "provider",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "aud",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "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": "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": "customObject",
+ "name": "Factor",
+ "properties": [
+ {
+ "name": "created_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "factor_type",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "Type of factor. Only \`totp\` supported with this version but may change in\\nfuture versions."
+ }
+ },
+ {
+ "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": "status",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "verified"
+ },
+ {
+ "type": "literal",
+ "value": "unverified"
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "Factor's status."
+ }
+ },
+ {
+ "name": "updated_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ "isOptional": true
+ },
+ {
+ "name": "id",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "identities",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "customObject",
+ "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": "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": "customObject",
+ "name": "UserMetadata",
+ "properties": []
+ }
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "type": "literal",
+ "value": null
+ }
+ ]
+ }
+ },
+ {
+ "name": "user",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "name": "User",
+ "properties": [
+ {
+ "name": "action_link",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "app_metadata",
+ "type": {
+ "type": "customObject",
+ "name": "UserAppMetadata",
+ "properties": [
+ {
+ "name": "provider",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "aud",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "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": "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": "customObject",
+ "name": "Factor",
+ "properties": [
+ {
+ "name": "created_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "factor_type",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "Type of factor. Only \`totp\` supported with this version but may change in\\nfuture versions."
+ }
+ },
+ {
+ "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": "status",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "verified"
+ },
+ {
+ "type": "literal",
+ "value": "unverified"
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "Factor's status."
+ }
+ },
+ {
+ "name": "updated_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ "isOptional": true
+ },
+ {
+ "name": "id",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "identities",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "customObject",
+ "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": "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": "customObject",
+ "name": "UserMetadata",
+ "properties": []
+ }
+ }
+ ]
+ },
+ {
+ "type": "literal",
+ "value": null
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "session",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ },
+ {
+ "name": "user",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "nameOnly",
+ "name": "AuthError"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ "comment": {
+ "shortText": "Creates a new user.",
+ "text": "Be 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.\\n",
+ "returns": "A logged-in session if the server has \\"autoconfirm\\" ON"
+ }
+ },
+ "@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.",
+ "text": "If you set the {@link 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{@see #stopAutoRefresh}\\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).",
+ "text": "If you call this method any managed visibility change callback will be\\nremoved and you must manage visibility changes on your own.\\n\\nSee {@link #startAutoRefresh} for more details.\\n"
+ }
+ },
+ "@supabase/auth-js.GoTrueClient.unlinkIdentity": {
+ "name": "@supabase/auth-js.GoTrueClient.unlinkIdentity",
+ "params": [
+ {
+ "name": "identity",
+ "type": {
+ "type": "customObject",
+ "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"
+ }
+ }
+ ]
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data"
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "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."
+ }
+ },
+ "@supabase/auth-js.GoTrueClient.updateUser": {
+ "name": "@supabase/auth-js.GoTrueClient.updateUser",
+ "params": [
+ {
+ "name": "attributes",
+ "type": {
+ "type": "customObject",
+ "name": "UserAttributes",
+ "properties": [
+ {
+ "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.",
+ "text": "The \`data\` should be a JSON object that includes user-specific info, such as their first and last name.\\n\\n"
+ }
+ },
+ {
+ "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.",
+ "text": "Call reauthenticate() to obtain the nonce first.\\n"
+ }
+ },
+ {
+ "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": "customObject",
+ "properties": [
+ {
+ "name": "emailRedirectTo",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ }
+ ]
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "name": "UserResponse",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "user",
+ "type": {
+ "type": "customObject",
+ "name": "User",
+ "properties": [
+ {
+ "name": "action_link",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "app_metadata",
+ "type": {
+ "type": "customObject",
+ "name": "UserAppMetadata",
+ "properties": [
+ {
+ "name": "provider",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "aud",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "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": "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": "customObject",
+ "name": "Factor",
+ "properties": [
+ {
+ "name": "created_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "factor_type",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "Type of factor. Only \`totp\` supported with this version but may change in\\nfuture versions."
+ }
+ },
+ {
+ "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": "status",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "verified"
+ },
+ {
+ "type": "literal",
+ "value": "unverified"
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "Factor's status."
+ }
+ },
+ {
+ "name": "updated_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ "isOptional": true
+ },
+ {
+ "name": "id",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "identities",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "customObject",
+ "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": "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": "customObject",
+ "name": "UserMetadata",
+ "properties": []
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "user",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "nameOnly",
+ "name": "AuthError"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ "comment": {
+ "shortText": "Updates user data for a logged in user."
+ }
+ },
+ "@supabase/auth-js.GoTrueClient.verifyOtp": {
+ "name": "@supabase/auth-js.GoTrueClient.verifyOtp",
+ "params": [
+ {
+ "name": "params",
+ "type": {
+ "type": "customUnion",
+ "name": "VerifyOtpParams",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "name": "VerifyMobileOtpParams",
+ "properties": [
+ {
+ "name": "options",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "captchaToken",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "Verification token received when the user completes the captcha on the site.",
+ "tags": [
+ {
+ "tag": "deprecated",
+ "text": "\\n"
+ }
+ ]
+ }
+ },
+ {
+ "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": "customUnion",
+ "name": "MobileOtpType",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "sms"
+ },
+ {
+ "type": "literal",
+ "value": "phone_change"
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "The user's verification type."
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "name": "VerifyEmailOtpParams",
+ "properties": [
+ {
+ "name": "email",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "The user's email address."
+ }
+ },
+ {
+ "name": "options",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "captchaToken",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "Verification token received when the user completes the captcha on the site.",
+ "tags": [
+ {
+ "tag": "deprecated",
+ "text": "\\n"
+ }
+ ]
+ }
+ },
+ {
+ "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": "customUnion",
+ "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"
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "The user's verification type."
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "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": "customUnion",
+ "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"
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "The user's verification type."
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "name": "AuthResponse",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "session",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "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": "customUnion",
+ "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": "customUnion",
+ "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": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "user",
+ "type": {
+ "type": "customObject",
+ "name": "User",
+ "properties": [
+ {
+ "name": "action_link",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "app_metadata",
+ "type": {
+ "type": "customObject",
+ "name": "UserAppMetadata",
+ "properties": [
+ {
+ "name": "provider",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "aud",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "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": "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": "customObject",
+ "name": "Factor",
+ "properties": [
+ {
+ "name": "created_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "factor_type",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "Type of factor. Only \`totp\` supported with this version but may change in\\nfuture versions."
+ }
+ },
+ {
+ "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": "status",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "verified"
+ },
+ {
+ "type": "literal",
+ "value": "unverified"
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "Factor's status."
+ }
+ },
+ {
+ "name": "updated_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ "isOptional": true
+ },
+ {
+ "name": "id",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "identities",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "customObject",
+ "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": "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": "customObject",
+ "name": "UserMetadata",
+ "properties": []
+ }
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "type": "literal",
+ "value": null
+ }
+ ]
+ }
+ },
+ {
+ "name": "user",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "name": "User",
+ "properties": [
+ {
+ "name": "action_link",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "app_metadata",
+ "type": {
+ "type": "customObject",
+ "name": "UserAppMetadata",
+ "properties": [
+ {
+ "name": "provider",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "aud",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "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": "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": "customObject",
+ "name": "Factor",
+ "properties": [
+ {
+ "name": "created_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "factor_type",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "Type of factor. Only \`totp\` supported with this version but may change in\\nfuture versions."
+ }
+ },
+ {
+ "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": "status",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "verified"
+ },
+ {
+ "type": "literal",
+ "value": "unverified"
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "Factor's status."
+ }
+ },
+ {
+ "name": "updated_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ "isOptional": true
+ },
+ {
+ "name": "id",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "identities",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "customObject",
+ "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": "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": "customObject",
+ "name": "UserMetadata",
+ "properties": []
+ }
+ }
+ ]
+ },
+ {
+ "type": "literal",
+ "value": null
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "session",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ },
+ {
+ "name": "user",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ }
+ },
+ {
+ "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."
+ }
+ },
+ "@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.GoTrueAdminMFAApi.deleteFactor": {
+ "name": "@supabase/auth-js.GoTrueAdminMFAApi.deleteFactor",
+ "params": [
+ {
+ "name": "params",
+ "type": {
+ "name": "AuthMFAAdminDeleteFactorParams",
+ "type": "customObject",
+ "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": "customUnion",
+ "name": "AuthMFAAdminDeleteFactorResponse",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "id",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "ID of the factor that was successfully deleted."
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "nameOnly",
+ "name": "AuthError"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ "comment": {
+ "shortText": "Deletes a factor on a user. This will log the user out of all active\\nsessions if the deleted factor was verified.",
+ "tags": [
+ {
+ "tag": "see",
+ "text": "{@link GoTrueMFAApi#unenroll}\\n"
+ },
+ {
+ "tag": "expermental",
+ "text": "\\n"
+ }
+ ]
+ }
+ },
+ "@supabase/auth-js.GoTrueAdminMFAApi.listFactors": {
+ "name": "@supabase/auth-js.GoTrueAdminMFAApi.listFactors",
+ "params": [
+ {
+ "name": "params",
+ "type": {
+ "name": "AuthMFAAdminListFactorsParams",
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "userId",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "ID of the user."
+ }
+ }
+ ]
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "name": "AuthMFAAdminListFactorsResponse",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "factors",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "customObject",
+ "name": "Factor",
+ "properties": [
+ {
+ "name": "created_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "factor_type",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "Type of factor. Only \`totp\` supported with this version but may change in\\nfuture versions."
+ }
+ },
+ {
+ "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": "status",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "verified"
+ },
+ {
+ "type": "literal",
+ "value": "unverified"
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "Factor's status."
+ }
+ },
+ {
+ "name": "updated_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ "comment": {
+ "shortText": "All factors attached to the user."
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "nameOnly",
+ "name": "AuthError"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ "comment": {
+ "shortText": "Lists all factors associated to a user."
+ }
+ },
+ "@supabase/auth-js.GoTrueMFAApi.challenge": {
+ "name": "@supabase/auth-js.GoTrueMFAApi.challenge",
+ "params": [
+ {
+ "name": "params",
+ "type": {
+ "name": "MFAChallengeParams",
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "factorId",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "ID of the factor to be challenged. Returned in enroll()."
+ }
+ }
+ ]
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "name": "AuthMFAChallengeResponse",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "expires_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "number"
+ },
+ "comment": {
+ "shortText": "Timestamp in UNIX seconds when this challenge will no longer be usable."
+ }
+ },
+ {
+ "name": "id",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "ID of the newly created challenge."
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "nameOnly",
+ "name": "AuthError"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ "comment": {
+ "shortText": "Prepares a challenge used to verify that a user has access to a MFA\\nfactor."
+ }
+ },
+ "@supabase/auth-js.GoTrueMFAApi.challengeAndVerify": {
+ "name": "@supabase/auth-js.GoTrueMFAApi.challengeAndVerify",
+ "params": [
+ {
+ "name": "params",
+ "type": {
+ "name": "MFAChallengeAndVerifyParams",
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "code",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "Verification code provided by the user."
+ }
+ },
+ {
+ "name": "factorId",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "ID of the factor being verified. Returned in enroll()."
+ }
+ }
+ ]
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "name": "AuthMFAVerifyResponse",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "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": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "Type of token, typically \`Bearer\`."
+ }
+ },
+ {
+ "name": "user",
+ "type": {
+ "type": "customObject",
+ "name": "User",
+ "properties": [
+ {
+ "name": "action_link",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "app_metadata",
+ "type": {
+ "type": "customObject",
+ "name": "UserAppMetadata",
+ "properties": [
+ {
+ "name": "provider",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "aud",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "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": "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": "customObject",
+ "name": "Factor",
+ "properties": [
+ {
+ "name": "created_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "factor_type",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "Type of factor. Only \`totp\` supported with this version but may change in\\nfuture versions."
+ }
+ },
+ {
+ "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": "status",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "verified"
+ },
+ {
+ "type": "literal",
+ "value": "unverified"
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "Factor's status."
+ }
+ },
+ {
+ "name": "updated_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ "isOptional": true
+ },
+ {
+ "name": "id",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "identities",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "customObject",
+ "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": "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": "customObject",
+ "name": "UserMetadata",
+ "properties": []
+ }
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "Updated user profile."
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "nameOnly",
+ "name": "AuthError"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ "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."
+ }
+ },
+ "@supabase/auth-js.GoTrueMFAApi.enroll": {
+ "name": "@supabase/auth-js.GoTrueMFAApi.enroll",
+ "params": [
+ {
+ "name": "params",
+ "type": {
+ "name": "MFAEnrollParams",
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "factorType",
+ "type": {
+ "type": "literal",
+ "value": "totp"
+ },
+ "comment": {
+ "shortText": "The type of factor being enrolled."
+ }
+ },
+ {
+ "name": "friendlyName",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "Human readable name assigned to the factor."
+ }
+ },
+ {
+ "name": "issuer",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "Domain which the user is enrolled with."
+ }
+ }
+ ]
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "name": "AuthMFAEnrollResponse",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "friendly_name",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "Friendly name of the factor, useful for distinguishing between factors"
+ }
+ },
+ {
+ "name": "id",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "ID of the factor that was just enrolled (in an unverified state)."
+ }
+ },
+ {
+ "name": "totp",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "qr_code",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "Contains a QR code encoding the authenticator URI. You can\\nconvert it to a URL by prepending \`data:image/svg+xml;utf-8,\` to\\nthe value. Avoid logging this value to the console."
+ }
+ },
+ {
+ "name": "secret",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "The TOTP secret (also encoded in the QR code). Show this secret\\nin a password-style field to the user, in case they are unable to\\nscan the QR code. Avoid logging this value to the console."
+ }
+ },
+ {
+ "name": "uri",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "The authenticator URI encoded within the QR code, should you need\\nto use it. Avoid loggin this value to the console."
+ }
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "TOTP enrollment information."
+ }
+ },
+ {
+ "name": "type",
+ "type": {
+ "type": "literal",
+ "value": "totp"
+ },
+ "comment": {
+ "shortText": "Type of MFA factor. Only \`totp\` supported for now."
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "nameOnly",
+ "name": "AuthError"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ "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.",
+ "text": "Upon verifying a factor, all other sessions are logged out and the current session's authenticator level is promoted to \`aal2\`.\\n\\n"
+ }
+ },
+ "@supabase/auth-js.GoTrueMFAApi.getAuthenticatorAssuranceLevel": {
+ "name": "@supabase/auth-js.GoTrueMFAApi.getAuthenticatorAssuranceLevel",
+ "params": [],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "name": "AuthMFAGetAuthenticatorAssuranceLevelResponse",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "currentAuthenticationMethods",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "customObject",
+ "name": "AMREntry",
+ "properties": [
+ {
+ "name": "method",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "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."
+ }
+ }
+ ]
+ }
+ },
+ "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."
+ }
+ },
+ {
+ "name": "currentLevel",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "customUnion",
+ "name": "AuthenticatorAssuranceLevels",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "aal1"
+ },
+ {
+ "type": "literal",
+ "value": "aal2"
+ }
+ ]
+ },
+ {
+ "type": "literal",
+ "value": null
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "Current AAL level of the session."
+ }
+ },
+ {
+ "name": "nextLevel",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "customUnion",
+ "name": "AuthenticatorAssuranceLevels",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "aal1"
+ },
+ {
+ "type": "literal",
+ "value": "aal2"
+ }
+ ]
+ },
+ {
+ "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.",
+ "tags": [
+ {
+ "tag": "see",
+ "text": "{@link GoTrueMFAApi#challenge}\\n"
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "nameOnly",
+ "name": "AuthError"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ "comment": {
+ "shortText": "Returns the Authenticator Assurance Level (AAL) for the active session.",
+ "text": "- \`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\\nAlthough this method returns a promise, it's fairly quick (microseconds)\\nand rarely uses the network. You can use this to check whether the current\\nuser needs to be shown a screen to verify their MFA factors.\\n\\n"
+ }
+ },
+ "@supabase/auth-js.GoTrueMFAApi.listFactors": {
+ "name": "@supabase/auth-js.GoTrueMFAApi.listFactors",
+ "params": [],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "name": "AuthMFAListFactorsResponse",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "all",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "customObject",
+ "name": "Factor",
+ "properties": [
+ {
+ "name": "created_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "factor_type",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "Type of factor. Only \`totp\` supported with this version but may change in\\nfuture versions."
+ }
+ },
+ {
+ "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": "status",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "verified"
+ },
+ {
+ "type": "literal",
+ "value": "unverified"
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "Factor's status."
+ }
+ },
+ {
+ "name": "updated_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ "comment": {
+ "shortText": "All available factors (verified and unverified)."
+ }
+ },
+ {
+ "name": "totp",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "customObject",
+ "name": "Factor",
+ "properties": [
+ {
+ "name": "created_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "factor_type",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "Type of factor. Only \`totp\` supported with this version but may change in\\nfuture versions."
+ }
+ },
+ {
+ "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": "status",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "verified"
+ },
+ {
+ "type": "literal",
+ "value": "unverified"
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "Factor's status."
+ }
+ },
+ {
+ "name": "updated_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ "comment": {
+ "shortText": "Only verified TOTP factors. (A subset of \`all\`.)"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "nameOnly",
+ "name": "AuthError"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ "comment": {
+ "shortText": "Returns the list of MFA factors enabled for this user.",
+ "tags": [
+ {
+ "tag": "see",
+ "text": "{@link GoTrueMFAApi#enroll}"
+ },
+ {
+ "tag": "see",
+ "text": "{@link GoTrueMFAApi#getAuthenticatorAssuranceLevel}"
+ },
+ {
+ "tag": "see",
+ "text": "{@link GoTrueClient#getUser}\\n\\n"
+ }
+ ]
+ }
+ },
+ "@supabase/auth-js.GoTrueMFAApi.unenroll": {
+ "name": "@supabase/auth-js.GoTrueMFAApi.unenroll",
+ "params": [
+ {
+ "name": "params",
+ "type": {
+ "name": "MFAUnenrollParams",
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "factorId",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "ID of the factor being unenrolled."
+ }
+ }
+ ]
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "name": "AuthMFAUnenrollResponse",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "id",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "ID of the factor that was successfully unenrolled."
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "nameOnly",
+ "name": "AuthError"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ "comment": {
+ "shortText": "Unenroll removes a MFA factor.\\nA user has to have an \`aal2\` authenticator level in order to unenroll a \`verified\` factor."
+ }
+ },
+ "@supabase/auth-js.GoTrueMFAApi.verify": {
+ "name": "@supabase/auth-js.GoTrueMFAApi.verify",
+ "params": [
+ {
+ "name": "params",
+ "type": {
+ "name": "MFAVerifyParams",
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "challengeId",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "ID of the challenge being verified. Returned in challenge()."
+ }
+ },
+ {
+ "name": "code",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "Verification code provided by the user."
+ }
+ },
+ {
+ "name": "factorId",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "ID of the factor being verified. Returned in enroll()."
+ }
+ }
+ ]
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "name": "AuthMFAVerifyResponse",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "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": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "Type of token, typically \`Bearer\`."
+ }
+ },
+ {
+ "name": "user",
+ "type": {
+ "type": "customObject",
+ "name": "User",
+ "properties": [
+ {
+ "name": "action_link",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "app_metadata",
+ "type": {
+ "type": "customObject",
+ "name": "UserAppMetadata",
+ "properties": [
+ {
+ "name": "provider",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "aud",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "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": "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": "customObject",
+ "name": "Factor",
+ "properties": [
+ {
+ "name": "created_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "factor_type",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "Type of factor. Only \`totp\` supported with this version but may change in\\nfuture versions."
+ }
+ },
+ {
+ "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": "status",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "verified"
+ },
+ {
+ "type": "literal",
+ "value": "unverified"
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "Factor's status."
+ }
+ },
+ {
+ "name": "updated_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ "isOptional": true
+ },
+ {
+ "name": "id",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "identities",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "customObject",
+ "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": "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": "customObject",
+ "name": "UserMetadata",
+ "properties": []
+ }
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "Updated user profile."
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "nameOnly",
+ "name": "AuthError"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ "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."
+ }
+ },
+ "@supabase/auth-js.Subscription.callback": {
+ "name": "@supabase/auth-js.Subscription.callback",
+ "params": [
+ {
+ "name": "event",
+ "type": {
+ "type": "customUnion",
+ "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": "session",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": null
+ },
+ {
+ "type": "customObject",
+ "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": "customUnion",
+ "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": "customUnion",
+ "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": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "user",
+ "type": {
+ "type": "customObject",
+ "name": "User",
+ "properties": [
+ {
+ "name": "action_link",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "app_metadata",
+ "type": {
+ "type": "customObject",
+ "name": "UserAppMetadata",
+ "properties": [
+ {
+ "name": "provider",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "aud",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "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": "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": "customObject",
+ "name": "Factor",
+ "properties": [
+ {
+ "name": "created_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "factor_type",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "Type of factor. Only \`totp\` supported with this version but may change in\\nfuture versions."
+ }
+ },
+ {
+ "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": "status",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "verified"
+ },
+ {
+ "type": "literal",
+ "value": "unverified"
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "Factor's status."
+ }
+ },
+ {
+ "name": "updated_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ "isOptional": true
+ },
+ {
+ "name": "id",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "identities",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "customObject",
+ "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": "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": "customObject",
+ "name": "UserMetadata",
+ "properties": []
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "intrinsic",
+ "name": "void"
+ }
+ },
+ "comment": {
+ "shortText": "The function to call every time there is an event. eg: (eventName) => {}"
+ }
+ },
+ "@supabase/auth-js.Subscription.unsubscribe": {
+ "name": "@supabase/auth-js.Subscription.unsubscribe",
+ "params": [],
+ "ret": {
+ "type": {
+ "type": "intrinsic",
+ "name": "void"
+ }
+ },
+ "comment": {
+ "shortText": "Call this to remove the listener."
+ }
+ }
+ }
+ },
+ {
+ "name": "@supabase/postgrest-js",
+ "methods": {
+ "@supabase/postgrest-js.PostgrestBuilder.constructor": {
+ "name": "@supabase/postgrest-js.PostgrestBuilder.constructor",
+ "params": [
+ {
+ "name": "builder"
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Result"
+ }
+ }
+ },
+ "@supabase/postgrest-js.PostgrestBuilder.then": {
+ "name": "@supabase/postgrest-js.PostgrestBuilder.then",
+ "params": [
+ {
+ "name": "onfulfilled",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": null
+ },
+ {
+ "type": "function",
+ "params": [
+ {
+ "name": "value",
+ "type": {
+ "type": "customUnion",
+ "name": "PostgrestSingleResponse",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "name": "PostgrestResponseSuccess",
+ "properties": [
+ {
+ "name": "count",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": null
+ },
+ {
+ "type": "intrinsic",
+ "name": "number"
+ }
+ ]
+ }
+ },
+ {
+ "name": "data",
+ "type": {
+ "type": "nameOnly",
+ "name": "T"
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ },
+ {
+ "name": "status",
+ "type": {
+ "type": "intrinsic",
+ "name": "number"
+ }
+ },
+ {
+ "name": "statusText",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "name": "PostgrestResponseFailure",
+ "properties": [
+ {
+ "name": "count",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ },
+ {
+ "name": "data",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "name": "PostgrestError",
+ "type": "customObject",
+ "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": "status",
+ "type": {
+ "type": "intrinsic",
+ "name": "number"
+ }
+ },
+ {
+ "name": "statusText",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "nameOnly",
+ "name": "TResult1"
+ },
+ {
+ "type": "nameOnly",
+ "name": "PromiseLike"
+ }
+ ]
+ }
+ }
+ }
+ ]
+ },
+ "isOptional": true
+ },
+ {
+ "name": "onrejected",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": null
+ },
+ {
+ "type": "function",
+ "params": [
+ {
+ "name": "reason",
+ "type": {
+ "type": "intrinsic",
+ "name": "any"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "nameOnly",
+ "name": "TResult2"
+ },
+ {
+ "type": "nameOnly",
+ "name": "PromiseLike"
+ }
+ ]
+ }
+ }
+ }
+ ]
+ },
+ "isOptional": true
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "PromiseLike"
+ }
+ }
+ },
+ "@supabase/postgrest-js.PostgrestBuilder.throwOnError": {
+ "name": "@supabase/postgrest-js.PostgrestBuilder.throwOnError",
+ "params": [],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Result"
+ }
+ },
+ "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.",
+ "text": "{@link https://github.com/supabase/supabase-js/issues/92}\\n"
+ }
+ },
+ "@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": "customObject",
+ "properties": [
+ {
+ "name": "fetch",
+ "type": {
+ "type": "function",
+ "params": [
+ {
+ "name": "input",
+ "type": {
+ "type": "customUnion",
+ "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": "Custom fetch\\n"
+ }
+ },
+ "isOptional": true
+ },
+ {
+ "name": "headers",
+ "type": {
+ "type": "record",
+ "name": "Record",
+ "keyType": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "valueType": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "Custom headers"
+ }
+ },
+ {
+ "name": "schema",
+ "type": {
+ "type": "nameOnly",
+ "name": "SchemaName"
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "Postgres schema to switch to"
+ }
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "Named parameters"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Database"
+ }
+ },
+ "comment": {
+ "shortText": "Creates a PostgREST client."
+ }
+ },
+ "@supabase/postgrest-js.PostgrestClient.from": {
+ "name": "@supabase/postgrest-js.PostgrestClient.from",
+ "params": [
+ {
+ "name": "relation",
+ "type": {
+ "type": "nameOnly",
+ "name": "TableName"
+ },
+ "comment": {
+ "shortText": "The table or view name to query\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "comment": {
+ "shortText": "Perform a query on a table or a view."
+ }
+ },
+ "@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": "Fn[Args]"
+ },
+ "comment": {
+ "shortText": "The arguments to pass to the function call"
+ }
+ },
+ {
+ "name": "options",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "count",
+ "type": {
+ "type": "customUnion",
+ "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.\\n"
+ }
+ },
+ {
+ "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": "Schema"
+ }
+ },
+ "comment": {
+ "shortText": "Perform a function call."
+ }
+ },
+ "@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\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Database"
+ }
+ },
+ "comment": {
+ "shortText": "Select a schema to query or perform an function (rpc) call.",
+ "text": "The schema needs to be on the list of exposed schemas inside Supabase.\\n"
+ }
+ },
+ "@supabase/postgrest-js.PostgrestFilterBuilder.constructor": {
+ "name": "@supabase/postgrest-js.PostgrestFilterBuilder.constructor",
+ "params": [
+ {
+ "name": "builder"
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ }
+ },
+ "@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\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "comment": {
+ "shortText": "Set the AbortSignal for the fetch request."
+ }
+ },
+ "@supabase/postgrest-js.PostgrestFilterBuilder.containedBy": {
+ "name": "@supabase/postgrest-js.PostgrestFilterBuilder.containedBy",
+ "params": [
+ {
+ "name": "column",
+ "type": {
+ "type": "nameOnly",
+ "name": "ColumnName"
+ },
+ "comment": {
+ "shortText": "The jsonb, array, or range column to filter on"
+ }
+ },
+ {
+ "name": "value",
+ "type": {
+ "type": "customUnion",
+ "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]"
+ }
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "The jsonb, array, or range value to filter with\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "comment": {
+ "shortText": "Only relevant for jsonb, array, and range columns. Match only rows where\\nevery element appearing in \`column\` is contained by \`value\`."
+ }
+ },
+ "@supabase/postgrest-js.PostgrestFilterBuilder.contains": {
+ "name": "@supabase/postgrest-js.PostgrestFilterBuilder.contains",
+ "params": [
+ {
+ "name": "column",
+ "type": {
+ "type": "nameOnly",
+ "name": "ColumnName"
+ },
+ "comment": {
+ "shortText": "The jsonb, array, or range column to filter on"
+ }
+ },
+ {
+ "name": "value",
+ "type": {
+ "type": "customUnion",
+ "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]"
+ }
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "The jsonb, array, or range value to filter with\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "comment": {
+ "shortText": "Only relevant for jsonb, array, and range columns. Match only rows where\\n\`column\` contains every element appearing in \`value\`."
+ }
+ },
+ "@supabase/postgrest-js.PostgrestFilterBuilder.csv": {
+ "name": "@supabase/postgrest-js.PostgrestFilterBuilder.csv",
+ "params": [],
+ "ret": {
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ "comment": {
+ "shortText": "Return \`data\` as a string in CSV format."
+ }
+ },
+ "@supabase/postgrest-js.PostgrestFilterBuilder.eq": {
+ "name": "@supabase/postgrest-js.PostgrestFilterBuilder.eq",
+ "params": [
+ {
+ "name": "column",
+ "type": {
+ "type": "nameOnly",
+ "name": "ColumnName"
+ },
+ "comment": {
+ "shortText": "The column to filter on"
+ }
+ },
+ {
+ "name": "value",
+ "type": {
+ "type": "nameOnly",
+ "name": "NonNullable"
+ },
+ "comment": {
+ "shortText": "The value to filter with\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "comment": {
+ "shortText": "Match only rows where \`column\` is equal to \`value\`.",
+ "text": "To check if the value of \`column\` is NULL, you should use \`.is()\` instead.\\n"
+ }
+ },
+ "@supabase/postgrest-js.PostgrestFilterBuilder.explain": {
+ "name": "@supabase/postgrest-js.PostgrestFilterBuilder.explain",
+ "params": [
+ {
+ "name": "options",
+ "type": {
+ "type": "customObject",
+ "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\\n"
+ }
+ },
+ {
+ "name": "buffers",
+ "type": {
+ "type": "intrinsic",
+ "name": "boolean"
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "If \`true\`, include information on buffer usage\\n"
+ }
+ },
+ {
+ "name": "format",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "text"
+ },
+ {
+ "type": "literal",
+ "value": "json"
+ }
+ ]
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "The format of the output, can be \`\\"text\\"\` (default)\\nor \`\\"json\\"\`\\n"
+ }
+ },
+ {
+ "name": "settings",
+ "type": {
+ "type": "intrinsic",
+ "name": "boolean"
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "If \`true\`, include information on configuration\\nparameters that affect query planning\\n"
+ }
+ },
+ {
+ "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\\n"
+ }
+ },
+ {
+ "name": "wal",
+ "type": {
+ "type": "intrinsic",
+ "name": "boolean"
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "If \`true\`, include information on WAL record generation\\n"
+ }
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "Named parameters\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ {
+ "type": "array",
+ "elemType": {
+ "type": "record",
+ "name": "Record",
+ "keyType": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "valueType": {
+ "type": "intrinsic",
+ "name": "unknown"
+ }
+ }
+ }
+ ]
+ }
+ },
+ "comment": {
+ "shortText": "Return \`data\` as the EXPLAIN plan for the query.",
+ "text": "You need to enable the\\n[db_plan_enabled](https://supabase.com/docs/guides/database/debugging-performance#enabling-explain)\\nsetting before using this method.\\n"
+ }
+ },
+ "@supabase/postgrest-js.PostgrestFilterBuilder.filter": {
+ "name": "@supabase/postgrest-js.PostgrestFilterBuilder.filter",
+ "params": [
+ {
+ "name": "column",
+ "type": {
+ "type": "nameOnly",
+ "name": "ColumnName"
+ },
+ "comment": {
+ "shortText": "The column to filter on"
+ }
+ },
+ {
+ "name": "operator",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "nameOnly",
+ "name": "FilterOperator"
+ },
+ {
+ "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.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"
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "The operator to filter with, following PostgREST syntax"
+ }
+ },
+ {
+ "name": "value",
+ "type": {
+ "type": "intrinsic",
+ "name": "unknown"
+ },
+ "comment": {
+ "shortText": "The value to filter with, following PostgREST syntax\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "comment": {
+ "shortText": "Match only rows which satisfy the filter. This is an escape hatch - you\\nshould use the specific filter methods wherever possible.",
+ "text": "Unlike 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.\\n"
+ }
+ },
+ "@supabase/postgrest-js.PostgrestFilterBuilder.geojson": {
+ "name": "@supabase/postgrest-js.PostgrestFilterBuilder.geojson",
+ "params": [],
+ "ret": {
+ "type": {
+ "type": "record",
+ "name": "Record",
+ "keyType": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "valueType": {
+ "type": "intrinsic",
+ "name": "unknown"
+ }
+ }
+ },
+ "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"
+ },
+ "comment": {
+ "shortText": "The column to filter on"
+ }
+ },
+ {
+ "name": "value",
+ "type": {
+ "type": "nameOnly",
+ "name": "Row[ColumnName]"
+ },
+ "comment": {
+ "shortText": "The value to filter with\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "comment": {
+ "shortText": "Match only rows where \`column\` is greater than \`value\`."
+ }
+ },
+ "@supabase/postgrest-js.PostgrestFilterBuilder.gte": {
+ "name": "@supabase/postgrest-js.PostgrestFilterBuilder.gte",
+ "params": [
+ {
+ "name": "column",
+ "type": {
+ "type": "nameOnly",
+ "name": "ColumnName"
+ },
+ "comment": {
+ "shortText": "The column to filter on"
+ }
+ },
+ {
+ "name": "value",
+ "type": {
+ "type": "nameOnly",
+ "name": "Row[ColumnName]"
+ },
+ "comment": {
+ "shortText": "The value to filter with\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "comment": {
+ "shortText": "Match only rows where \`column\` is greater than or equal to \`value\`."
+ }
+ },
+ "@supabase/postgrest-js.PostgrestFilterBuilder.ilike": {
+ "name": "@supabase/postgrest-js.PostgrestFilterBuilder.ilike",
+ "params": [
+ {
+ "name": "column",
+ "type": {
+ "type": "nameOnly",
+ "name": "ColumnName"
+ },
+ "comment": {
+ "shortText": "The column to filter on"
+ }
+ },
+ {
+ "name": "pattern",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "The pattern to match with\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "comment": {
+ "shortText": "Match only rows where \`column\` matches \`pattern\` case-insensitively."
+ }
+ },
+ "@supabase/postgrest-js.PostgrestFilterBuilder.ilikeAllOf": {
+ "name": "@supabase/postgrest-js.PostgrestFilterBuilder.ilikeAllOf",
+ "params": [
+ {
+ "name": "column",
+ "type": {
+ "type": "nameOnly",
+ "name": "ColumnName"
+ },
+ "comment": {
+ "shortText": "The column to filter on"
+ }
+ },
+ {
+ "name": "patterns",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ "comment": {
+ "shortText": "The patterns to match with\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "comment": {
+ "shortText": "Match only rows where \`column\` matches all of \`patterns\` case-insensitively."
+ }
+ },
+ "@supabase/postgrest-js.PostgrestFilterBuilder.ilikeAnyOf": {
+ "name": "@supabase/postgrest-js.PostgrestFilterBuilder.ilikeAnyOf",
+ "params": [
+ {
+ "name": "column",
+ "type": {
+ "type": "nameOnly",
+ "name": "ColumnName"
+ },
+ "comment": {
+ "shortText": "The column to filter on"
+ }
+ },
+ {
+ "name": "patterns",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ "comment": {
+ "shortText": "The patterns to match with\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "comment": {
+ "shortText": "Match only rows where \`column\` matches any of \`patterns\` case-insensitively."
+ }
+ },
+ "@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",
+ "elemType": {
+ "type": "nameOnly",
+ "name": "Row[ColumnName]"
+ }
+ },
+ "comment": {
+ "shortText": "The values array to filter with\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "comment": {
+ "shortText": "Match only rows where \`column\` is included in the \`values\` array."
+ }
+ },
+ "@supabase/postgrest-js.PostgrestFilterBuilder.is": {
+ "name": "@supabase/postgrest-js.PostgrestFilterBuilder.is",
+ "params": [
+ {
+ "name": "column",
+ "type": {
+ "type": "nameOnly",
+ "name": "ColumnName"
+ },
+ "comment": {
+ "shortText": "The column to filter on"
+ }
+ },
+ {
+ "name": "value",
+ "comment": {
+ "shortText": "The value to filter with\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "comment": {
+ "shortText": "Match only rows where \`column\` IS \`value\`.",
+ "text": "For 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()\`.\\n"
+ }
+ },
+ "@supabase/postgrest-js.PostgrestFilterBuilder.like": {
+ "name": "@supabase/postgrest-js.PostgrestFilterBuilder.like",
+ "params": [
+ {
+ "name": "column",
+ "type": {
+ "type": "nameOnly",
+ "name": "ColumnName"
+ },
+ "comment": {
+ "shortText": "The column to filter on"
+ }
+ },
+ {
+ "name": "pattern",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "The pattern to match with\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "comment": {
+ "shortText": "Match only rows where \`column\` matches \`pattern\` case-sensitively."
+ }
+ },
+ "@supabase/postgrest-js.PostgrestFilterBuilder.likeAllOf": {
+ "name": "@supabase/postgrest-js.PostgrestFilterBuilder.likeAllOf",
+ "params": [
+ {
+ "name": "column",
+ "type": {
+ "type": "nameOnly",
+ "name": "ColumnName"
+ },
+ "comment": {
+ "shortText": "The column to filter on"
+ }
+ },
+ {
+ "name": "patterns",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ "comment": {
+ "shortText": "The patterns to match with\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "comment": {
+ "shortText": "Match only rows where \`column\` matches all of \`patterns\` case-sensitively."
+ }
+ },
+ "@supabase/postgrest-js.PostgrestFilterBuilder.likeAnyOf": {
+ "name": "@supabase/postgrest-js.PostgrestFilterBuilder.likeAnyOf",
+ "params": [
+ {
+ "name": "column",
+ "type": {
+ "type": "nameOnly",
+ "name": "ColumnName"
+ },
+ "comment": {
+ "shortText": "The column to filter on"
+ }
+ },
+ {
+ "name": "patterns",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ "comment": {
+ "shortText": "The patterns to match with\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "comment": {
+ "shortText": "Match only rows where \`column\` matches any of \`patterns\` case-sensitively."
+ }
+ },
+ "@supabase/postgrest-js.PostgrestFilterBuilder.limit": {
+ "name": "@supabase/postgrest-js.PostgrestFilterBuilder.limit",
+ "params": [
+ {
+ "name": "count",
+ "type": {
+ "type": "intrinsic",
+ "name": "number"
+ },
+ "comment": {
+ "shortText": "The maximum number of rows to return"
+ }
+ },
+ {
+ "name": "options",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "foreignTable",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "Deprecated, use \`options.referencedTable\`\\ninstead\\n"
+ }
+ },
+ {
+ "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": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "comment": {
+ "shortText": "Limit the query result by \`count\`."
+ }
+ },
+ "@supabase/postgrest-js.PostgrestFilterBuilder.lt": {
+ "name": "@supabase/postgrest-js.PostgrestFilterBuilder.lt",
+ "params": [
+ {
+ "name": "column",
+ "type": {
+ "type": "nameOnly",
+ "name": "ColumnName"
+ },
+ "comment": {
+ "shortText": "The column to filter on"
+ }
+ },
+ {
+ "name": "value",
+ "type": {
+ "type": "nameOnly",
+ "name": "Row[ColumnName]"
+ },
+ "comment": {
+ "shortText": "The value to filter with\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "comment": {
+ "shortText": "Match only rows where \`column\` is less than \`value\`."
+ }
+ },
+ "@supabase/postgrest-js.PostgrestFilterBuilder.lte": {
+ "name": "@supabase/postgrest-js.PostgrestFilterBuilder.lte",
+ "params": [
+ {
+ "name": "column",
+ "type": {
+ "type": "nameOnly",
+ "name": "ColumnName"
+ },
+ "comment": {
+ "shortText": "The column to filter on"
+ }
+ },
+ {
+ "name": "value",
+ "type": {
+ "type": "nameOnly",
+ "name": "Row[ColumnName]"
+ },
+ "comment": {
+ "shortText": "The value to filter with\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "comment": {
+ "shortText": "Match only rows where \`column\` is less than or equal to \`value\`."
+ }
+ },
+ "@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]"
+ }
+ },
+ "comment": {
+ "shortText": "The object to filter with, with column names as keys mapped\\nto their filter values\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "comment": {
+ "shortText": "Match only rows where each column in \`query\` keys is equal to its\\nassociated value. Shorthand for multiple \`.eq()\`s."
+ }
+ },
+ "@supabase/postgrest-js.PostgrestFilterBuilder.maybeSingle": {
+ "name": "@supabase/postgrest-js.PostgrestFilterBuilder.maybeSingle",
+ "params": [],
+ "ret": {
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": null
+ },
+ {
+ "type": "nameOnly",
+ "name": "ResultOne"
+ }
+ ]
+ }
+ },
+ "comment": {
+ "shortText": "Return \`data\` as a single object instead of an array of objects.",
+ "text": "Query result must be zero or one row (e.g. using \`.limit(1)\`), otherwise\\nthis returns an error.\\n"
+ }
+ },
+ "@supabase/postgrest-js.PostgrestFilterBuilder.neq": {
+ "name": "@supabase/postgrest-js.PostgrestFilterBuilder.neq",
+ "params": [
+ {
+ "name": "column",
+ "type": {
+ "type": "nameOnly",
+ "name": "ColumnName"
+ },
+ "comment": {
+ "shortText": "The column to filter on"
+ }
+ },
+ {
+ "name": "value",
+ "type": {
+ "type": "nameOnly",
+ "name": "Row[ColumnName]"
+ },
+ "comment": {
+ "shortText": "The value to filter with\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "comment": {
+ "shortText": "Match only rows where \`column\` is not equal to \`value\`."
+ }
+ },
+ "@supabase/postgrest-js.PostgrestFilterBuilder.not": {
+ "name": "@supabase/postgrest-js.PostgrestFilterBuilder.not",
+ "params": [
+ {
+ "name": "column",
+ "type": {
+ "type": "nameOnly",
+ "name": "ColumnName"
+ },
+ "comment": {
+ "shortText": "The column to filter on"
+ }
+ },
+ {
+ "name": "operator",
+ "type": {
+ "type": "nameOnly",
+ "name": "FilterOperator"
+ },
+ "comment": {
+ "shortText": "The operator to be negated to filter with, following\\nPostgREST syntax"
+ }
+ },
+ {
+ "name": "value",
+ "type": {
+ "type": "nameOnly",
+ "name": "Row[ColumnName]"
+ },
+ "comment": {
+ "shortText": "The value to filter with, following PostgREST syntax\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "comment": {
+ "shortText": "Match only rows which doesn't satisfy the filter.",
+ "text": "Unlike 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.\\n"
+ }
+ },
+ "@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": "customObject",
+ "properties": [
+ {
+ "name": "foreignTable",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "Deprecated, use \`referencedTable\` instead\\n"
+ }
+ },
+ {
+ "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": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "comment": {
+ "shortText": "Match only rows which satisfy at least one of the filters.",
+ "text": "Unlike 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.\\n"
+ }
+ },
+ "@supabase/postgrest-js.PostgrestFilterBuilder.order": {
+ "name": "@supabase/postgrest-js.PostgrestFilterBuilder.order",
+ "params": [
+ {
+ "name": "column",
+ "type": {
+ "type": "nameOnly",
+ "name": "ColumnName"
+ },
+ "comment": {
+ "shortText": "The column to order by"
+ }
+ },
+ {
+ "name": "options",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "ascending",
+ "type": {
+ "type": "intrinsic",
+ "name": "boolean"
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "If \`true\`, the result will be in ascending order"
+ }
+ },
+ {
+ "name": "nullsFirst",
+ "type": {
+ "type": "intrinsic",
+ "name": "boolean"
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "If \`true\`, \`null\`s appear first. If \`false\`,\\n\`null\`s appear last."
+ }
+ },
+ {
+ "name": "referencedTable",
+ "type": {
+ "type": "intrinsic",
+ "name": "undefined"
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "Set this to order a referenced table by\\nits columns"
+ }
+ }
+ ]
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "Named parameters"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "comment": {
+ "shortText": "Order the query result by \`column\`.",
+ "text": "You 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.\\n"
+ }
+ },
+ "@supabase/postgrest-js.PostgrestFilterBuilder.overlaps": {
+ "name": "@supabase/postgrest-js.PostgrestFilterBuilder.overlaps",
+ "params": [
+ {
+ "name": "column",
+ "type": {
+ "type": "nameOnly",
+ "name": "ColumnName"
+ },
+ "comment": {
+ "shortText": "The array or range column to filter on"
+ }
+ },
+ {
+ "name": "value",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ {
+ "type": "array",
+ "elemType": {
+ "type": "nameOnly",
+ "name": "Row[ColumnName]"
+ }
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "The array or range value to filter with\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "comment": {
+ "shortText": "Only relevant for array and range columns. Match only rows where\\n\`column\` and \`value\` have an element in common."
+ }
+ },
+ "@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": "customObject",
+ "properties": [
+ {
+ "name": "foreignTable",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "Deprecated, use \`options.referencedTable\`\\ninstead\\n"
+ }
+ },
+ {
+ "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": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "comment": {
+ "shortText": "Limit the query result by starting at an offset (\`from\`) and ending at the offset (\`from + 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."
+ }
+ },
+ "@supabase/postgrest-js.PostgrestFilterBuilder.rangeAdjacent": {
+ "name": "@supabase/postgrest-js.PostgrestFilterBuilder.rangeAdjacent",
+ "params": [
+ {
+ "name": "column",
+ "type": {
+ "type": "nameOnly",
+ "name": "ColumnName"
+ },
+ "comment": {
+ "shortText": "The range column to filter on"
+ }
+ },
+ {
+ "name": "range",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "The range to filter with\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "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."
+ }
+ },
+ "@supabase/postgrest-js.PostgrestFilterBuilder.rangeGt": {
+ "name": "@supabase/postgrest-js.PostgrestFilterBuilder.rangeGt",
+ "params": [
+ {
+ "name": "column",
+ "type": {
+ "type": "nameOnly",
+ "name": "ColumnName"
+ },
+ "comment": {
+ "shortText": "The range column to filter on"
+ }
+ },
+ {
+ "name": "range",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "The range to filter with\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "comment": {
+ "shortText": "Only relevant for range columns. Match only rows where every element in\\n\`column\` is greater than any element in \`range\`."
+ }
+ },
+ "@supabase/postgrest-js.PostgrestFilterBuilder.rangeGte": {
+ "name": "@supabase/postgrest-js.PostgrestFilterBuilder.rangeGte",
+ "params": [
+ {
+ "name": "column",
+ "type": {
+ "type": "nameOnly",
+ "name": "ColumnName"
+ },
+ "comment": {
+ "shortText": "The range column to filter on"
+ }
+ },
+ {
+ "name": "range",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "The range to filter with\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "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\`."
+ }
+ },
+ "@supabase/postgrest-js.PostgrestFilterBuilder.rangeLt": {
+ "name": "@supabase/postgrest-js.PostgrestFilterBuilder.rangeLt",
+ "params": [
+ {
+ "name": "column",
+ "type": {
+ "type": "nameOnly",
+ "name": "ColumnName"
+ },
+ "comment": {
+ "shortText": "The range column to filter on"
+ }
+ },
+ {
+ "name": "range",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "The range to filter with\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "comment": {
+ "shortText": "Only relevant for range columns. Match only rows where every element in\\n\`column\` is less than any element in \`range\`."
+ }
+ },
+ "@supabase/postgrest-js.PostgrestFilterBuilder.rangeLte": {
+ "name": "@supabase/postgrest-js.PostgrestFilterBuilder.rangeLte",
+ "params": [
+ {
+ "name": "column",
+ "type": {
+ "type": "nameOnly",
+ "name": "ColumnName"
+ },
+ "comment": {
+ "shortText": "The range column to filter on"
+ }
+ },
+ {
+ "name": "range",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "The range to filter with\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "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\`."
+ }
+ },
+ "@supabase/postgrest-js.PostgrestFilterBuilder.returns": {
+ "name": "@supabase/postgrest-js.PostgrestFilterBuilder.returns",
+ "params": [],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "comment": {
+ "shortText": "Override the type of the returned \`data\`."
+ }
+ },
+ "@supabase/postgrest-js.PostgrestFilterBuilder.rollback": {
+ "name": "@supabase/postgrest-js.PostgrestFilterBuilder.rollback",
+ "params": [],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "comment": {
+ "shortText": "Rollback the query.",
+ "text": "\`data\` will still be returned, but the query is not committed.\\n"
+ }
+ },
+ "@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\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "comment": {
+ "shortText": "Perform a SELECT on the query result.",
+ "text": "By default, \`.insert()\`, \`.update()\`, \`.upsert()\`, and \`.delete()\` do not\\nreturn modified rows. By calling this method, modified rows are returned in\\n\`data\`.\\n"
+ }
+ },
+ "@supabase/postgrest-js.PostgrestFilterBuilder.single": {
+ "name": "@supabase/postgrest-js.PostgrestFilterBuilder.single",
+ "params": [],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "ResultOne"
+ }
+ },
+ "comment": {
+ "shortText": "Return \`data\` as a single object instead of an array of objects.",
+ "text": "Query result must be one row (e.g. using \`.limit(1)\`), otherwise this\\nreturns an error.\\n"
+ }
+ },
+ "@supabase/postgrest-js.PostgrestFilterBuilder.textSearch": {
+ "name": "@supabase/postgrest-js.PostgrestFilterBuilder.textSearch",
+ "params": [
+ {
+ "name": "column",
+ "type": {
+ "type": "nameOnly",
+ "name": "ColumnName"
+ },
+ "comment": {
+ "shortText": "The text or tsvector column to filter on"
+ }
+ },
+ {
+ "name": "query",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "The query text to match with"
+ }
+ },
+ {
+ "name": "options",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "config",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "The text search configuration to use"
+ }
+ },
+ {
+ "name": "type",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "plain"
+ },
+ {
+ "type": "literal",
+ "value": "phrase"
+ },
+ {
+ "type": "literal",
+ "value": "websearch"
+ }
+ ]
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "Change how the \`query\` text is interpreted\\n"
+ }
+ }
+ ]
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "Named parameters"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "comment": {
+ "shortText": "Only relevant for text and tsvector columns. Match only rows where\\n\`column\` matches the query string in \`query\`."
+ }
+ },
+ "@supabase/postgrest-js.PostgrestFilterBuilder.then": {
+ "name": "@supabase/postgrest-js.PostgrestFilterBuilder.then",
+ "params": [
+ {
+ "name": "onfulfilled",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": null
+ },
+ {
+ "type": "function",
+ "params": [
+ {
+ "name": "value",
+ "type": {
+ "type": "customUnion",
+ "name": "PostgrestSingleResponse",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "name": "PostgrestResponseSuccess",
+ "properties": [
+ {
+ "name": "count",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": null
+ },
+ {
+ "type": "intrinsic",
+ "name": "number"
+ }
+ ]
+ }
+ },
+ {
+ "name": "data",
+ "type": {
+ "type": "nameOnly",
+ "name": "T"
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ },
+ {
+ "name": "status",
+ "type": {
+ "type": "intrinsic",
+ "name": "number"
+ }
+ },
+ {
+ "name": "statusText",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "name": "PostgrestResponseFailure",
+ "properties": [
+ {
+ "name": "count",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ },
+ {
+ "name": "data",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "name": "PostgrestError",
+ "type": "customObject",
+ "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": "status",
+ "type": {
+ "type": "intrinsic",
+ "name": "number"
+ }
+ },
+ {
+ "name": "statusText",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "nameOnly",
+ "name": "TResult1"
+ },
+ {
+ "type": "nameOnly",
+ "name": "PromiseLike"
+ }
+ ]
+ }
+ }
+ }
+ ]
+ },
+ "isOptional": true
+ },
+ {
+ "name": "onrejected",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": null
+ },
+ {
+ "type": "function",
+ "params": [
+ {
+ "name": "reason",
+ "type": {
+ "type": "intrinsic",
+ "name": "any"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "nameOnly",
+ "name": "TResult2"
+ },
+ {
+ "type": "nameOnly",
+ "name": "PromiseLike"
+ }
+ ]
+ }
+ }
+ }
+ ]
+ },
+ "isOptional": true
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "PromiseLike"
+ }
+ }
+ },
+ "@supabase/postgrest-js.PostgrestFilterBuilder.throwOnError": {
+ "name": "@supabase/postgrest-js.PostgrestFilterBuilder.throwOnError",
+ "params": [],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "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.",
+ "text": "{@link https://github.com/supabase/supabase-js/issues/92}\\n"
+ }
+ },
+ "@supabase/postgrest-js.PostgrestQueryBuilder.constructor": {
+ "name": "@supabase/postgrest-js.PostgrestQueryBuilder.constructor",
+ "params": [
+ {
+ "name": "url",
+ "type": {
+ "type": "nameOnly",
+ "name": "URL"
+ }
+ },
+ {
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "fetch",
+ "type": {
+ "type": "function",
+ "params": [
+ {
+ "name": "input",
+ "type": {
+ "type": "customUnion",
+ "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"
+ }
+ }
+ }
+ },
+ "isOptional": true
+ },
+ {
+ "name": "headers",
+ "type": {
+ "type": "record",
+ "name": "Record",
+ "keyType": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "valueType": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ "isOptional": true
+ },
+ {
+ "name": "schema",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ }
+ ]
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ }
+ },
+ "@supabase/postgrest-js.PostgrestQueryBuilder.delete": {
+ "name": "@supabase/postgrest-js.PostgrestQueryBuilder.delete",
+ "params": [
+ {
+ "name": "options",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "count",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "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.\\n"
+ }
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "Named parameters\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "comment": {
+ "shortText": "Perform a DELETE on the table or view.",
+ "text": "By default, deleted rows are not returned. To return it, chain the call\\nwith \`.select()\` after filters.\\n"
+ }
+ },
+ "@supabase/postgrest-js.PostgrestQueryBuilder.insert": {
+ "name": "@supabase/postgrest-js.PostgrestQueryBuilder.insert",
+ "params": [
+ {
+ "name": "values",
+ "type": {
+ "type": "nameOnly",
+ "name": "Row"
+ },
+ "comment": {
+ "shortText": "The values to insert. Pass an object to insert a single row\\nor an array to insert multiple rows.\\n"
+ }
+ },
+ {
+ "name": "options",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "count",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "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.\\n"
+ }
+ }
+ ]
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "Named parameters\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "comment": {
+ "shortText": "Perform an INSERT into the table or view.",
+ "text": "By default, inserted rows are not returned. To return it, chain the call\\nwith \`.select()\`.\\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\`\\n"
+ }
+ },
+ {
+ "name": "options",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "count",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "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.\\n"
+ }
+ },
+ {
+ "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.\\n"
+ }
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "Named parameters\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "comment": {
+ "shortText": "Perform a SELECT query on the table or view."
+ }
+ },
+ "@supabase/postgrest-js.PostgrestQueryBuilder.update": {
+ "name": "@supabase/postgrest-js.PostgrestQueryBuilder.update",
+ "params": [
+ {
+ "name": "values",
+ "type": {
+ "type": "nameOnly",
+ "name": "Row"
+ },
+ "comment": {
+ "shortText": "The values to update with\\n"
+ }
+ },
+ {
+ "name": "options",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "count",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "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.\\n"
+ }
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "Named parameters\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "comment": {
+ "shortText": "Perform an UPDATE on the table or view.",
+ "text": "By default, updated rows are not returned. To return it, chain the call\\nwith \`.select()\` after filters.\\n"
+ }
+ },
+ "@supabase/postgrest-js.PostgrestQueryBuilder.upsert": {
+ "name": "@supabase/postgrest-js.PostgrestQueryBuilder.upsert",
+ "params": [
+ {
+ "name": "values",
+ "type": {
+ "type": "nameOnly",
+ "name": "Row"
+ },
+ "comment": {
+ "shortText": "The values to upsert with. Pass an object to upsert a\\nsingle row or an array to upsert multiple rows.\\n"
+ }
+ },
+ {
+ "name": "options",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "count",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "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.\\n"
+ }
+ },
+ {
+ "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.\\n"
+ }
+ },
+ {
+ "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.\\n"
+ }
+ }
+ ]
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "Named parameters\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "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\`.",
+ "text": "By default, upserted rows are not returned. To return it, chain the call\\nwith \`.select()\`.\\n"
+ }
+ },
+ "@supabase/postgrest-js.PostgrestTransformBuilder.constructor": {
+ "name": "@supabase/postgrest-js.PostgrestTransformBuilder.constructor",
+ "params": [
+ {
+ "name": "builder"
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ }
+ },
+ "@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\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "comment": {
+ "shortText": "Set the AbortSignal for the fetch request."
+ }
+ },
+ "@supabase/postgrest-js.PostgrestTransformBuilder.csv": {
+ "name": "@supabase/postgrest-js.PostgrestTransformBuilder.csv",
+ "params": [],
+ "ret": {
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ "comment": {
+ "shortText": "Return \`data\` as a string in CSV format."
+ }
+ },
+ "@supabase/postgrest-js.PostgrestTransformBuilder.explain": {
+ "name": "@supabase/postgrest-js.PostgrestTransformBuilder.explain",
+ "params": [
+ {
+ "name": "options",
+ "type": {
+ "type": "customObject",
+ "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\\n"
+ }
+ },
+ {
+ "name": "buffers",
+ "type": {
+ "type": "intrinsic",
+ "name": "boolean"
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "If \`true\`, include information on buffer usage\\n"
+ }
+ },
+ {
+ "name": "format",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "text"
+ },
+ {
+ "type": "literal",
+ "value": "json"
+ }
+ ]
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "The format of the output, can be \`\\"text\\"\` (default)\\nor \`\\"json\\"\`\\n"
+ }
+ },
+ {
+ "name": "settings",
+ "type": {
+ "type": "intrinsic",
+ "name": "boolean"
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "If \`true\`, include information on configuration\\nparameters that affect query planning\\n"
+ }
+ },
+ {
+ "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\\n"
+ }
+ },
+ {
+ "name": "wal",
+ "type": {
+ "type": "intrinsic",
+ "name": "boolean"
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "If \`true\`, include information on WAL record generation\\n"
+ }
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "Named parameters\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ {
+ "type": "array",
+ "elemType": {
+ "type": "record",
+ "name": "Record",
+ "keyType": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "valueType": {
+ "type": "intrinsic",
+ "name": "unknown"
+ }
+ }
+ }
+ ]
+ }
+ },
+ "comment": {
+ "shortText": "Return \`data\` as the EXPLAIN plan for the query.",
+ "text": "You need to enable the\\n[db_plan_enabled](https://supabase.com/docs/guides/database/debugging-performance#enabling-explain)\\nsetting before using this method.\\n"
+ }
+ },
+ "@supabase/postgrest-js.PostgrestTransformBuilder.geojson": {
+ "name": "@supabase/postgrest-js.PostgrestTransformBuilder.geojson",
+ "params": [],
+ "ret": {
+ "type": {
+ "type": "record",
+ "name": "Record",
+ "keyType": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "valueType": {
+ "type": "intrinsic",
+ "name": "unknown"
+ }
+ }
+ },
+ "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": "count",
+ "type": {
+ "type": "intrinsic",
+ "name": "number"
+ },
+ "comment": {
+ "shortText": "The maximum number of rows to return"
+ }
+ },
+ {
+ "name": "options",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "foreignTable",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "Deprecated, use \`options.referencedTable\`\\ninstead\\n"
+ }
+ },
+ {
+ "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": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "comment": {
+ "shortText": "Limit the query result by \`count\`."
+ }
+ },
+ "@supabase/postgrest-js.PostgrestTransformBuilder.maybeSingle": {
+ "name": "@supabase/postgrest-js.PostgrestTransformBuilder.maybeSingle",
+ "params": [],
+ "ret": {
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": null
+ },
+ {
+ "type": "nameOnly",
+ "name": "ResultOne"
+ }
+ ]
+ }
+ },
+ "comment": {
+ "shortText": "Return \`data\` as a single object instead of an array of objects.",
+ "text": "Query result must be zero or one row (e.g. using \`.limit(1)\`), otherwise\\nthis returns an error.\\n"
+ }
+ },
+ "@supabase/postgrest-js.PostgrestTransformBuilder.order": {
+ "name": "@supabase/postgrest-js.PostgrestTransformBuilder.order",
+ "params": [
+ {
+ "name": "column",
+ "type": {
+ "type": "nameOnly",
+ "name": "ColumnName"
+ },
+ "comment": {
+ "shortText": "The column to order by"
+ }
+ },
+ {
+ "name": "options",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "ascending",
+ "type": {
+ "type": "intrinsic",
+ "name": "boolean"
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "If \`true\`, the result will be in ascending order"
+ }
+ },
+ {
+ "name": "nullsFirst",
+ "type": {
+ "type": "intrinsic",
+ "name": "boolean"
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "If \`true\`, \`null\`s appear first. If \`false\`,\\n\`null\`s appear last."
+ }
+ },
+ {
+ "name": "referencedTable",
+ "type": {
+ "type": "intrinsic",
+ "name": "undefined"
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "Set this to order a referenced table by\\nits columns"
+ }
+ }
+ ]
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "Named parameters"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "comment": {
+ "shortText": "Order the query result by \`column\`.",
+ "text": "You 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.\\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": "customObject",
+ "properties": [
+ {
+ "name": "foreignTable",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "Deprecated, use \`options.referencedTable\`\\ninstead\\n"
+ }
+ },
+ {
+ "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": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "comment": {
+ "shortText": "Limit the query result by starting at an offset (\`from\`) and ending at the offset (\`from + 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."
+ }
+ },
+ "@supabase/postgrest-js.PostgrestTransformBuilder.returns": {
+ "name": "@supabase/postgrest-js.PostgrestTransformBuilder.returns",
+ "params": [],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "comment": {
+ "shortText": "Override the type of the returned \`data\`."
+ }
+ },
+ "@supabase/postgrest-js.PostgrestTransformBuilder.rollback": {
+ "name": "@supabase/postgrest-js.PostgrestTransformBuilder.rollback",
+ "params": [],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "comment": {
+ "shortText": "Rollback the query.",
+ "text": "\`data\` will still be returned, but the query is not committed.\\n"
+ }
+ },
+ "@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\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "comment": {
+ "shortText": "Perform a SELECT on the query result.",
+ "text": "By default, \`.insert()\`, \`.update()\`, \`.upsert()\`, and \`.delete()\` do not\\nreturn modified rows. By calling this method, modified rows are returned in\\n\`data\`.\\n"
+ }
+ },
+ "@supabase/postgrest-js.PostgrestTransformBuilder.single": {
+ "name": "@supabase/postgrest-js.PostgrestTransformBuilder.single",
+ "params": [],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "ResultOne"
+ }
+ },
+ "comment": {
+ "shortText": "Return \`data\` as a single object instead of an array of objects.",
+ "text": "Query result must be one row (e.g. using \`.limit(1)\`), otherwise this\\nreturns an error.\\n"
+ }
+ },
+ "@supabase/postgrest-js.PostgrestTransformBuilder.then": {
+ "name": "@supabase/postgrest-js.PostgrestTransformBuilder.then",
+ "params": [
+ {
+ "name": "onfulfilled",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": null
+ },
+ {
+ "type": "function",
+ "params": [
+ {
+ "name": "value",
+ "type": {
+ "type": "customUnion",
+ "name": "PostgrestSingleResponse",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "name": "PostgrestResponseSuccess",
+ "properties": [
+ {
+ "name": "count",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": null
+ },
+ {
+ "type": "intrinsic",
+ "name": "number"
+ }
+ ]
+ }
+ },
+ {
+ "name": "data",
+ "type": {
+ "type": "nameOnly",
+ "name": "T"
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ },
+ {
+ "name": "status",
+ "type": {
+ "type": "intrinsic",
+ "name": "number"
+ }
+ },
+ {
+ "name": "statusText",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "name": "PostgrestResponseFailure",
+ "properties": [
+ {
+ "name": "count",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ },
+ {
+ "name": "data",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "name": "PostgrestError",
+ "type": "customObject",
+ "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": "status",
+ "type": {
+ "type": "intrinsic",
+ "name": "number"
+ }
+ },
+ {
+ "name": "statusText",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "nameOnly",
+ "name": "TResult1"
+ },
+ {
+ "type": "nameOnly",
+ "name": "PromiseLike"
+ }
+ ]
+ }
+ }
+ }
+ ]
+ },
+ "isOptional": true
+ },
+ {
+ "name": "onrejected",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": null
+ },
+ {
+ "type": "function",
+ "params": [
+ {
+ "name": "reason",
+ "type": {
+ "type": "intrinsic",
+ "name": "any"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "nameOnly",
+ "name": "TResult2"
+ },
+ {
+ "type": "nameOnly",
+ "name": "PromiseLike"
+ }
+ ]
+ }
+ }
+ }
+ ]
+ },
+ "isOptional": true
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "PromiseLike"
+ }
+ }
+ },
+ "@supabase/postgrest-js.PostgrestTransformBuilder.throwOnError": {
+ "name": "@supabase/postgrest-js.PostgrestTransformBuilder.throwOnError",
+ "params": [],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "Schema"
+ }
+ },
+ "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.",
+ "text": "{@link https://github.com/supabase/supabase-js/issues/92}\\n"
+ }
+ }
+ }
+ },
+ {
+ "name": "@supabase/realtime-js",
+ "methods": {
+ "@supabase/realtime-js.RealtimeChannel.constructor": {
+ "name": "@supabase/realtime-js.RealtimeChannel.constructor",
+ "params": [
+ {
+ "name": "topic",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "params",
+ "type": {
+ "name": "RealtimeChannelOptions",
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "config",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "broadcast",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "ack",
+ "type": {
+ "type": "intrinsic",
+ "name": "boolean"
+ },
+ "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"
+ }
+ },
+ {
+ "name": "presence",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "key",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ }
+ ]
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "key option is used to track presence payload across clients"
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "socket"
+ }
+ ]
+ },
+ "@supabase/realtime-js.RealtimeChannel._fetchWithTimeout": {
+ "name": "@supabase/realtime-js.RealtimeChannel._fetchWithTimeout",
+ "params": [
+ {
+ "name": "url",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "options",
+ "type": {
+ "type": "index signature",
+ "keyType": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "valueType": {
+ "type": "intrinsic",
+ "name": "any"
+ }
+ }
+ },
+ {
+ "name": "timeout",
+ "type": {
+ "type": "intrinsic",
+ "name": "number"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "nameOnly",
+ "name": "Response"
+ }
+ }
+ }
+ },
+ "@supabase/realtime-js.RealtimeChannel.on": {
+ "name": "@supabase/realtime-js.RealtimeChannel.on",
+ "params": [
+ {
+ "name": "type",
+ "type": {
+ "type": "literal",
+ "value": "presence"
+ }
+ },
+ {
+ "name": "filter",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "event",
+ "type": {
+ "type": "literal",
+ "value": "sync"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "callback",
+ "type": {
+ "type": "function",
+ "params": [],
+ "ret": {
+ "type": {
+ "type": "intrinsic",
+ "name": "void"
+ }
+ }
+ }
+ }
+ ],
+ "comment": {
+ "shortText": "Creates an event handler that listens to changes."
+ }
+ },
+ "@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"
+ }
+ }
+ }
+ }
+ },
+ "@supabase/realtime-js.RealtimeChannel.send": {
+ "name": "@supabase/realtime-js.RealtimeChannel.send",
+ "params": [
+ {
+ "name": "args",
+ "type": {
+ "type": "customObject",
+ "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": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "presence"
+ },
+ {
+ "type": "literal",
+ "value": "broadcast"
+ },
+ {
+ "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\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "name": "RealtimeChannelSendResponse",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "ok"
+ },
+ {
+ "type": "literal",
+ "value": "timed out"
+ },
+ {
+ "type": "literal",
+ "value": "error"
+ }
+ ]
+ }
+ }
+ },
+ "comment": {
+ "shortText": "Sends a message into the channel."
+ }
+ },
+ "@supabase/realtime-js.RealtimeChannel.subscribe": {
+ "name": "@supabase/realtime-js.RealtimeChannel.subscribe",
+ "params": [
+ {
+ "name": "callback",
+ "type": {
+ "type": "function",
+ "params": [
+ {
+ "name": "status",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "SUBSCRIBED"
+ },
+ {
+ "type": "literal",
+ "value": "TIMED_OUT"
+ },
+ {
+ "type": "literal",
+ "value": "CLOSED"
+ },
+ {
+ "type": "literal",
+ "value": "CHANNEL_ERROR"
+ }
+ ]
+ }
+ },
+ {
+ "name": "err",
+ "type": {
+ "type": "nameOnly",
+ "name": "Error"
+ },
+ "isOptional": true
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "intrinsic",
+ "name": "void"
+ }
+ }
+ },
+ "isOptional": true
+ },
+ {
+ "name": "timeout",
+ "type": {
+ "type": "intrinsic",
+ "name": "number"
+ }
+ }
+ ],
+ "comment": {
+ "shortText": "Subscribe registers your client with the server"
+ }
+ },
+ "@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": "customUnion",
+ "name": "RealtimeChannelSendResponse",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "ok"
+ },
+ {
+ "type": "literal",
+ "value": "timed out"
+ },
+ {
+ "type": "literal",
+ "value": "error"
+ }
+ ]
+ }
+ }
+ }
+ },
+ "@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": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "error"
+ },
+ {
+ "type": "literal",
+ "value": "ok"
+ },
+ {
+ "type": "literal",
+ "value": "timed out"
+ }
+ ]
+ }
+ }
+ },
+ "comment": {
+ "shortText": "Leaves the channel.",
+ "text": "Unsubscribes 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!\\") )\\n"
+ }
+ },
+ "@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": "customUnion",
+ "name": "RealtimeChannelSendResponse",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "ok"
+ },
+ {
+ "type": "literal",
+ "value": "timed out"
+ },
+ {
+ "type": "literal",
+ "value": "error"
+ }
+ ]
+ }
+ }
+ }
+ },
+ "@supabase/realtime-js.RealtimeChannel.updateJoinPayload": {
+ "name": "@supabase/realtime-js.RealtimeChannel.updateJoinPayload",
+ "params": [
+ {
+ "name": "payload",
+ "type": {
+ "type": "index signature",
+ "keyType": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "valueType": {
+ "type": "intrinsic",
+ "name": "any"
+ }
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "intrinsic",
+ "name": "void"
+ }
+ }
+ },
+ "@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": "customObject",
+ "properties": [
+ {
+ "name": "decode",
+ "type": {
+ "type": "nameOnly",
+ "name": "Function"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "encode",
+ "type": {
+ "type": "nameOnly",
+ "name": "Function"
+ },
+ "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": "heartbeatIntervalMs",
+ "type": {
+ "type": "intrinsic",
+ "name": "number"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "log_level",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "info"
+ },
+ {
+ "type": "literal",
+ "value": "debug"
+ },
+ {
+ "type": "literal",
+ "value": "warn"
+ },
+ {
+ "type": "literal",
+ "value": "error"
+ }
+ ]
+ },
+ "isOptional": true
+ },
+ {
+ "name": "logger",
+ "type": {
+ "type": "nameOnly",
+ "name": "Function"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "params",
+ "type": {
+ "type": "index signature",
+ "keyType": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "valueType": {
+ "type": "intrinsic",
+ "name": "any"
+ }
+ },
+ "isOptional": true
+ },
+ {
+ "name": "reconnectAfterMs",
+ "type": {
+ "type": "nameOnly",
+ "name": "Function"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "timeout",
+ "type": {
+ "type": "intrinsic",
+ "name": "number"
+ },
+ "isOptional": true
+ },
+ {
+ "name": "transport",
+ "type": {
+ "type": "nameOnly",
+ "name": "WebSocketLikeConstructor"
+ },
+ "isOptional": true
+ }
+ ]
+ },
+ "isOptional": true
+ }
+ ],
+ "comment": {
+ "shortText": "Initializes the Socket."
+ }
+ },
+ "@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": "customObject",
+ "properties": [
+ {
+ "name": "config",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "broadcast",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "ack",
+ "type": {
+ "type": "intrinsic",
+ "name": "boolean"
+ },
+ "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"
+ }
+ },
+ {
+ "name": "presence",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "key",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "isOptional": true
+ }
+ ]
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "key option is used to track presence payload across clients"
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "@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": "CONNECTION_STATE"
+ }
+ },
+ "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.\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "intrinsic",
+ "name": "void"
+ }
+ },
+ "comment": {
+ "shortText": "Disconnects the socket."
+ }
+ },
+ "@supabase/realtime-js.RealtimeClient.getChannels": {
+ "name": "@supabase/realtime-js.RealtimeClient.getChannels",
+ "params": [],
+ "ret": {
+ "type": {
+ "type": "array"
+ }
+ },
+ "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.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.",
+ "text": "For customized logging, \`this.logger\` can be overridden.\\n"
+ }
+ },
+ "@supabase/realtime-js.RealtimeClient.push": {
+ "name": "@supabase/realtime-js.RealtimeClient.push",
+ "params": [
+ {
+ "name": "data",
+ "type": {
+ "name": "RealtimeMessage",
+ "type": "customObject",
+ "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.",
+ "text": "If the socket is not connected, the message gets enqueued within a local buffer, and sent out when a connection is next established.\\n"
+ }
+ },
+ "@supabase/realtime-js.RealtimeClient.removeAllChannels": {
+ "name": "@supabase/realtime-js.RealtimeClient.removeAllChannels",
+ "params": [],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "array",
+ "elemType": {
+ "type": "customUnion",
+ "name": "RealtimeRemoveChannelResponse",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "ok"
+ },
+ {
+ "type": "literal",
+ "value": "timed out"
+ },
+ {
+ "type": "literal",
+ "value": "error"
+ }
+ ]
+ }
+ }
+ }
+ },
+ "comment": {
+ "shortText": "Unsubscribes and removes all channels"
+ }
+ },
+ "@supabase/realtime-js.RealtimeClient.removeChannel": {
+ "name": "@supabase/realtime-js.RealtimeClient.removeChannel",
+ "params": [
+ {
+ "name": "channel",
+ "comment": {
+ "shortText": "A RealtimeChannel instance\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "name": "RealtimeRemoveChannelResponse",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": "ok"
+ },
+ {
+ "type": "literal",
+ "value": "timed out"
+ },
+ {
+ "type": "literal",
+ "value": "error"
+ }
+ ]
+ }
+ }
+ },
+ "comment": {
+ "shortText": "Unsubscribes and removes a single channel"
+ }
+ },
+ "@supabase/realtime-js.RealtimeClient.setAuth": {
+ "name": "@supabase/realtime-js.RealtimeClient.setAuth",
+ "params": [
+ {
+ "name": "token",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": null
+ },
+ {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "A JWT string.\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "intrinsic",
+ "name": "void"
+ }
+ },
+ "comment": {
+ "shortText": "Sets the JWT access token used for channel subscription authorization and Realtime RLS."
+ }
+ },
+ "@supabase/realtime-js.RealtimePresence.constructor": {
+ "name": "@supabase/realtime-js.RealtimePresence.constructor",
+ "params": [
+ {
+ "name": "channel",
+ "comment": {
+ "shortText": "The RealtimeChannel"
+ }
+ },
+ {
+ "name": "opts",
+ "type": {
+ "type": "nameOnly",
+ "name": "@types/phoenix.PresenceOpts"
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "The options,\\n for example \`{events: {state: 'state', diff: 'diff'}}\`\\n"
+ }
+ }
+ ],
+ "comment": {
+ "shortText": "Initializes the Presence."
+ }
+ }
+ }
+ },
+ {
+ "name": "@supabase/storage-js",
+ "methods": {
+ "@supabase/storage-js.index.StorageApiError.constructor": {
+ "name": "@supabase/storage-js.index.StorageApiError.constructor",
+ "params": [
+ {
+ "name": "message",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "status",
+ "type": {
+ "type": "intrinsic",
+ "name": "number"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "StorageApiError"
+ }
+ }
+ },
+ "@supabase/storage-js.index.StorageApiError.toJSON": {
+ "name": "@supabase/storage-js.index.StorageApiError.toJSON",
+ "params": [],
+ "ret": {
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "message",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "name",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "status",
+ "type": {
+ "type": "intrinsic",
+ "name": "number"
+ }
+ }
+ ]
+ }
+ }
+ },
+ "@supabase/storage-js.index.StorageClient.constructor": {
+ "name": "@supabase/storage-js.index.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": "nameOnly",
+ "name": "RequestInfo"
+ }
+ },
+ {
+ "name": "init",
+ "type": {
+ "type": "nameOnly",
+ "name": "RequestInit"
+ },
+ "isOptional": true
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "nameOnly",
+ "name": "Response"
+ }
+ }
+ }
+ },
+ "isOptional": true
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "StorageClient"
+ }
+ }
+ },
+ "@supabase/storage-js.index.StorageClient.createBucket": {
+ "name": "@supabase/storage-js.index.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": "customObject",
+ "properties": [
+ {
+ "name": "allowedMimeTypes",
+ "type": {
+ "type": "customUnion",
+ "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": "customUnion",
+ "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."
+ }
+ }
+ ]
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "nameOnly",
+ "name": "Pick"
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "nameOnly",
+ "name": "StorageError"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ "comment": {
+ "shortText": "Creates a new Storage bucket",
+ "returns": "newly created bucket id\\n"
+ }
+ },
+ "@supabase/storage-js.index.StorageClient.deleteBucket": {
+ "name": "@supabase/storage-js.index.StorageClient.deleteBucket",
+ "params": [
+ {
+ "name": "id",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "The unique identifier of the bucket you would like to delete.\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "message",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "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."
+ }
+ },
+ "@supabase/storage-js.index.StorageClient.emptyBucket": {
+ "name": "@supabase/storage-js.index.StorageClient.emptyBucket",
+ "params": [
+ {
+ "name": "id",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "The unique identifier of the bucket you would like to empty.\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "message",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "nameOnly",
+ "name": "StorageError"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ "comment": {
+ "shortText": "Removes all objects inside a single bucket."
+ }
+ },
+ "@supabase/storage-js.index.StorageClient.from": {
+ "name": "@supabase/storage-js.index.StorageClient.from",
+ "params": [
+ {
+ "name": "id",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "The bucket id to operate on.\\n"
+ }
+ }
+ ],
+ "comment": {
+ "shortText": "Perform file operation in a bucket."
+ }
+ },
+ "@supabase/storage-js.index.StorageClient.getBucket": {
+ "name": "@supabase/storage-js.index.StorageClient.getBucket",
+ "params": [
+ {
+ "name": "id",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "comment": {
+ "shortText": "The unique identifier of the bucket you would like to retrieve.\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "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": "updated_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "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."
+ }
+ },
+ "@supabase/storage-js.index.StorageClient.listBuckets": {
+ "name": "@supabase/storage-js.index.StorageClient.listBuckets",
+ "params": [],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "customObject",
+ "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": "updated_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "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."
+ }
+ },
+ "@supabase/storage-js.index.StorageClient.updateBucket": {
+ "name": "@supabase/storage-js.index.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": "customObject",
+ "properties": [
+ {
+ "name": "allowedMimeTypes",
+ "type": {
+ "type": "customUnion",
+ "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.\\n"
+ }
+ },
+ {
+ "name": "fileSizeLimit",
+ "type": {
+ "type": "customUnion",
+ "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": "customUnion",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "message",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "nameOnly",
+ "name": "StorageError"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ "comment": {
+ "shortText": "Updates a Storage bucket"
+ }
+ },
+ "@supabase/storage-js.index.StorageError.constructor": {
+ "name": "@supabase/storage-js.index.StorageError.constructor",
+ "params": [
+ {
+ "name": "message",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "StorageError"
+ }
+ }
+ },
+ "@supabase/storage-js.index.StorageUnknownError.constructor": {
+ "name": "@supabase/storage-js.index.StorageUnknownError.constructor",
+ "params": [
+ {
+ "name": "message",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "originalError",
+ "type": {
+ "type": "intrinsic",
+ "name": "unknown"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "StorageUnknownError"
+ }
+ }
+ },
+ "@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": "nameOnly",
+ "name": "RequestInfo"
+ }
+ },
+ {
+ "name": "init",
+ "type": {
+ "type": "nameOnly",
+ "name": "RequestInit"
+ },
+ "isOptional": true
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "nameOnly",
+ "name": "Response"
+ }
+ }
+ }
+ },
+ "isOptional": true
+ }
+ ]
+ },
+ "@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": "customObject",
+ "properties": [
+ {
+ "name": "allowedMimeTypes",
+ "type": {
+ "type": "customUnion",
+ "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": "customUnion",
+ "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."
+ }
+ }
+ ]
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "nameOnly",
+ "name": "Pick"
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "nameOnly",
+ "name": "StorageError"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ "comment": {
+ "shortText": "Creates a new Storage bucket",
+ "returns": "newly created bucket id\\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.\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "message",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "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."
+ }
+ },
+ "@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.\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "message",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "nameOnly",
+ "name": "StorageError"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ "comment": {
+ "shortText": "Removes all objects inside a single bucket."
+ }
+ },
+ "@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.\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "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": "updated_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "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."
+ }
+ },
+ "@supabase/storage-js.packages/StorageBucketApi.default.listBuckets": {
+ "name": "@supabase/storage-js.packages/StorageBucketApi.default.listBuckets",
+ "params": [],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "customObject",
+ "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": "updated_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "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."
+ }
+ },
+ "@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": "customObject",
+ "properties": [
+ {
+ "name": "allowedMimeTypes",
+ "type": {
+ "type": "customUnion",
+ "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.\\n"
+ }
+ },
+ {
+ "name": "fileSizeLimit",
+ "type": {
+ "type": "customUnion",
+ "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": "customUnion",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "message",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "nameOnly",
+ "name": "StorageError"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ "comment": {
+ "shortText": "Updates a Storage bucket"
+ }
+ },
+ "@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": "nameOnly",
+ "name": "RequestInfo"
+ }
+ },
+ {
+ "name": "init",
+ "type": {
+ "type": "nameOnly",
+ "name": "RequestInit"
+ },
+ "isOptional": true
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "nameOnly",
+ "name": "Response"
+ }
+ }
+ }
+ },
+ "isOptional": true
+ }
+ ]
+ },
+ "@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\`.\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "path",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "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."
+ }
+ },
+ "@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\`.\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "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": "customObject",
+ "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."
+ }
+ },
+ "@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": "customObject",
+ "properties": [
+ {
+ "name": "download",
+ "type": {
+ "type": "customUnion",
+ "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": "customObject",
+ "name": "TransformOptions",
+ "properties": [
+ {
+ "name": "format",
+ "type": {
+ "type": "literal",
+ "value": "origin"
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "Specify the format of the image requested.",
+ "text": "When 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.\\n"
+ }
+ },
+ {
+ "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": "customUnion",
+ "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.\\n"
+ }
+ }
+ ]
+ },
+ "isOptional": true
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "signedUrl",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "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."
+ }
+ },
+ "@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": "customObject",
+ "properties": [
+ {
+ "name": "download",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ {
+ "type": "intrinsic",
+ "name": "boolean"
+ }
+ ]
+ },
+ "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.\\n"
+ }
+ }
+ ]
+ },
+ "isOptional": true
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "error",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": null
+ },
+ {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ ]
+ }
+ },
+ {
+ "name": "path",
+ "type": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "literal",
+ "value": null
+ },
+ {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ ]
+ }
+ },
+ {
+ "name": "signedUrl",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "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."
+ }
+ },
+ "@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": "customObject",
+ "properties": [
+ {
+ "name": "transform",
+ "type": {
+ "type": "customObject",
+ "name": "TransformOptions",
+ "properties": [
+ {
+ "name": "format",
+ "type": {
+ "type": "literal",
+ "value": "origin"
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "Specify the format of the image requested.",
+ "text": "When 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.\\n"
+ }
+ },
+ {
+ "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": "customUnion",
+ "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.\\n"
+ }
+ }
+ ]
+ },
+ "isOptional": true
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "nameOnly",
+ "name": "Blob"
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "nameOnly",
+ "name": "StorageError"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ "comment": {
+ "shortText": "Downloads a file from a private bucket. For public buckets, make a request to the URL returned from \`getPublicUrl\` instead."
+ }
+ },
+ "@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": "customObject",
+ "properties": [
+ {
+ "name": "download",
+ "type": {
+ "type": "customUnion",
+ "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": "customObject",
+ "name": "TransformOptions",
+ "properties": [
+ {
+ "name": "format",
+ "type": {
+ "type": "literal",
+ "value": "origin"
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "Specify the format of the image requested.",
+ "text": "When 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.\\n"
+ }
+ },
+ {
+ "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": "customUnion",
+ "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.\\n"
+ }
+ }
+ ]
+ },
+ "isOptional": true
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "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."
+ }
+ },
+ "@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.\\n"
+ }
+ },
+ {
+ "name": "options",
+ "type": {
+ "type": "customObject",
+ "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": "customObject",
+ "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
+ },
+ {
+ "name": "parameters",
+ "type": {
+ "type": "customObject",
+ "name": "FetchParameters",
+ "properties": [
+ {
+ "name": "signal",
+ "type": {
+ "type": "nameOnly",
+ "name": "AbortSignal"
+ },
+ "isOptional": true,
+ "comment": {
+ "shortText": "Pass in an AbortController's signal to cancel the request."
+ }
+ }
+ ]
+ },
+ "isOptional": true
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "customObject",
+ "name": "FileObject",
+ "properties": [
+ {
+ "name": "bucket_id",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "buckets",
+ "type": {
+ "type": "customObject",
+ "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": "updated_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "created_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "id",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "last_accessed_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "metadata",
+ "type": {
+ "type": "record",
+ "name": "Record",
+ "keyType": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "valueType": {
+ "type": "intrinsic",
+ "name": "any"
+ }
+ }
+ },
+ {
+ "name": "name",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "owner",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "updated_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "nameOnly",
+ "name": "StorageError"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ "comment": {
+ "shortText": "Lists all the files within a bucket."
+ }
+ },
+ "@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\`.\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "message",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "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."
+ }
+ },
+ "@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'\`].\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "array",
+ "elemType": {
+ "type": "customObject",
+ "name": "FileObject",
+ "properties": [
+ {
+ "name": "bucket_id",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "buckets",
+ "type": {
+ "type": "customObject",
+ "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": "updated_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "created_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "id",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "last_accessed_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "metadata",
+ "type": {
+ "type": "record",
+ "name": "Record",
+ "keyType": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "valueType": {
+ "type": "intrinsic",
+ "name": "any"
+ }
+ }
+ },
+ {
+ "name": "name",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "owner",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "name": "updated_at",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "nameOnly",
+ "name": "StorageError"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ "comment": {
+ "shortText": "Deletes files within the same bucket"
+ }
+ },
+ "@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": "customUnion",
+ "subTypes": [
+ {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ {
+ "type": "nameOnly",
+ "name": "ArrayBuffer"
+ },
+ {
+ "type": "nameOnly",
+ "name": "ArrayBufferView"
+ },
+ {
+ "type": "nameOnly",
+ "name": "Blob"
+ },
+ {
+ "type": "nameOnly",
+ "name": "@types/node.Buffer"
+ },
+ {
+ "type": "nameOnly",
+ "name": "File"
+ },
+ {
+ "type": "nameOnly",
+ "name": "FormData"
+ },
+ {
+ "type": "nameOnly",
+ "name": "@types/node.NodeJS.ReadableStream"
+ },
+ {
+ "type": "nameOnly",
+ "name": "ReadableStream"
+ },
+ {
+ "type": "nameOnly",
+ "name": "URLSearchParams"
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "The body of the file to be stored in the bucket.\\n"
+ }
+ },
+ {
+ "name": "fileOptions",
+ "type": {
+ "type": "customObject",
+ "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": "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
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "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": "customObject",
+ "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."
+ }
+ },
+ "@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.\\n"
+ }
+ },
+ {
+ "name": "fileOptions",
+ "type": {
+ "type": "customObject",
+ "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": "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
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "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": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "nameOnly",
+ "name": "StorageError"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ "comment": {
+ "shortText": "Uploads a file to an existing bucket."
+ }
+ },
+ "@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.\\n"
+ }
+ },
+ {
+ "name": "fileOptions",
+ "type": {
+ "type": "customObject",
+ "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": "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
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "subTypes": [
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "fullPath",
+ "type": {
+ "type": "intrinsic",
+ "name": "any"
+ }
+ },
+ {
+ "name": "path",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ }
+ ]
+ },
+ {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "data",
+ "type": {
+ "type": "literal",
+ "value": null
+ }
+ },
+ {
+ "name": "error",
+ "type": {
+ "type": "intrinsic",
+ "name": "any"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ "comment": {
+ "shortText": "Upload a file with a token generated from \`createSignedUploadUrl\`."
+ }
+ }
+ }
+ },
+ {
+ "name": "@supabase/functions-js",
+ "methods": {
+ "@supabase/functions-js.FunctionsClient.constructor": {
+ "name": "@supabase/functions-js.FunctionsClient.constructor",
+ "params": [
+ {
+ "name": "url",
+ "type": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ {
+ "type": {
+ "type": "customObject",
+ "properties": [
+ {
+ "name": "customFetch",
+ "type": {
+ "type": "function",
+ "params": [
+ {
+ "name": "input",
+ "type": {
+ "type": "customUnion",
+ "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"
+ }
+ }
+ }
+ },
+ "isOptional": true
+ },
+ {
+ "name": "headers",
+ "type": {
+ "type": "record",
+ "name": "Record",
+ "keyType": {
+ "type": "intrinsic",
+ "name": "string"
+ },
+ "valueType": {
+ "type": "intrinsic",
+ "name": "string"
+ }
+ },
+ "isOptional": true
+ },
+ {
+ "name": "region",
+ "isOptional": true
+ }
+ ]
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "FunctionsClient"
+ }
+ }
+ },
+ "@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": "customObject",
+ "properties": [
+ {
+ "name": "body",
+ "type": {
+ "type": "customUnion",
+ "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": "customUnion",
+ "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",
+ "isOptional": true,
+ "comment": {
+ "shortText": "The Region to invoke the function in."
+ }
+ }
+ ]
+ },
+ "comment": {
+ "shortText": "Options for invoking the Function.\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "promise",
+ "name": "Promise",
+ "awaited": {
+ "type": "customUnion",
+ "name": "FunctionsResponse",
+ "subTypes": []
+ }
+ }
+ },
+ "comment": {
+ "shortText": "Invokes a function"
+ }
+ },
+ "@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\\n"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "intrinsic",
+ "name": "void"
+ }
+ },
+ "comment": {
+ "shortText": "Updates the authorization header"
+ }
+ },
+ "@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.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.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.FunctionsRelayError.constructor": {
+ "name": "@supabase/functions-js.FunctionsRelayError.constructor",
+ "params": [
+ {
+ "name": "context",
+ "type": {
+ "type": "intrinsic",
+ "name": "any"
+ }
+ }
+ ],
+ "ret": {
+ "type": {
+ "type": "nameOnly",
+ "name": "FunctionsRelayError"
+ }
+ }
+ }
+ }
+ }
+]"
+`;
diff --git a/apps/docs/features/helpers.fetch.ts b/apps/docs/features/helpers.fetch.ts
new file mode 100644
index 00000000000..6a38fb63933
--- /dev/null
+++ b/apps/docs/features/helpers.fetch.ts
@@ -0,0 +1,17 @@
+/**
+ * Next.js extends native `fetch` with revalidation options.
+ *
+ * This module provides some reusable utility functions to set revalidation
+ * options for `fetch`, for example when it needs to be passed to a
+ * third-party API.
+ */
+
+import { ONE_DAY_IN_SECONDS } from './helpers.time'
+
+function fetchWithNextOptions(options: NextFetchRequestConfig) {
+ return (info: RequestInfo) => fetch(info, { next: options })
+}
+
+const fetchRevalidatePerDay = fetchWithNextOptions({ revalidate: ONE_DAY_IN_SECONDS })
+
+export { fetchWithNextOptions, fetchRevalidatePerDay }
diff --git a/apps/docs/features/helpers.fs.ts b/apps/docs/features/helpers.fs.ts
new file mode 100644
index 00000000000..2f1c5c6f84d
--- /dev/null
+++ b/apps/docs/features/helpers.fs.ts
@@ -0,0 +1,53 @@
+import { watch } from 'node:fs'
+import { stat } from 'node:fs/promises'
+
+import { IS_DEV } from '~/lib/constants'
+import type { OrPromise } from '~/features/helpers.types'
+
+/**
+ * Caches a function for the length of the server process.
+ *
+ * In DEV, watches a directory to cache bust on edit.
+ */
+export const cache_fullProcess_withDevCacheBust = (
+ /**
+ * The function whose results to cache
+ */
+ fn: (...args: Args) => OrPromise,
+ /**
+ * The directory to watch for edits
+ */
+ watchDirectory: string,
+ /**
+ * A function that generates the cache key to bust, given the changed
+ * filename (relative to the watch directory)
+ */
+ genCacheKeyFromFilename: (filename: string) => string
+) => {
+ const _cache = new Map()
+
+ if (IS_DEV) {
+ watch(watchDirectory, { recursive: true }, (_, filename) => {
+ if (!filename) return
+ const cacheKey = genCacheKeyFromFilename(filename)
+ _cache.delete(cacheKey)
+ })
+ }
+
+ return async (...args: Args) => {
+ const cacheKey = JSON.stringify(args)
+ if (!_cache.has(cacheKey)) {
+ _cache.set(cacheKey, await fn(...args))
+ }
+ return _cache.get(cacheKey)!
+ }
+}
+
+export const existsFile = async (fullPath: string) => {
+ try {
+ await stat(fullPath)
+ return true
+ } catch {
+ return false
+ }
+}
diff --git a/apps/docs/features/helpers.time.ts b/apps/docs/features/helpers.time.ts
new file mode 100644
index 00000000000..4997d861de3
--- /dev/null
+++ b/apps/docs/features/helpers.time.ts
@@ -0,0 +1,3 @@
+const ONE_DAY_IN_SECONDS = 60 * 60 * 24
+
+export { ONE_DAY_IN_SECONDS }
diff --git a/apps/docs/features/helpers.types.ts b/apps/docs/features/helpers.types.ts
new file mode 100644
index 00000000000..200048aae30
--- /dev/null
+++ b/apps/docs/features/helpers.types.ts
@@ -0,0 +1,5 @@
+type OrPromise = T | Promise
+
+type WithRequired = T & { [P in K]-?: T[P] }
+
+export type { OrPromise, WithRequired }
diff --git a/apps/docs/features/recommendations/NotFound.client.tsx b/apps/docs/features/recommendations/NotFound.client.tsx
new file mode 100644
index 00000000000..616022bd81c
--- /dev/null
+++ b/apps/docs/features/recommendations/NotFound.client.tsx
@@ -0,0 +1,101 @@
+'use client'
+
+import { useSupabaseClient } from '@supabase/auth-helpers-react'
+import { type SupabaseClient } from '@supabase/supabase-js'
+import { X } from 'lucide-react'
+import { useEffect, useRef, useState } from 'react'
+
+import { useCommandMenu } from '@ui-patterns/Cmdk'
+import { GenericSkeletonLoader } from '@ui-patterns/ShimmeringLoader'
+import { type DocsSearchResult } from 'common'
+import { Button, cn } from 'ui'
+
+import ButtonCard from '~/components/ButtonCard'
+
+function SearchButton() {
+ const { setIsOpen: setCommandMenuOpen } = useCommandMenu()
+
+ return (
+ setCommandMenuOpen(true)}>
+ Search for page
+
+ )
+}
+
+async function getRecommendations(page: string, supabase: SupabaseClient) {
+ try {
+ const query = decodeURIComponent(page.replace(/^\/(?:guides|reference)\//, '')).replace(
+ /[_\/-]/g,
+ ' '
+ )
+ if (!query) return []
+
+ const { data, error } = await supabase.rpc('docs_search_fts', { query })
+ if (error || !data?.length) return []
+ return data as Array>
+ } catch (err) {
+ console.error(err)
+ return []
+ }
+}
+
+function Recommendations({ page }: { page: string }) {
+ const supabase = useSupabaseClient()
+ const [recommendations, setRecommendations] = useState(
+ [] as Array>
+ )
+
+ const fetched = useRef(false)
+
+ useEffect(() => {
+ getRecommendations(page, supabase).then((data) => {
+ if (!fetched.current) {
+ setRecommendations(data)
+ fetched.current = true
+ }
+ })
+ }, [page, supabase])
+
+ return (
+
+ Are you looking for...?
+ {!fetched.current && }
+ {fetched.current && recommendations.length === 0 && }
+ {fetched.current && recommendations.length > 0 && (
+
+ )}
+
+ )
+}
+
+function LoadingState() {
+ return
+}
+
+function NoResults() {
+ return No recommendations found.
+}
+
+function RecommendationsList({
+ recommendations,
+}: {
+ recommendations: Array>
+}) {
+ return (
+
+ {recommendations
+ .filter(({ title }) => !!title)
+ .slice(0, 6)
+ .map(({ path, title, subtitle, description }) => (
+
+ ))}
+
+ )
+}
+
+export { SearchButton, Recommendations }
diff --git a/apps/docs/features/recommendations/NotFound.utils.ts b/apps/docs/features/recommendations/NotFound.utils.ts
new file mode 100644
index 00000000000..19774150840
--- /dev/null
+++ b/apps/docs/features/recommendations/NotFound.utils.ts
@@ -0,0 +1,8 @@
+const notFoundLink = (origPath: string) => {
+ if (!origPath) return '/not-found'
+
+ const searchParams = new URLSearchParams({ page: origPath })
+ return `/not-found?${searchParams}`
+}
+
+export { notFoundLink }
diff --git a/apps/docs/features/ui/Accordion.tsx b/apps/docs/features/ui/Accordion.tsx
new file mode 100644
index 00000000000..dea771bb5a4
--- /dev/null
+++ b/apps/docs/features/ui/Accordion.tsx
@@ -0,0 +1,13 @@
+'use client'
+
+import { Accordion as AccordionPrimitive } from 'ui'
+
+/**
+ * This makes the component work in MDX files, which otherwise would error on
+ * "trying to dot into a Client Component".
+ */
+
+const Accordion = AccordionPrimitive
+const AccordionItem = AccordionPrimitive.Item
+
+export { Accordion, AccordionItem }
diff --git a/apps/docs/features/ui/CodeHike.tsx b/apps/docs/features/ui/CodeHike.tsx
new file mode 100644
index 00000000000..c54dbba339d
--- /dev/null
+++ b/apps/docs/features/ui/CodeHike.tsx
@@ -0,0 +1,28 @@
+'use client'
+
+import { CH } from '@code-hike/mdx/components'
+
+/**
+ * [Charis 2024-04-20]
+ *
+ * Annotations are broken and I can't find a way around it.
+ *
+ * Problem seems to be related to CH.annotations being a map of components and
+ * not a component itself. It's not bundled by the RSC bundler, and you get the
+ * error `Could not find the module .../CodeHike.tsx#annotations#mark in the
+ * React Client Manifest`.
+ */
+
+export const Code = CH.Code
+export const Section = CH.Section
+export const SectionLink = CH.SectionLink
+export const SectionCode = CH.SectionCode
+export const Spotlight = CH.Spotlight
+export const Scrollycoding = CH.Scrollycoding
+export const Preview = CH.Preview
+export const Annotation = CH.Annotation
+export const Slideshow = CH.Slideshow
+export const InlineCode = CH.InlineCode
+export const CodeSlot = CH.CodeSlot
+export const PreviewSlot = CH.PreviewSlot
+export const StaticToggle = CH.StaticToggle
diff --git a/apps/docs/features/ui/GlassPanelWithIconPicker.tsx b/apps/docs/features/ui/GlassPanelWithIconPicker.tsx
new file mode 100644
index 00000000000..3521f774c81
--- /dev/null
+++ b/apps/docs/features/ui/GlassPanelWithIconPicker.tsx
@@ -0,0 +1,18 @@
+import { type ComponentProps, type PropsWithChildren } from 'react'
+import { GlassPanel } from 'ui-patterns/GlassPanel'
+
+import MenuIconPicker from '~/components/Navigation/NavigationMenu/MenuIconPicker'
+
+type GlassPanelWithIconPickerProps = PropsWithChildren<
+ Omit, 'icon'> & { icon: string }
+>
+
+function GlassPanelWithIconPicker({ children, icon, ...props }: GlassPanelWithIconPickerProps) {
+ return (
+ } {...props}>
+ {children}
+
+ )
+}
+
+export { GlassPanelWithIconPicker }
diff --git a/apps/docs/features/ui/IconPanelWithIconPicker.tsx b/apps/docs/features/ui/IconPanelWithIconPicker.tsx
new file mode 100644
index 00000000000..4cec2f9e9c3
--- /dev/null
+++ b/apps/docs/features/ui/IconPanelWithIconPicker.tsx
@@ -0,0 +1,14 @@
+import { type ComponentProps } from 'react'
+import { IconPanel } from 'ui-patterns'
+
+import MenuIconPicker from '~/components/Navigation/NavigationMenu/MenuIconPicker'
+
+type IconPanelWithIconPickerProps = Omit, 'icon'> & {
+ icon: string
+}
+
+function IconPanelWithIconPicker({ icon, ...props }: IconPanelWithIconPickerProps) {
+ return } {...props} />
+}
+
+export { IconPanelWithIconPicker }
diff --git a/apps/docs/components/Tabs.tsx b/apps/docs/features/ui/Tabs.tsx
similarity index 100%
rename from apps/docs/components/Tabs.tsx
rename to apps/docs/features/ui/Tabs.tsx
diff --git a/apps/docs/generator/api.ts b/apps/docs/generator/api.ts
index f915e422534..1c3c7361199 100644
--- a/apps/docs/generator/api.ts
+++ b/apps/docs/generator/api.ts
@@ -1,6 +1,6 @@
import template from './templates/ApiTemplate'
import { slugify, toArrayWithKey, toTitle, writeToDisk } from './helpers'
-import { OpenAPIV3, OpenAPIV2 } from 'openapi-types'
+import type { OpenAPIV3, OpenAPIV2 } from 'openapi-types'
import * as fs from 'fs'
import * as ejs from 'ejs'
diff --git a/apps/docs/hooks/useCopy.ts b/apps/docs/hooks/useCopy.ts
index 460df34f30a..9b052e4adee 100644
--- a/apps/docs/hooks/useCopy.ts
+++ b/apps/docs/hooks/useCopy.ts
@@ -1,3 +1,5 @@
+'use client'
+
import { useState } from 'react'
export function useCopy() {
diff --git a/apps/docs/jest.config.mjs b/apps/docs/jest.config.mjs
deleted file mode 100644
index 296d4256ae6..00000000000
--- a/apps/docs/jest.config.mjs
+++ /dev/null
@@ -1,13 +0,0 @@
-import nextJest from 'next/jest.js'
-
-const createJestConfig = nextJest({
- // Provide the path to your Next.js app to load next.config.js and .env files in your test environment
- dir: './',
-})
-
-const config = {
- setupFilesAfterEnv: ['/jest.setup.js'],
- testEnvironment: 'jsdom',
-}
-
-export default createJestConfig(config)
diff --git a/apps/docs/jest.setup.js b/apps/docs/jest.setup.js
deleted file mode 100644
index c44951a680d..00000000000
--- a/apps/docs/jest.setup.js
+++ /dev/null
@@ -1 +0,0 @@
-import '@testing-library/jest-dom'
diff --git a/apps/docs/layouts/DefaultLayout.tsx b/apps/docs/layouts/DefaultLayout.tsx
index f6b3f8bf230..39224810673 100644
--- a/apps/docs/layouts/DefaultLayout.tsx
+++ b/apps/docs/layouts/DefaultLayout.tsx
@@ -3,4 +3,4 @@ import { type FC, type PropsWithChildren } from 'react'
export const LayoutMainContent: FC> = ({
className,
children,
-}) => {children}
+}) => {children}
diff --git a/apps/docs/layouts/HomeLayout.tsx b/apps/docs/layouts/HomeLayout.tsx
index 7f2ff3de39a..4c04c9fc9cd 100644
--- a/apps/docs/layouts/HomeLayout.tsx
+++ b/apps/docs/layouts/HomeLayout.tsx
@@ -1,73 +1,21 @@
-import { MDXProvider } from '@mdx-js/react'
-import { NextSeo } from 'next-seo'
-import Head from 'next/head'
-import { useRouter } from 'next/router'
-import { FC } from 'react'
-import components from '~/components'
+import { type PropsWithChildren } from 'react'
+
import HomePageCover from '~/components/HomePageCover'
-import { MenuId } from '~/components/Navigation/NavigationMenu/NavigationMenu'
import { LayoutMainContent } from './DefaultLayout'
-import { MainSkeleton } from './MainSkeleton'
-
-interface Props {
- meta: {
- title: string
- canonical?: string
- description?: string
- video?: string
- }
- children: any
-}
-
-const HomeLayout: FC = (props: Props) => {
- const { asPath } = useRouter()
+import { SidebarSkeleton } from './MainSkeleton'
+const HomeLayout = ({ children }: PropsWithChildren) => {
return (
- <>
-
- {asPath === '/' ? 'Supabase Docs' : `${props.meta?.title} | Supabase Docs`}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- >
+
+
+
+
+
+
+
+
)
}
diff --git a/apps/docs/layouts/MainSkeleton.tsx b/apps/docs/layouts/MainSkeleton.tsx
index 18206d69af1..a0c9176f42d 100644
--- a/apps/docs/layouts/MainSkeleton.tsx
+++ b/apps/docs/layouts/MainSkeleton.tsx
@@ -1,15 +1,22 @@
-import { useTheme } from 'next-themes'
-import Image from 'next/legacy/image'
-import Link from 'next/link'
-import { type CSSProperties, type PropsWithChildren, memo, useEffect } from 'react'
+'use client'
+
+import dynamic from 'next/dynamic'
+import { memo, useEffect, type PropsWithChildren, type ReactNode } from 'react'
+
import { cn } from 'ui'
-import Footer from '~/components/Navigation/Footer'
-import HomeMenuIconPicker from '~/components/Navigation/NavigationMenu/HomeMenuIconPicker'
-import NavigationMenu, { type MenuId } from '~/components/Navigation/NavigationMenu/NavigationMenu'
+
+import DefaultNavigationMenu, {
+ MenuId,
+} from '~/components/Navigation/NavigationMenu/NavigationMenu'
import TopNavBar from '~/components/Navigation/NavigationMenu/TopNavBar'
import { DOCS_CONTENT_CONTAINER_ID } from '~/features/ui/helpers.constants'
import { menuState, useMenuMobileOpen } from '~/hooks/useMenuState'
+const Footer = dynamic(() => import('~/components/Navigation/Footer'))
+const NavigationMenu = dynamic(
+ () => import('~/components/Navigation/NavigationMenu/NavigationMenu')
+)
+
const levelsData = {
home: {
icon: 'home',
@@ -156,60 +163,52 @@ const MobileHeader = memo(function MobileHeader({ menuId }: { menuId: MenuId })
return (
menuState.setMenuMobileOpen(!mobileMenuOpen)}
>
+ !mobileMenuOpen ? 'w-4' : 'absolute rotate-45 top-[6px]'
+ )}
+ />
+ !mobileMenuOpen ? 'w-3 group-hover:w-4' : 'absolute w-4 -rotate-45 top-[2px]'
+ )}
+ />
-
-
-
{mobileMenuOpen
? 'Close'
: menuLevel
- ? levelsData[menuLevel].name
+ ? levelsData[menuLevel]?.name
: levelsData['home'].name}
@@ -233,7 +232,7 @@ const MobileMenuBackdrop = memo(function MobileMenuBackdrop() {
return (
menuState.setMenuMobileOpen(!mobileMenuOpen)}
>
)
})
-const HeaderLogo = memo(function HeaderLogo() {
- const { resolvedTheme } = useTheme()
- return (
-
-
- DOCS
-
- )
-})
-
const Container = memo(function Container({
children,
className,
}: PropsWithChildren<{ className?: string }>) {
- const mobileMenuOpen = useMenuMobileOpen()
-
return (
-
+ {children}
+
)
})
-const NavContainer = memo(function NavContainer({ menuId }: { menuId: MenuId }) {
+const NavContainer = memo(function NavContainer({ children }: PropsWithChildren) {
const mobileMenuOpen = useMenuMobileOpen()
return (
-
+
Main menu
-
-
)
})
-function MainSkeleton({ children, menuId }: PropsWithChildren<{ menuId: MenuId }>) {
+interface SkeletonProps extends PropsWithChildren {
+ menuId?: MenuId
+ NavigationMenu?: ReactNode
+}
+
+function TopNavSkeleton({ children }) {
return (
-
-
-
-
+
+ )
+}
+
+function SidebarSkeleton({ children, menuId, NavigationMenu }: SkeletonProps) {
+ const mobileMenuOpen = useMenuMobileOpen()
+ const hideSideNav = !menuId
+
+ return (
+
+ {!hideSideNav && (
+
{NavigationMenu ?? }
+ )}
+
+
-
-
-
+ {!hideSideNav &&
}
{children}
@@ -386,4 +377,4 @@ function MainSkeleton({ children, menuId }: PropsWithChildren<{ menuId: MenuId }
)
}
-export { MainSkeleton }
+export { TopNavSkeleton, SidebarSkeleton }
diff --git a/apps/docs/layouts/SiteLayout.tsx b/apps/docs/layouts/SiteLayout.tsx
index 5754ddff924..5803c8ad70c 100644
--- a/apps/docs/layouts/SiteLayout.tsx
+++ b/apps/docs/layouts/SiteLayout.tsx
@@ -1,15 +1,5 @@
-import Head from 'next/head'
import { PropsWithChildren } from 'react'
-const SiteLayout = ({ children }: PropsWithChildren<{}>) => {
- return (
- <>
-
-
Supabase Docs
-
-
{children}
- >
- )
-}
+const SiteLayout = ({ children }: PropsWithChildren<{}>) =>
{children}
export default SiteLayout
diff --git a/apps/docs/layouts/guides/index.tsx b/apps/docs/layouts/guides/index.tsx
index 1c510cd3315..c625530ddcf 100644
--- a/apps/docs/layouts/guides/index.tsx
+++ b/apps/docs/layouts/guides/index.tsx
@@ -1,21 +1,16 @@
-import { MDXProvider } from '@mdx-js/react'
+'use client'
+
import 'katex/dist/katex.min.css'
-import { ExternalLink } from 'lucide-react'
-import { NextSeo } from 'next-seo'
-import { useRouter } from 'next/router'
+
import { type FC } from 'react'
-import { cn } from 'ui'
-
-import components from '~/components'
import { FooterHelpCalloutType } from '~/components/FooterHelpCallout'
-import GuidesTableOfContents from '~/components/GuidesTableOfContents'
import { type MenuId } from '~/components/Navigation/NavigationMenu/NavigationMenu'
import { LayoutMainContent } from '~/layouts/DefaultLayout'
-import { MainSkeleton } from '~/layouts/MainSkeleton'
+import { SidebarSkeleton } from '~/layouts/MainSkeleton'
interface Props {
- meta: {
+ meta?: {
title: string
description?: string // used in meta tags
hide_table_of_contents?: boolean
@@ -35,123 +30,12 @@ interface Props {
}
const Layout: FC
= (props) => {
- const { asPath } = useRouter()
- const router = useRouter()
-
const menuId = props.menuId
- const EDIT_BUTTON_EXCLUDE_LIST = ['/404']
-
- // page type, ie, Auth, Database, Storage etc
- const ogPageType = asPath.split('/')[2]
- // open graph image url constructor
- const ogImageUrl = encodeURI(
- `https://obuldanrptloktxcffvn.supabase.co/functions/v1/og-images?site=docs${
- ogPageType ? `&type=${ogPageType}` : ''
- }&title=${encodeURIComponent(props.meta?.title)}&description=${encodeURIComponent(props.meta?.description)}`
- )
-
return (
- <>
-
-
-
-
-
- {props.meta?.breadcrumb && (
-
{props.meta.breadcrumb}
- )}
-
- {props.meta.title}
- {props.meta?.subtitle && (
- {props.meta.subtitle}
- )}
-
- {props.children}
-
- {EDIT_BUTTON_EXCLUDE_LIST.includes(router.route) ? (
- <>>
- ) : (
-
- )}
-
-
- {!props.hideToc && !props.meta?.hide_table_of_contents && (
-
- )}
-
-
-
- >
+
+ {props.children}
+
)
}
diff --git a/apps/docs/layouts/ref/RefSubLayout.tsx b/apps/docs/layouts/ref/RefSubLayout.tsx
index 69a91fc1db3..1e1ef0e3f20 100644
--- a/apps/docs/layouts/ref/RefSubLayout.tsx
+++ b/apps/docs/layouts/ref/RefSubLayout.tsx
@@ -1,10 +1,11 @@
import { useInView } from 'react-intersection-observer'
import { FC, PropsWithChildren } from 'react'
import { highlightSelectedNavItem } from 'ui/src/components/CustomHTMLElements/CustomHTMLElements.utils'
-import { useRouter } from 'next/router'
+import { useRouter } from 'next/compat/router'
import { useNavigationMenuContext } from '~/components/Navigation/NavigationMenu/NavigationMenu.Context'
import { menuState } from '~/hooks/useMenuState'
import Image from 'next/legacy/image'
+import { cn } from 'ui'
interface ISectionContainer {
id: string
@@ -66,7 +67,7 @@ const Section: FC> = (props) => {
key={props.id + 'section'}
className={[
props.singleColumn ? 'prose w-full' : 'w-full',
- 'py-16 lg:py-32 first:pt-8 last:pb-8',
+ 'py-16 first:pt-8 last:pb-8',
].join(' ')}
>
@@ -120,11 +121,11 @@ const StickyHeader: FC = ({ icon, ...props }) => {
ref={ref}
id={props.slug}
data-ref-id={props.id}
- className={[
- 'text-2xl font-medium text-foreground scroll-mt-24',
+ className={cn(
+ 'text-2xl font-medium text-foreground scroll-mt-[calc(32px+2rem)] lg:scroll-mt-[calc(var(--header-height)+1px+4rem)]',
!icon && 'mb-8',
- props.monoFont && 'font-mono',
- ].join(' ')}
+ props.monoFont && 'font-mono'
+ )}
>
{props.title && {props.title} }
@@ -148,7 +149,7 @@ const Examples: FC> = (props) => {
*/
return (
-
{props.children}
+
{props.children}
)
}
@@ -169,7 +170,7 @@ const EducationSection: FC> = ({
return (
{!hideTitle && }
{props.children}
diff --git a/apps/docs/layouts/ref/RefSubLayoutNonFunc.tsx b/apps/docs/layouts/ref/RefSubLayoutNonFunc.tsx
index b31b8260e68..e841d71da7a 100644
--- a/apps/docs/layouts/ref/RefSubLayoutNonFunc.tsx
+++ b/apps/docs/layouts/ref/RefSubLayoutNonFunc.tsx
@@ -1,7 +1,7 @@
import { useInView } from 'react-intersection-observer'
import { FC, PropsWithChildren } from 'react'
import { highlightSelectedNavItem } from 'ui/src/components/CustomHTMLElements/CustomHTMLElements.utils'
-import { useRouter } from 'next/router'
+import { useRouter } from 'next/compat/router'
import { useNavigationMenuContext } from '~/components/Navigation/NavigationMenu/NavigationMenu.Context'
import { menuState } from '~/hooks/useMenuState'
@@ -37,10 +37,7 @@ const RefSubLayoutNonFunc: FC> &
const Section: FC> = (props) => {
return (
-
+
> = (props) => {
return (
-
{props.children}
+
{props.children}
)
}
diff --git a/apps/docs/lib/constants.ts b/apps/docs/lib/constants.ts
index 53c1ad2bd59..4729a0c07c5 100644
--- a/apps/docs/lib/constants.ts
+++ b/apps/docs/lib/constants.ts
@@ -2,9 +2,11 @@ export const API_URL = (
process.env.NODE_ENV === 'development'
? process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8080'
: process.env.NEXT_PUBLIC_API_URL
-).replace(/\/platform$/, '')
+)?.replace(/\/platform$/, '')
export const BASE_PATH = process.env.NEXT_PUBLIC_BASE_PATH || '/docs'
export const BUILD_PREVIEW_HTML = process.env.NEXT_PUBLIC_BUILD_PREVIEW_HTML === 'true'
+export const IS_DEV = process.env.NODE_ENV === 'development'
export const IS_PLATFORM = process.env.NEXT_PUBLIC_IS_PLATFORM === 'true'
export const IS_PREVIEW = process.env.NEXT_PUBLIC_VERCEL_ENV === 'preview'
export const LOCAL_SUPABASE = process.env.NEXT_PUBLIC_LOCAL_SUPABASE === 'true'
+export const MISC_URL = process.env.NEXT_PUBLIC_MISC_URL ?? ''
diff --git a/apps/docs/lib/docs.ts b/apps/docs/lib/docs.ts
index 6481e58f3cf..a5e9e3ac86c 100644
--- a/apps/docs/lib/docs.ts
+++ b/apps/docs/lib/docs.ts
@@ -14,11 +14,16 @@ import codeHikeTheme from 'config/code-hike.theme.json' assert { type: 'json' }
const DOCS_DIRECTORY = join(dirname(fileURLToPath(import.meta.url)), '..')
export const GUIDES_DIRECTORY = join(DOCS_DIRECTORY, 'content/guides')
+export const SPEC_DIRECTORY = join(DOCS_DIRECTORY, 'spec')
-type GuideFrontmatter = {
+export type GuideFrontmatter = {
title: string
+ subtitle?: string
description?: string
+ canonical?: string
hideToc?: boolean
+ // @deprecated
+ hide_table_of_contents?: boolean
tocVideo?: string
}
@@ -34,11 +39,28 @@ export function isValidGuideFrontmatter(obj: object): obj is GuideFrontmatter {
`Invalid guide frontmatter: Title must exist and be a string. Received: ${obj.title}`
)
}
+ if ('subtitle' in obj && typeof obj.subtitle !== 'string') {
+ throw Error(`Invalid guide frontmatter: Subtitle must be a sring. Received: ${obj.subtitle}`)
+ }
if ('description' in obj && typeof obj.description !== 'string') {
throw Error(
`Invalid guide frontmatter: Description must be a string. Received: ${obj.description}`
)
}
+ if ('canonical' in obj && typeof obj.canonical !== 'string') {
+ throw Error(`Invalid guide frontmatter: Canonical must be a string. Received: ${obj.canonical}`)
+ }
+ if ('hideToc' in obj && typeof obj.hideToc !== 'boolean') {
+ throw Error(`Invalid guide frontmatter: hideToc must be a boolean. Received: ${obj.hideToc}`)
+ }
+ if ('hide_table_of_contents' in obj && typeof obj.hide_table_of_contents !== 'boolean') {
+ throw Error(
+ `Invalid guide frontmatter: hide_table_of_contents must be a boolean. Received ${obj.hide_table_of_contents}`
+ )
+ }
+ if ('tocVideo' in obj && typeof obj.tocVideo !== 'string') {
+ throw Error(`Invalid guide frontmatter: tocVideo must be a string. Received ${obj.tocVideo}`)
+ }
return true
}
diff --git a/apps/docs/lib/fetch/feedback.ts b/apps/docs/lib/fetch/feedback.ts
index 670780b7c7c..8bafd80ff59 100644
--- a/apps/docs/lib/fetch/feedback.ts
+++ b/apps/docs/lib/fetch/feedback.ts
@@ -20,7 +20,7 @@ export async function sendFeedback({
}: SendFeedbackVariables) {
const { data, error } = await post('/platform/feedback/docs', {
body: {
- page: pathname,
+ page: pathname ?? '',
isHelpful,
title,
feedback: message,
diff --git a/apps/docs/lib/fetch/fetchWrappers.ts b/apps/docs/lib/fetch/fetchWrappers.ts
index 2e3efd513dd..440ac83dc8b 100644
--- a/apps/docs/lib/fetch/fetchWrappers.ts
+++ b/apps/docs/lib/fetch/fetchWrappers.ts
@@ -1,4 +1,4 @@
-import { type paths } from '~/types/api'
+import type { paths } from 'api-types'
import createClient from 'openapi-fetch'
import { v4 as uuidv4 } from 'uuid'
import { API_URL } from '../constants'
@@ -37,13 +37,7 @@ export async function constructHeaders(
}
export const get: typeof _get = async (url, init) => {
- let headers: Headers = null
- try {
- headers = await constructHeaders(init?.headers)
- } catch (err) {
- console.error(err)
- return { error: err, response: undefined }
- }
+ const headers = await constructHeaders(init?.headers)
return await _get(url, {
...init,
@@ -52,13 +46,7 @@ export const get: typeof _get = async (url, init) => {
}
export const post: typeof _post = async (url, init) => {
- let headers: Headers = null
- try {
- headers = await constructHeaders(init?.headers)
- } catch (err) {
- console.error(err)
- return { error: err, response: undefined }
- }
+ const headers = await constructHeaders(init?.headers)
return await _post(url, {
...init,
@@ -67,13 +55,7 @@ export const post: typeof _post = async (url, init) => {
}
export const unauthedAllowedPost: typeof _post = async (url, init) => {
- let headers: Headers = null
- try {
- headers = await constructHeaders(init?.headers, { allowUnauthenticated: true })
- } catch (err) {
- console.error(err)
- return { error: err, response: undefined }
- }
+ const headers = await constructHeaders(init?.headers, { allowUnauthenticated: true })
return await _post(url, {
...init,
diff --git a/apps/docs/lib/fetch/organizations.ts b/apps/docs/lib/fetch/organizations.ts
index 40ee51f1861..9db981af8c8 100644
--- a/apps/docs/lib/fetch/organizations.ts
+++ b/apps/docs/lib/fetch/organizations.ts
@@ -1,6 +1,6 @@
import { useQuery, UseQueryOptions } from '@tanstack/react-query'
import { get } from './fetchWrappers'
-import type { components } from '~/types/api'
+import type { components } from 'api-types'
import type { ResponseError } from '~/types/fetch'
const organizationKeys = {
diff --git a/apps/docs/lib/fetch/projectApi.ts b/apps/docs/lib/fetch/projectApi.ts
index d9b757914ee..0401701a176 100644
--- a/apps/docs/lib/fetch/projectApi.ts
+++ b/apps/docs/lib/fetch/projectApi.ts
@@ -26,7 +26,7 @@ async function getProjectApi({ projectRef }: ProjectApiVariables, signal?: Abort
return data
}
-type ProjectApiData = Awaited
>
+export type ProjectApiData = Awaited>
type ProjectApiError = ResponseError
export function useProjectApiQuery(
diff --git a/apps/docs/lib/helpers.ts b/apps/docs/lib/helpers.ts
index 112898e065a..81e4a187c93 100644
--- a/apps/docs/lib/helpers.ts
+++ b/apps/docs/lib/helpers.ts
@@ -1,4 +1,8 @@
-import { ICommonBase, ICommonItem, ICommonSection } from '../components/reference/Reference.types'
+import type {
+ ICommonBase,
+ ICommonItem,
+ ICommonSection,
+} from '../components/reference/Reference.types'
// menus to render in the SideBar.js (Ref Nav.constants.ts)
export function getPageType(asPath: string) {
diff --git a/apps/docs/lib/mdx/generateRefMarkdown.tsx b/apps/docs/lib/mdx/generateRefMarkdown.tsx
index f30bc10f4fc..bda0debbe01 100644
--- a/apps/docs/lib/mdx/generateRefMarkdown.tsx
+++ b/apps/docs/lib/mdx/generateRefMarkdown.tsx
@@ -5,7 +5,7 @@ import codeHikeTheme from 'config/code-hike.theme.json' assert { type: 'json' }
import matter from 'gray-matter'
import { serialize } from 'next-mdx-remote/serialize'
import remarkGfm from 'remark-gfm'
-import { ICommonMarkdown } from '~/components/reference/Reference.types'
+import type { ICommonMarkdown } from '~/components/reference/Reference.types'
async function generateRefMarkdown(sections: ICommonMarkdown[], slug: string) {
let markdownContent = []
diff --git a/apps/docs/lib/mdx/getConfig.tsx b/apps/docs/lib/mdx/getConfig.tsx
deleted file mode 100644
index fe479b8114b..00000000000
--- a/apps/docs/lib/mdx/getConfig.tsx
+++ /dev/null
@@ -1,33 +0,0 @@
-import specStorageV0 from '~/spec/storage_v0_config.yaml' assert { type: 'yml' }
-import specRealtimeV0 from '~/spec/realtime_v0_config.yaml' assert { type: 'yml' }
-import specAuthV1 from '~/spec/gotrue_v1_config.yaml' assert { type: 'yml' }
-import specAnalyticsV0 from '~/spec/analytics_v0_config.yaml' assert { type: 'yml' }
-import specFunctionsV0 from '~/spec/functions_v0_config.yaml' assert { type: 'yml' }
-
-function getStorageConfigV0() {
- return { ...specStorageV0 }
-}
-
-function getRealtimeConfigV0() {
- return { ...specRealtimeV0 }
-}
-
-function getAuthConfigV1() {
- return { ...specAuthV1 }
-}
-
-function getAnalyticsConfigV0() {
- return { ...specAnalyticsV0 }
-}
-
-function getFunctionsConfigV0() {
- return { ...specFunctionsV0 }
-}
-
-export {
- getStorageConfigV0,
- getRealtimeConfigV0,
- getAuthConfigV1,
- getAnalyticsConfigV0,
- getFunctionsConfigV0,
-}
diff --git a/apps/docs/lib/mdx/handleRefStaticPaths.tsx b/apps/docs/lib/mdx/handleRefStaticPaths.tsx
index 476dce8e22d..344c60256fa 100644
--- a/apps/docs/lib/mdx/handleRefStaticPaths.tsx
+++ b/apps/docs/lib/mdx/handleRefStaticPaths.tsx
@@ -1,4 +1,4 @@
-import { ICommonSection } from '~/components/reference/Reference.types'
+import type { ICommonSection } from '~/components/reference/Reference.types'
async function handleRefGetStaticPaths(sections: ICommonSection[]) {
// In preview environments, don't generate static pages (faster builds)
diff --git a/apps/docs/lib/mdx/handleRefStaticProps.tsx b/apps/docs/lib/mdx/handleRefStaticProps.tsx
index 56c6c159ed0..e2f89f678ac 100644
--- a/apps/docs/lib/mdx/handleRefStaticProps.tsx
+++ b/apps/docs/lib/mdx/handleRefStaticProps.tsx
@@ -1,4 +1,4 @@
-import { ICommonMarkdown, ICommonSection } from '~/components/reference/Reference.types'
+import type { ICommonMarkdown, ICommonSection } from '~/components/reference/Reference.types'
import generateRefMarkdown from '~/lib/mdx/generateRefMarkdown'
async function handleRefStaticProps(sections: ICommonSection[], libraryPath: string) {
diff --git a/apps/docs/lib/mdx/plugins/rehypeLinkTransform.ts b/apps/docs/lib/mdx/plugins/rehypeLinkTransform.ts
index 5eab44f885d..c8cb8dcf532 100644
--- a/apps/docs/lib/mdx/plugins/rehypeLinkTransform.ts
+++ b/apps/docs/lib/mdx/plugins/rehypeLinkTransform.ts
@@ -1,6 +1,6 @@
-import { Element } from 'hast'
+import type { Element } from 'hast'
import { hasProperty } from 'hast-util-has-property'
-import { Node } from 'unist'
+import type { Node } from 'unist'
import { visit } from 'unist-util-visit'
export type UrlTransformFunction = (url: string, node: Element) => string
diff --git a/apps/docs/lib/mdx/plugins/remarkAdmonition.ts b/apps/docs/lib/mdx/plugins/remarkAdmonition.ts
index 79fee5702aa..edde7fe21ca 100644
--- a/apps/docs/lib/mdx/plugins/remarkAdmonition.ts
+++ b/apps/docs/lib/mdx/plugins/remarkAdmonition.ts
@@ -1,7 +1,7 @@
-import { Content, Paragraph, Parent } from 'mdast'
-import { MdxJsxFlowElement } from 'mdast-util-mdx'
-import { AdmonitionProps } from 'ui'
-import { Node } from 'unist'
+import type { Content, Paragraph, Parent } from 'mdast'
+import type { MdxJsxFlowElement } from 'mdast-util-mdx'
+import type { AdmonitionProps } from 'ui'
+import type { Node } from 'unist'
import { visit } from 'unist-util-visit'
/**
diff --git a/apps/docs/lib/mdx/plugins/remarkRemoveTitle.ts b/apps/docs/lib/mdx/plugins/remarkRemoveTitle.ts
index 3dcce035b60..e81587c32b5 100644
--- a/apps/docs/lib/mdx/plugins/remarkRemoveTitle.ts
+++ b/apps/docs/lib/mdx/plugins/remarkRemoveTitle.ts
@@ -1,4 +1,4 @@
-import { Parent } from 'mdast'
+import type { Parent } from 'mdast'
/**
* Removes the top heading from a MD file if
diff --git a/apps/docs/lib/mdx/plugins/remarkTabs.ts b/apps/docs/lib/mdx/plugins/remarkTabs.ts
index 3562c2a6eca..bd5e15be768 100644
--- a/apps/docs/lib/mdx/plugins/remarkTabs.ts
+++ b/apps/docs/lib/mdx/plugins/remarkTabs.ts
@@ -1,6 +1,6 @@
-import { Content, Paragraph, Parent } from 'mdast'
-import { MdxJsxFlowElement } from 'mdast-util-mdx'
-import { Node } from 'unist'
+import type { Content, Paragraph, Parent } from 'mdast'
+import type { MdxJsxFlowElement } from 'mdast-util-mdx'
+import type { Node } from 'unist'
import { visit } from 'unist-util-visit'
/**
diff --git a/apps/docs/lib/refGenerator/helpers.ts b/apps/docs/lib/refGenerator/helpers.ts
index 6a30f0ad918..f377d56155c 100644
--- a/apps/docs/lib/refGenerator/helpers.ts
+++ b/apps/docs/lib/refGenerator/helpers.ts
@@ -1,9 +1,9 @@
-import { TsDoc } from '../../generator/legacy/definitions'
+import type { TsDoc } from '../../generator/legacy/definitions'
import { values, mapValues } from 'lodash'
-import { OpenAPIV3 } from 'openapi-types'
+import type { OpenAPIV3 } from 'openapi-types'
import { flattenSections } from '../helpers'
-import { ICommonItem } from '~/components/reference/Reference.types'
+import type { ICommonItem } from '~/components/reference/Reference.types'
export function extractTsDocNode(nodeToFind: string, definition: any) {
const nodePath = nodeToFind.split('.')
diff --git a/apps/docs/next-env.d.ts b/apps/docs/next-env.d.ts
index 4f11a03dc6c..fd36f9494e2 100644
--- a/apps/docs/next-env.d.ts
+++ b/apps/docs/next-env.d.ts
@@ -1,5 +1,6 @@
///
///
+///
// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.
diff --git a/apps/docs/next.config.mjs b/apps/docs/next.config.mjs
index 762c631aaec..259c5e70ede 100644
--- a/apps/docs/next.config.mjs
+++ b/apps/docs/next.config.mjs
@@ -1,6 +1,7 @@
// @ts-check
import { remarkCodeHike } from '@code-hike/mdx'
import nextMdx from '@next/mdx'
+import os from 'node:os'
import rehypeSlug from 'rehype-slug'
import remarkGfm from 'remark-gfm'
@@ -33,6 +34,7 @@ const withMDX = nextMdx({
})
/** @type {import('next').NextConfig} nextConfig */
+
const nextConfig = {
// Append the default value with md extensions
pageExtensions: ['ts', 'tsx', 'js', 'jsx', 'md', 'mdx'],
@@ -60,17 +62,31 @@ const nextConfig = {
transform: 'lodash/{{member}}',
},
},
- transpilePackages: [
- 'ui',
- 'ui-patterns',
- 'common',
- 'mermaid',
- 'mdx-mermaid',
- 'dayjs',
- 'shared-data',
- 'api-types',
- 'icons',
- ],
+ transpilePackages: ['ui', 'ui-patterns', 'common', 'dayjs', 'shared-data', 'api-types', 'icons'],
+ /**
+ * The SQL to REST API translator relies on libpg-query, which packages a
+ * native Node.js module that wraps the Postgres query parser.
+ *
+ * The default webpack config can't load native modules, so we need a custom
+ * loader for it, which calls process.dlopen to load C++ Addons.
+ *
+ * See https://github.com/eisberg-labs/nextjs-node-loader
+ */
+ webpack: (config) => {
+ config.module.rules.push({
+ test: /\.node$/,
+ use: [
+ {
+ loader: 'nextjs-node-loader',
+ options: {
+ flags: os.constants.dlopen.RTLD_NOW,
+ outputPath: config.output.path,
+ },
+ },
+ ],
+ })
+ return config
+ },
async headers() {
return [
{
@@ -129,6 +145,15 @@ const nextConfig = {
},
]
},
+ typescript: {
+ // WARNING: production builds can successfully complete even there are type errors
+ // Typechecking is checked separately via .github/workflows/typecheck.yml
+ ignoreBuildErrors: true,
+ },
+ eslint: {
+ // We are already running linting via GH action, this will skip linting during production build on Vercel
+ ignoreDuringBuilds: true,
+ },
}
const configExport = () => {
diff --git a/apps/docs/package.json b/apps/docs/package.json
index 2351445488a..b78bc4b2852 100644
--- a/apps/docs/package.json
+++ b/apps/docs/package.json
@@ -10,7 +10,7 @@
"start": "next start",
"lint": "next lint",
"typecheck": "tsc --noEmit",
- "test": "jest --passWithNoTests",
+ "test": "vitest",
"build:sitemap": "node ./internals/generate-sitemap.mjs",
"embeddings": "tsx scripts/search/generate-embeddings.ts",
"embeddings:refresh": "npm run embeddings -- --refresh",
@@ -32,7 +32,7 @@
"@octokit/plugin-paginate-graphql": "^4.0.0",
"@radix-ui/react-accordion": "^1.1.2",
"@supabase/auth-helpers-react": "^0.4.2",
- "@supabase/supabase-js": "^2.41.1",
+ "@supabase/supabase-js": "^2.44.3",
"@tailwindcss/container-queries": "^0.1.1",
"@tanstack/react-query": "^5.13.4",
"common": "*",
@@ -54,8 +54,6 @@
"mdast-util-mdx": "^2.0.0",
"mdast-util-to-markdown": "^1.5.0",
"mdast-util-to-string": "^3.1.1",
- "mdx-mermaid": "2.0.0-rc3",
- "mermaid": "^10.0.2",
"micromark-extension-mdxjs": "^1.0.0",
"next": "^14.2.3",
"next-mdx-remote": "^4.4.1",
@@ -97,12 +95,14 @@
"dotenv": "^16.0.3",
"ejs": "^3.1.10",
"globby": "^13.2.2",
- "jest-environment-jsdom": "^29.7.0",
+ "nextjs-node-loader": "^1.1.5",
"npm-run-all": "^4.1.5",
"openapi-types": "^12.1.3",
"simple-git": "^3.24.0",
"tsconfig": "*",
"tsx": "^4.6.2",
- "typescript": "^5.4.3"
+ "typescript": "^5.5.0",
+ "vite-tsconfig-paths": "^4.3.2",
+ "vitest": "^2.0.2"
}
}
diff --git a/apps/docs/pages/__dev-secret-auth.tsx b/apps/docs/pages/__dev-secret-auth.tsx
index de882c374f1..eccae335bda 100644
--- a/apps/docs/pages/__dev-secret-auth.tsx
+++ b/apps/docs/pages/__dev-secret-auth.tsx
@@ -1,4 +1,4 @@
-import { useRouter } from 'next/router'
+import { useRouter } from 'next/compat/router'
import { Button_Shadcn_ } from 'ui'
import { auth } from '~/lib/userAuth'
diff --git a/apps/docs/pages/_app.tsx b/apps/docs/pages/_app.tsx
index 3ab997f2673..38b19b776fe 100644
--- a/apps/docs/pages/_app.tsx
+++ b/apps/docs/pages/_app.tsx
@@ -4,47 +4,24 @@ import '../styles/main.scss'
import '../styles/new-docs.scss'
import '../styles/prism-okaidia.scss'
-import { ThemeProvider } from 'common'
import MetaFaviconsPagesRouter from 'common/MetaFavicons/pages-router'
import Head from 'next/head'
-import { PortalToast } from 'ui'
-import { PromoToast } from 'ui-patterns/PromoToast'
-import { CommandMenuProvider } from 'ui-patterns/Cmdk'
-import { AuthContainer } from '~/features/auth/auth.client'
-import { QueryClientProvider } from '~/features/data/queryClient.client'
-import { ShortcutPreviewBuild } from '~/features/envs/staging.client'
-import { PageTelemetry } from '~/features/telemetry/telemetry.client'
-import { ThemeSandbox } from '~/features/ui/theme.client'
-import { ScrollRestoration } from '~/features/ui/helpers.scroll.client'
-import SiteLayout from '~/layouts/SiteLayout'
+
import type { AppPropsWithLayout } from '~/types'
+import { GlobalProviders } from '~/features/app.providers'
function MyApp({ Component, pageProps }: AppPropsWithLayout) {
return (
-
+ <>
+ Supabase Docs
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ >
)
}
diff --git a/apps/docs/pages/guides/ai/[[...slug]].tsx b/apps/docs/pages/guides/ai/[[...slug]].tsx
deleted file mode 100644
index a19f8a02e54..00000000000
--- a/apps/docs/pages/guides/ai/[[...slug]].tsx
+++ /dev/null
@@ -1,29 +0,0 @@
-import { type GetStaticPaths, type GetStaticProps, type InferGetStaticPropsType } from 'next'
-import { MDXRemote } from 'next-mdx-remote'
-
-import components from '~/components'
-import { MenuId } from '~/components/Navigation/NavigationMenu/NavigationMenu'
-import Layout from '~/layouts/DefaultGuideLayout'
-import { getGuidesStaticPaths, getGuidesStaticProps } from '~/lib/docs'
-
-export const getStaticPaths = (async () => {
- return getGuidesStaticPaths('ai')
-}) satisfies GetStaticPaths
-
-export const getStaticProps = (async (args) => {
- return getGuidesStaticProps('ai', args)
-}) satisfies GetStaticProps
-
-export default function AiGuide({
- frontmatter,
- mdxSource,
- editLink,
-}: InferGetStaticPropsType) {
- const { hideToc, ...meta } = frontmatter
-
- return (
-
-
-
- )
-}
diff --git a/apps/docs/pages/guides/ai/python/[slug].tsx b/apps/docs/pages/guides/ai/python/[slug].tsx
deleted file mode 100644
index 952e4bfa099..00000000000
--- a/apps/docs/pages/guides/ai/python/[slug].tsx
+++ /dev/null
@@ -1,157 +0,0 @@
-import { CodeHikeConfig, remarkCodeHike } from '@code-hike/mdx'
-import { GetStaticPaths, GetStaticProps } from 'next'
-import { MDXRemote, MDXRemoteSerializeResult } from 'next-mdx-remote'
-import { serialize } from 'next-mdx-remote/serialize'
-import { relative } from 'path'
-import rehypeSlug from 'rehype-slug'
-import remarkGfm from 'remark-gfm'
-import codeHikeTheme from 'config/code-hike.theme.json' assert { type: 'json' }
-import components from '~/components'
-import Layout from '~/layouts/DefaultGuideLayout'
-import { UrlTransformFunction, linkTransform } from '~/lib/mdx/plugins/rehypeLinkTransform'
-import remarkMkDocsAdmonition from '~/lib/mdx/plugins/remarkAdmonition'
-import { removeTitle } from '~/lib/mdx/plugins/remarkRemoveTitle'
-import { MenuId } from '~/components/Navigation/NavigationMenu/NavigationMenu'
-
-// We fetch these docs at build time from an external repo
-const org = 'supabase'
-const repo = 'vecs'
-const branch = 'main'
-const docsDir = 'docs'
-const externalSite = 'https://supabase.github.io/vecs'
-
-// Each external docs page is mapped to a local page
-const pageMap = [
- {
- slug: 'api',
- meta: {
- title: 'API',
- },
- remoteFile: 'api.md',
- },
- {
- slug: 'collections',
- meta: {
- title: 'Collections',
- },
- remoteFile: 'concepts_collections.md',
- },
- {
- slug: 'indexes',
- meta: {
- title: 'Indexes',
- },
- remoteFile: 'concepts_indexes.md',
- },
- {
- slug: 'metadata',
- meta: {
- title: 'Metadata',
- },
- remoteFile: 'concepts_metadata.md',
- },
-]
-
-interface PythonClientDocsProps {
- source: MDXRemoteSerializeResult
- meta: {
- title: string
- description?: string
- }
-}
-
-export default function PythonClientDocs({ source, meta }: PythonClientDocsProps) {
- return (
-
-
-
- )
-}
-
-/**
- * Fetch markdown from external repo and transform links
- */
-export const getStaticProps: GetStaticProps = async ({ params }) => {
- const page = pageMap.find(({ slug }) => slug === params.slug)
-
- if (!page) {
- throw new Error(`No page mapping found for slug '${params.slug}'`)
- }
-
- const { remoteFile, meta } = page
-
- const response = await fetch(
- `https://raw.githubusercontent.com/${org}/${repo}/${branch}/${docsDir}/${remoteFile}`
- )
-
- const source = await response.text()
-
- const urlTransform: UrlTransformFunction = (url) => {
- try {
- const externalSiteUrl = new URL(externalSite)
-
- const placeholderHostname = 'placeholder'
- const { hostname, pathname, hash } = new URL(url, `http://${placeholderHostname}`)
-
- // Don't modify a url with a FQDN or a url that's only a hash
- if (hostname !== placeholderHostname || pathname === '/') {
- return url
- }
-
- const relativePage = (
- pathname.endsWith('.md')
- ? pathname.replace(/\.md$/, '')
- : relative(externalSiteUrl.pathname, pathname)
- ).replace(/^\//, '')
-
- const page = pageMap.find(({ remoteFile }) => `${relativePage}.md` === remoteFile)
-
- // If we have a mapping for this page, use the mapped path
- if (page) {
- return page.slug + hash
- }
-
- // If we don't have this page in our docs, link to original docs
- return `${externalSite}/${relativePage}${hash}`
- } catch (err) {
- console.error('Error transforming markdown URL', err)
- return url
- }
- }
-
- const codeHikeOptions: CodeHikeConfig = {
- theme: codeHikeTheme,
- lineNumbers: true,
- showCopyButton: true,
- skipLanguages: [],
- autoImport: false,
- }
-
- const mdxSource = await serialize(source, {
- scope: {
- chCodeConfig: codeHikeOptions,
- },
- mdxOptions: {
- remarkPlugins: [
- remarkGfm,
- remarkMkDocsAdmonition,
- [removeTitle, meta.title],
- [remarkCodeHike, codeHikeOptions],
- ],
- rehypePlugins: [[linkTransform, urlTransform], rehypeSlug],
- },
- })
-
- return { props: { source: mdxSource, meta } }
-}
-
-export const getStaticPaths: GetStaticPaths = async () => {
- return {
- paths: pageMap.map(({ slug }) => ({
- params: {
- slug,
- },
- })),
- fallback: false,
- }
-}
diff --git a/apps/docs/pages/guides/api/[[...slug]].tsx b/apps/docs/pages/guides/api/[[...slug]].tsx
deleted file mode 100644
index 80b2d9f4e80..00000000000
--- a/apps/docs/pages/guides/api/[[...slug]].tsx
+++ /dev/null
@@ -1,30 +0,0 @@
-import { stripIndent } from 'common-tags'
-import { type GetStaticPaths, type GetStaticProps, type InferGetStaticPropsType } from 'next'
-import { MDXRemote } from 'next-mdx-remote'
-
-import components from '~/components'
-import { MenuId } from '~/components/Navigation/NavigationMenu/NavigationMenu'
-import Layout from '~/layouts/DefaultGuideLayout'
-import { getGuidesStaticPaths, getGuidesStaticProps } from '~/lib/docs'
-
-export const getStaticPaths = (async () => {
- return getGuidesStaticPaths('api')
-}) satisfies GetStaticPaths
-
-export const getStaticProps = (async (args) => {
- return getGuidesStaticProps('api', args)
-}) satisfies GetStaticProps
-
-export default function ApiGuide({
- frontmatter,
- mdxSource,
- editLink,
-}: InferGetStaticPropsType) {
- const { hideToc, ...meta } = frontmatter
-
- return (
-
-
-
- )
-}
diff --git a/apps/docs/pages/guides/auth/[[...slug]].tsx b/apps/docs/pages/guides/auth/[[...slug]].tsx
deleted file mode 100644
index 9e645a917ea..00000000000
--- a/apps/docs/pages/guides/auth/[[...slug]].tsx
+++ /dev/null
@@ -1,29 +0,0 @@
-import { type GetStaticPaths, type GetStaticProps, type InferGetStaticPropsType } from 'next'
-import { MDXRemote } from 'next-mdx-remote'
-
-import components from '~/components'
-import { MenuId } from '~/components/Navigation/NavigationMenu/NavigationMenu'
-import Layout from '~/layouts/DefaultGuideLayout'
-import { getGuidesStaticPaths, getGuidesStaticProps } from '~/lib/docs'
-
-export const getStaticPaths = (async () => {
- return getGuidesStaticPaths('auth')
-}) satisfies GetStaticPaths
-
-export const getStaticProps = (async (args) => {
- return getGuidesStaticProps('auth', args)
-}) satisfies GetStaticProps
-
-export default function AuthGuide({
- frontmatter,
- mdxSource,
- editLink,
-}: InferGetStaticPropsType) {
- const { hideToc, ...meta } = frontmatter
-
- return (
-
-
-
- )
-}
diff --git a/apps/docs/pages/guides/cli/[[...slug]].tsx b/apps/docs/pages/guides/cli/[[...slug]].tsx
deleted file mode 100644
index 2dd168f672d..00000000000
--- a/apps/docs/pages/guides/cli/[[...slug]].tsx
+++ /dev/null
@@ -1,29 +0,0 @@
-import { type GetStaticPaths, type GetStaticProps, type InferGetStaticPropsType } from 'next'
-import { MDXRemote } from 'next-mdx-remote'
-
-import components from '~/components'
-import { MenuId } from '~/components/Navigation/NavigationMenu/NavigationMenu'
-import Layout from '~/layouts/DefaultGuideLayout'
-import { getGuidesStaticPaths, getGuidesStaticProps } from '~/lib/docs'
-
-export const getStaticPaths = (async () => {
- return getGuidesStaticPaths('cli')
-}) satisfies GetStaticPaths
-
-export const getStaticProps = (async (args) => {
- return getGuidesStaticProps('cli', args)
-}) satisfies GetStaticProps
-
-export default function CliGuide({
- frontmatter,
- mdxSource,
- editLink,
-}: InferGetStaticPropsType) {
- const { hideToc, ...meta } = frontmatter
-
- return (
-
-
-
- )
-}
diff --git a/apps/docs/pages/guides/cli/github-action/[slug].tsx b/apps/docs/pages/guides/cli/github-action/[slug].tsx
deleted file mode 100644
index d06701295e5..00000000000
--- a/apps/docs/pages/guides/cli/github-action/[slug].tsx
+++ /dev/null
@@ -1,159 +0,0 @@
-import { CodeHikeConfig, remarkCodeHike } from '@code-hike/mdx'
-import { GetStaticPaths, GetStaticProps } from 'next'
-import { MDXRemote, MDXRemoteSerializeResult } from 'next-mdx-remote'
-import { serialize } from 'next-mdx-remote/serialize'
-import { relative } from 'path'
-import rehypeSlug from 'rehype-slug'
-import remarkGfm from 'remark-gfm'
-import codeHikeTheme from 'config/code-hike.theme.json' assert { type: 'json' }
-import components from '~/components'
-import Layout from '~/layouts/DefaultGuideLayout'
-import { UrlTransformFunction, linkTransform } from '~/lib/mdx/plugins/rehypeLinkTransform'
-import remarkMkDocsAdmonition from '~/lib/mdx/plugins/remarkAdmonition'
-import { removeTitle } from '~/lib/mdx/plugins/remarkRemoveTitle'
-import remarkPyMdownTabs from '~/lib/mdx/plugins/remarkTabs'
-import { MenuId } from '~/components/Navigation/NavigationMenu/NavigationMenu'
-
-// We fetch these docs at build time from an external repo
-const org = 'supabase'
-const repo = 'setup-cli'
-const branch = 'gh-pages'
-const docsDir = 'docs'
-const externalSite = 'https://supabase.github.io/setup-cli'
-
-// Each external docs page is mapped to a local page
-const pageMap = [
- {
- slug: 'generating-types',
- meta: {
- title: 'Generate types using GitHub Actions',
- description: 'End-to-end type safety across client, server, and database.',
- subtitle: 'End-to-end type safety across client, server, and database.',
- tocVideo: 'VSNgAIObBdw',
- },
- remoteFile: 'generating-types.md',
- },
- {
- slug: 'testing',
- meta: {
- title: 'Automated testing using GitHub Actions',
- description: 'Run your tests when you or your team make changes.',
- subtitle: 'Run your tests when you or your team make changes.',
- },
- remoteFile: 'testing.md',
- },
- {
- slug: 'backups',
- meta: {
- title: 'Automated backups using GitHub Actions',
- description: 'Backup your database on a regular basis.',
- subtitle: 'Backup your database on a regular basis.',
- },
- remoteFile: 'backups.md',
- },
-]
-
-interface ActionDocsProps {
- source: MDXRemoteSerializeResult
- meta: {
- title: string
- description?: string
- }
-}
-
-export default function ActionDocs({ source, meta }: ActionDocsProps) {
- return (
-
-
-
- )
-}
-
-/**
- * Fetch markdown from external repo and transform links
- */
-export const getStaticProps: GetStaticProps = async ({ params }) => {
- const page = pageMap.find(({ slug }) => slug === params.slug)
-
- if (!page) {
- throw new Error(`No page mapping found for slug '${params.slug}'`)
- }
-
- const { remoteFile, meta } = page
-
- const response = await fetch(
- `https://raw.githubusercontent.com/${org}/${repo}/${branch}/${docsDir}/${remoteFile}`
- )
-
- const source = await response.text()
-
- const urlTransform: UrlTransformFunction = (url) => {
- try {
- const externalSiteUrl = new URL(externalSite)
-
- const placeholderHostname = 'placeholder'
- const { hostname, pathname, hash } = new URL(url, `http://${placeholderHostname}`)
-
- // Don't modify a url with a FQDN or a url that's only a hash
- if (hostname !== placeholderHostname || pathname === '/') {
- return url
- }
-
- const relativePage = (
- pathname.endsWith('.md')
- ? pathname.replace(/\.md$/, '')
- : relative(externalSiteUrl.pathname, pathname)
- ).replace(/^\//, '')
-
- const page = pageMap.find(({ remoteFile }) => `${relativePage}.md` === remoteFile)
-
- // If we have a mapping for this page, use the mapped path
- if (page) {
- return page.slug + hash
- }
-
- // If we don't have this page in our docs, link to original docs
- return `${externalSite}/${relativePage}${hash}`
- } catch (err) {
- console.error('Error transforming markdown URL', err)
- return url
- }
- }
-
- const codeHikeOptions: CodeHikeConfig = {
- theme: codeHikeTheme,
- lineNumbers: true,
- showCopyButton: true,
- skipLanguages: [],
- autoImport: false,
- }
-
- const mdxSource = await serialize(source, {
- scope: {
- chCodeConfig: codeHikeOptions,
- },
- mdxOptions: {
- remarkPlugins: [
- remarkGfm,
- remarkMkDocsAdmonition,
- remarkPyMdownTabs,
- [removeTitle, meta.title],
- [remarkCodeHike, codeHikeOptions],
- ],
- rehypePlugins: [[linkTransform, urlTransform], rehypeSlug],
- },
- })
-
- return { props: { source: mdxSource, meta } }
-}
-
-export const getStaticPaths: GetStaticPaths = async () => {
- return {
- paths: pageMap.map(({ slug }) => ({
- params: {
- slug,
- },
- })),
- fallback: false,
- }
-}
diff --git a/apps/docs/pages/guides/database/[[...slug]].tsx b/apps/docs/pages/guides/database/[[...slug]].tsx
deleted file mode 100644
index 0ee6416477b..00000000000
--- a/apps/docs/pages/guides/database/[[...slug]].tsx
+++ /dev/null
@@ -1,39 +0,0 @@
-import { type GetStaticPaths, type GetStaticProps, type InferGetStaticPropsType } from 'next'
-import { MDXRemote } from 'next-mdx-remote'
-
-import components from '~/components'
-import { MenuId } from '~/components/Navigation/NavigationMenu/NavigationMenu'
-import Layout from '~/layouts/DefaultGuideLayout'
-import { getGuidesStaticPaths, getGuidesStaticProps } from '~/lib/docs'
-
-export const getStaticPaths = (async () => {
- const paths = await getGuidesStaticPaths('database')
-
- /**
- * Wrappers is special, so remove it
- * Needs to be handled within its own subdirectory or won't build on dev
- */
- paths.paths = paths.paths.filter(
- ({ params }) => !(params.slug.at(0) === 'extensions' && params.slug.at(1) === 'wrappers')
- )
-
- return paths
-}) satisfies GetStaticPaths
-
-export const getStaticProps = (async (args) => {
- return getGuidesStaticProps('database', args)
-}) satisfies GetStaticProps
-
-export default function DatabaseGuide({
- frontmatter,
- mdxSource,
- editLink,
-}: InferGetStaticPropsType) {
- const { hideToc, ...meta } = frontmatter
-
- return (
-
-
-
- )
-}
diff --git a/apps/docs/pages/guides/database/extensions/wrappers/[[...slug]].tsx b/apps/docs/pages/guides/database/extensions/wrappers/[[...slug]].tsx
deleted file mode 100644
index 3879c045049..00000000000
--- a/apps/docs/pages/guides/database/extensions/wrappers/[[...slug]].tsx
+++ /dev/null
@@ -1,212 +0,0 @@
-import { CodeHikeConfig, remarkCodeHike } from '@code-hike/mdx'
-import { GetStaticPaths, GetStaticProps, InferGetStaticPropsType } from 'next'
-import { MDXRemote } from 'next-mdx-remote'
-import { serialize } from 'next-mdx-remote/serialize'
-import { relative } from 'node:path'
-import rehypeSlug from 'rehype-slug'
-import emoji from 'remark-emoji'
-import remarkGfm from 'remark-gfm'
-
-import codeHikeTheme from 'config/code-hike.theme.json' assert { type: 'json' }
-
-import components from '~/components'
-import { MenuId } from '~/components/Navigation/NavigationMenu/NavigationMenu'
-import Layout from '~/layouts/DefaultGuideLayout'
-import { getGuidesStaticPaths, getGuidesStaticProps } from '~/lib/docs'
-import { UrlTransformFunction, linkTransform } from '~/lib/mdx/plugins/rehypeLinkTransform'
-import remarkMkDocsAdmonition from '~/lib/mdx/plugins/remarkAdmonition'
-import { removeTitle } from '~/lib/mdx/plugins/remarkRemoveTitle'
-import remarkPyMdownTabs from '~/lib/mdx/plugins/remarkTabs'
-
-// We fetch these docs at build time from an external repo
-const org = 'supabase'
-const repo = 'wrappers'
-const branch = 'main'
-const docsDir = 'docs'
-const externalSite = 'https://supabase.github.io/wrappers'
-
-// Each external docs page is mapped to a local page
-const pageMap = [
- {
- slug: 'airtable',
- meta: {
- title: 'Airtable',
- },
- remoteFile: 'airtable.md',
- },
- {
- slug: 'auth0',
- meta: {
- title: 'Auth0',
- },
- remoteFile: 'auth0.md',
- },
- {
- slug: 'bigquery',
- meta: {
- title: 'BigQuery',
- },
- remoteFile: 'bigquery.md',
- },
- {
- slug: 'clickhouse',
- meta: {
- title: 'ClickHouse',
- },
- remoteFile: 'clickhouse.md',
- },
- {
- slug: 'cognito',
- meta: {
- title: 'AWS Cognito',
- },
- remoteFile: 'cognito.md',
- },
- {
- slug: 'firebase',
- meta: {
- title: 'Firebase',
- },
- remoteFile: 'firebase.md',
- },
- {
- slug: 'logflare',
- meta: {
- title: 'Logflare',
- },
- remoteFile: 'logflare.md',
- },
- {
- slug: 'mssql',
- meta: {
- title: 'MSSQL',
- },
- remoteFile: 'mssql.md',
- },
- {
- slug: 'redis',
- meta: {
- title: 'Redis',
- },
- remoteFile: 'redis.md',
- },
- {
- slug: 's3',
- meta: {
- title: 'AWS S3',
- },
- remoteFile: 's3.md',
- },
- {
- slug: 'stripe',
- meta: {
- title: 'Stripe',
- },
- remoteFile: 'stripe.md',
- },
-]
-
-export default function WrappersDocs({
- source,
- meta,
- editLink,
-}: InferGetStaticPropsType) {
- return (
-
-
-
- )
-}
-
-/**
- * Fetch markdown from external repo and transform links
- */
-export const getStaticProps: GetStaticProps = async (args) => {
- const { params } = args
- const federatedPage = pageMap.find(({ slug }) => slug === params.slug.at(0))
-
- if (!federatedPage) {
- const { props } = await getGuidesStaticProps('database/extensions/wrappers', args)
- return {
- props: {
- source: props.mdxSource,
- meta: props.frontmatter,
- },
- }
- }
-
- const { remoteFile, meta } = federatedPage
- const repoPath = `${org}/${repo}/${branch}/${docsDir}/${remoteFile}`
- const repoEditPath = `${org}/${repo}/blob/${branch}/${docsDir}/${remoteFile}`
- const response = await fetch(`https://raw.githubusercontent.com/${repoPath}`)
-
- const source = await response.text()
-
- const urlTransform: UrlTransformFunction = (url) => {
- try {
- const externalSiteUrl = new URL(externalSite)
-
- const placeholderHostname = 'placeholder'
- const { hostname, pathname, hash } = new URL(url, `http://${placeholderHostname}`)
-
- // Don't modify a url with a FQDN or a url that's only a hash
- if (hostname !== placeholderHostname || pathname === '/') {
- return url
- }
- const relativePage = (
- pathname.endsWith('.md')
- ? pathname.replace(/\.md$/, '')
- : relative(externalSiteUrl.pathname, pathname)
- ).replace(/^\//, '')
-
- const page = pageMap.find(({ remoteFile }) => `${relativePage}.md` === remoteFile)
-
- // If we have a mapping for this page, use the mapped path
- if (page) {
- return page.slug + hash
- }
-
- // If we don't have this page in our docs, link to original docs
- return `${externalSite}/${relativePage}${hash}`
- } catch (err) {
- console.error('Error transforming markdown URL', err)
- return url
- }
- }
-
- const codeHikeOptions: CodeHikeConfig = {
- theme: codeHikeTheme,
- lineNumbers: true,
- showCopyButton: true,
- skipLanguages: [],
- autoImport: false,
- }
-
- const mdxSource = await serialize(source, {
- scope: {
- chCodeConfig: codeHikeOptions,
- },
- mdxOptions: {
- remarkPlugins: [
- remarkGfm,
- remarkMkDocsAdmonition,
- emoji,
- remarkPyMdownTabs,
- [removeTitle, meta.title],
- [remarkCodeHike, codeHikeOptions],
- ],
- rehypePlugins: [[linkTransform, urlTransform], rehypeSlug],
- },
- })
-
- return { props: { source: mdxSource, meta, editLink: repoEditPath } }
-}
-
-export const getStaticPaths: GetStaticPaths = async () => {
- const mdxPaths = (await getGuidesStaticPaths('database/extensions/wrappers')).paths
- const federatedPaths = pageMap.map(({ slug }) => ({ params: { slug: [slug] } }))
- return {
- paths: [...federatedPaths, ...mdxPaths],
- fallback: false,
- }
-}
diff --git a/apps/docs/pages/guides/functions/[[...slug]].tsx b/apps/docs/pages/guides/functions/[[...slug]].tsx
deleted file mode 100644
index 8a8ed0defd2..00000000000
--- a/apps/docs/pages/guides/functions/[[...slug]].tsx
+++ /dev/null
@@ -1,29 +0,0 @@
-import { type GetStaticPaths, type GetStaticProps, type InferGetStaticPropsType } from 'next'
-import { MDXRemote } from 'next-mdx-remote'
-
-import components from '~/components'
-import { MenuId } from '~/components/Navigation/NavigationMenu/NavigationMenu'
-import Layout from '~/layouts/DefaultGuideLayout'
-import { getGuidesStaticPaths, getGuidesStaticProps } from '~/lib/docs'
-
-export const getStaticPaths = (async () => {
- return getGuidesStaticPaths('functions')
-}) satisfies GetStaticPaths
-
-export const getStaticProps = (async (args) => {
- return getGuidesStaticProps('functions', args)
-}) satisfies GetStaticProps
-
-export default function FunctionsGuide({
- frontmatter,
- mdxSource,
- editLink,
-}: InferGetStaticPropsType) {
- const { hideToc, ...meta } = frontmatter
-
- return (
-
-
-
- )
-}
diff --git a/apps/docs/pages/guides/getting-started/[[...slug]].tsx b/apps/docs/pages/guides/getting-started/[[...slug]].tsx
deleted file mode 100644
index e16c15ac68f..00000000000
--- a/apps/docs/pages/guides/getting-started/[[...slug]].tsx
+++ /dev/null
@@ -1,29 +0,0 @@
-import { type GetStaticPaths, type GetStaticProps, type InferGetStaticPropsType } from 'next'
-import { MDXRemote } from 'next-mdx-remote'
-
-import components from '~/components'
-import { MenuId } from '~/components/Navigation/NavigationMenu/NavigationMenu'
-import Layout from '~/layouts/DefaultGuideLayout'
-import { getGuidesStaticPaths, getGuidesStaticProps } from '~/lib/docs'
-
-export const getStaticPaths = (async () => {
- return getGuidesStaticPaths('getting-started')
-}) satisfies GetStaticPaths
-
-export const getStaticProps = (async (args) => {
- return getGuidesStaticProps('getting-started', args)
-}) satisfies GetStaticProps
-
-export default function GettingStartedGuide({
- frontmatter,
- mdxSource,
- editLink,
-}: InferGetStaticPropsType) {
- const { hideToc, ...meta } = frontmatter
-
- return (
-
-
-
- )
-}
diff --git a/apps/docs/pages/guides/graphql/[[...slug]].tsx b/apps/docs/pages/guides/graphql/[[...slug]].tsx
deleted file mode 100644
index 00eaecfe221..00000000000
--- a/apps/docs/pages/guides/graphql/[[...slug]].tsx
+++ /dev/null
@@ -1,220 +0,0 @@
-import { CodeHikeConfig, remarkCodeHike } from '@code-hike/mdx'
-import { GetStaticPaths, GetStaticProps } from 'next'
-import { MDXRemote, MDXRemoteSerializeResult } from 'next-mdx-remote'
-import { serialize } from 'next-mdx-remote/serialize'
-import { isAbsolute, relative } from 'path'
-import rehypeSlug from 'rehype-slug'
-import remarkGfm from 'remark-gfm'
-
-import components from '~/components'
-import { MenuId } from '~/components/Navigation/NavigationMenu/NavigationMenu'
-import Layout from '~/layouts/DefaultGuideLayout'
-import { UrlTransformFunction, linkTransform } from '~/lib/mdx/plugins/rehypeLinkTransform'
-import remarkMkDocsAdmonition from '~/lib/mdx/plugins/remarkAdmonition'
-import { removeTitle } from '~/lib/mdx/plugins/remarkRemoveTitle'
-import remarkPyMdownTabs from '~/lib/mdx/plugins/remarkTabs'
-
-import codeHikeTheme from 'config/code-hike.theme.json' assert { type: 'json' }
-
-// We fetch these docs at build time from an external repo
-const org = 'supabase'
-const repo = 'pg_graphql'
-const branch = 'master'
-const docsDir = 'docs'
-const externalSite = 'https://supabase.github.io/pg_graphql'
-
-// Each external docs page is mapped to a local page
-const pageMap = [
- {
- meta: {
- id: 'graphql-overview',
- title: 'GraphQL',
- subtitle: 'Autogenerated GraphQL APIs with Postgres.',
- },
- remoteFile: 'supabase.md',
- },
- {
- slug: 'api',
- meta: {
- id: 'graphql-api',
- title: 'GraphQL API',
- subtitle: 'Understanding the core concepts of the GraphQL API.',
- },
- remoteFile: 'api.md',
- },
- {
- slug: 'views',
- meta: {
- id: 'graphql-views',
- title: 'Views',
- subtitle: 'Using Postgres Views with GraphQL.',
- },
- remoteFile: 'views.md',
- },
- {
- slug: 'functions',
- meta: {
- id: 'graphql-functions',
- title: 'Functions',
- subtitle: 'Using Postgres Functions with GraphQL.',
- },
- remoteFile: 'functions.md',
- },
- {
- slug: 'computed-fields',
- meta: {
- id: 'graphql-computed-fields',
- title: 'Computed Fields',
- subtitle: 'Using Postgres Computed Fields with GraphQL.',
- },
- remoteFile: 'computed-fields.md',
- },
- {
- slug: 'configuration',
- meta: {
- id: 'graphql-configuration',
- title: 'Configuration & Customization',
- subtitle: 'Extra configuration options can be set on SQL entities using comment directives.',
- },
- remoteFile: 'configuration.md',
- },
- {
- slug: 'security',
- meta: {
- id: 'graphql-security',
- title: 'Security',
- subtitle: 'Securing your GraphQL API.',
- },
- remoteFile: 'security.md',
- },
- {
- slug: 'with-apollo',
- meta: {
- id: 'graphql-with-apollo',
- title: 'With Apollo',
- subtitle: 'Using pg_grapqhl with Apollo.',
- },
- remoteFile: 'usage_with_apollo.md',
- },
- {
- slug: 'with-relay',
- meta: {
- id: 'graphql-with-relay',
- title: 'With Relay',
- subtitle: 'Using pg_grapqhl with Relay.',
- },
- remoteFile: 'usage_with_relay.md',
- },
-]
-
-interface PGGraphQLDocsProps {
- source: MDXRemoteSerializeResult
- meta: {
- title: string
- description?: string
- }
-}
-
-export default function PGGraphQLDocs({ source, meta }: PGGraphQLDocsProps) {
- return (
-
-
-
- )
-}
-
-/**
- * Fetch markdown from external repo and transform links
- */
-export const getStaticProps: GetStaticProps = async ({ params }) => {
- const [slug] = params.slug ?? []
- const page = pageMap.find((page) => page.slug === slug)
-
- if (!page) {
- throw new Error(`No page mapping found for slug '${slug}'`)
- }
-
- const { remoteFile, meta } = page
-
- const response = await fetch(
- `https://raw.githubusercontent.com/${org}/${repo}/${branch}/${docsDir}/${remoteFile}`
- )
-
- const source = await response.text()
-
- const urlTransform: UrlTransformFunction = (url) => {
- try {
- const externalSiteUrl = new URL(externalSite)
-
- const placeholderHostname = 'placeholder'
- const { hostname, pathname, hash } = new URL(url, `http://${placeholderHostname}`)
-
- // Don't modify a url with a FQDN or a url that's only a hash
- if (hostname !== placeholderHostname || pathname === '/') {
- return url
- }
-
- const getRelativePath = () => {
- if (pathname.endsWith('.md')) {
- return pathname.replace(/\.md$/, '')
- }
- if (isAbsolute(url)) {
- return relative(externalSiteUrl.pathname, pathname)
- }
- return pathname
- }
-
- const relativePath = getRelativePath().replace(/^\//, '')
-
- const page = pageMap.find(({ remoteFile }) => `${relativePath}.md` === remoteFile)
-
- // If we have a mapping for this page, use the mapped path
- if (page) {
- return 'graphql/' + page.slug + hash
- }
-
- // If we don't have this page in our docs, link to original docs
- return `${externalSite}/${relativePath}${hash}`
- } catch (err) {
- console.error('Error transforming markdown URL', err)
- return url
- }
- }
-
- const codeHikeOptions: CodeHikeConfig = {
- theme: codeHikeTheme,
- lineNumbers: true,
- showCopyButton: true,
- skipLanguages: [],
- autoImport: false,
- }
-
- const mdxSource = await serialize(source, {
- scope: {
- chCodeConfig: codeHikeOptions,
- },
- mdxOptions: {
- remarkPlugins: [
- remarkGfm,
- remarkMkDocsAdmonition,
- remarkPyMdownTabs,
- [removeTitle, meta.title],
- [remarkCodeHike, codeHikeOptions],
- ],
- rehypePlugins: [[linkTransform, urlTransform], rehypeSlug],
- },
- })
-
- return { props: { source: mdxSource, meta } }
-}
-
-export const getStaticPaths: GetStaticPaths = async () => {
- return {
- paths: pageMap.map(({ slug }) => ({
- params: {
- slug: slug ? [slug] : [],
- },
- })),
- fallback: false,
- }
-}
diff --git a/apps/docs/pages/guides/platform/[[...slug]].tsx b/apps/docs/pages/guides/platform/[[...slug]].tsx
deleted file mode 100644
index f20307d7974..00000000000
--- a/apps/docs/pages/guides/platform/[[...slug]].tsx
+++ /dev/null
@@ -1,29 +0,0 @@
-import { type GetStaticPaths, type GetStaticProps, type InferGetStaticPropsType } from 'next'
-import { MDXRemote } from 'next-mdx-remote'
-
-import components from '~/components'
-import { MenuId } from '~/components/Navigation/NavigationMenu/NavigationMenu'
-import Layout from '~/layouts/DefaultGuideLayout'
-import { getGuidesStaticPaths, getGuidesStaticProps } from '~/lib/docs'
-
-export const getStaticPaths = (async () => {
- return getGuidesStaticPaths('platform')
-}) satisfies GetStaticPaths
-
-export const getStaticProps = (async (args) => {
- return getGuidesStaticProps('platform', args)
-}) satisfies GetStaticProps
-
-export default function PlatformGuide({
- frontmatter,
- mdxSource,
- editLink,
-}: InferGetStaticPropsType) {
- const { hideToc, ...meta } = frontmatter
-
- return (
-
-
-
- )
-}
diff --git a/apps/docs/pages/guides/platform/terraform/[[...slug]].tsx b/apps/docs/pages/guides/platform/terraform/[[...slug]].tsx
deleted file mode 100644
index 1eb6d14123f..00000000000
--- a/apps/docs/pages/guides/platform/terraform/[[...slug]].tsx
+++ /dev/null
@@ -1,167 +0,0 @@
-import { CodeHikeConfig, remarkCodeHike } from '@code-hike/mdx'
-import matter from 'gray-matter'
-import { GetStaticPaths, GetStaticProps, InferGetStaticPropsType } from 'next'
-import { MDXRemote } from 'next-mdx-remote'
-import { serialize } from 'next-mdx-remote/serialize'
-import remarkGfm from 'remark-gfm'
-import rehypeSlug from 'rehype-slug'
-
-import codeHikeTheme from 'config/code-hike.theme.json' assert { type: 'json' }
-
-import components from '~/components'
-import { MenuId } from '~/components/Navigation/NavigationMenu/NavigationMenu'
-import Layout from '~/layouts/DefaultGuideLayout'
-import { isValidGuideFrontmatter } from '~/lib/docs'
-import { UrlTransformFunction, linkTransform } from '~/lib/mdx/plugins/rehypeLinkTransform'
-import remarkMkDocsAdmonition from '~/lib/mdx/plugins/remarkAdmonition'
-import { removeTitle } from '~/lib/mdx/plugins/remarkRemoveTitle'
-import remarkPyMdownTabs from '~/lib/mdx/plugins/remarkTabs'
-
-// We fetch these docs at build time from an external repo
-export const org = 'supabase'
-export const repo = 'terraform-provider-supabase'
-export const branch = 'v1.1.3'
-export const docsDir = 'docs'
-
-// Each external docs page is mapped to a local page
-const pageMap = [
- {
- remoteFile: 'README.md',
- meta: {
- title: 'Terraform Provider',
- },
- useRoot: true,
- },
- {
- slug: 'tutorial',
- remoteFile: 'tutorial.md',
- meta: {
- title: 'Using the Supabase Terraform Provider',
- },
- },
-]
-
-export default function TerraformDocs({
- source,
- meta,
- editLink,
-}: InferGetStaticPropsType) {
- return (
-
-
-
- )
-}
-
-/**
- * The GitHub repo uses relative links, which don't lead to the right locations
- * in docs.
- *
- * @param url The original link, as written in the Markdown file
- * @returns The rewritten link
- */
-const urlTransform: UrlTransformFunction = (url: string) => {
- try {
- const placeholderHostname = 'placeholder'
- const { hostname, pathname, hash } = new URL(url, `http://${placeholderHostname}`)
-
- // Don't modify a url with a FQDN or a url that's only a hash
- if (hostname !== placeholderHostname || pathname === '/') {
- return url
- }
-
- const getBasename = (pathname: string) =>
- pathname.endsWith('.md') ? pathname.replace(/\.md$/, '') : pathname
- const stripLeadingPrefix = (pathname: string) => pathname.replace(/^\//, '')
- const stripLeadingDocs = (pathname: string) => pathname.replace(/^docs\//, '')
-
- const relativePath = stripLeadingPrefix(getBasename(pathname))
-
- const page = pageMap.find(
- ({ remoteFile, useRoot }) =>
- (useRoot && `${relativePath}.md` === remoteFile) ||
- (!useRoot && `${stripLeadingDocs(relativePath)}.md` === remoteFile)
- )
-
- if (page) {
- return 'terraform' + `/${page.slug}` + hash
- }
-
- // If we don't have this page in our docs, link to GitHub repo
- return `https://github.com/${org}/${repo}/blob/${branch}${pathname}${hash}`
- } catch (err) {
- console.error('Error transforming markdown URL', err)
- return url
- }
-}
-
-/**
- * Fetch markdown from external repo and transform links
- */
-export const getStaticProps = (async ({ params }) => {
- const [slug] = params.slug ?? []
- const page = pageMap.find((page) => page.slug === slug)
-
- if (!page) {
- throw new Error(`No page mapping found for slug '${slug}'`)
- }
-
- const { meta, remoteFile, useRoot } = page
-
- let response = await fetch(
- `https://raw.githubusercontent.com/${org}/${repo}/${branch}/${useRoot ? '' : `${docsDir}/`}${remoteFile}`
- )
-
- let content = await response.text()
- // Strip out HTML comments
- content = content.replace(//, '')
- const { content: source, data } = matter(content)
- Object.assign(meta, data)
-
- if (!isValidGuideFrontmatter(meta)) {
- throw Error('Guide frontmatter is invalid.')
- }
-
- const codeHikeOptions: CodeHikeConfig = {
- theme: codeHikeTheme,
- lineNumbers: true,
- showCopyButton: true,
- skipLanguages: [],
- autoImport: false,
- }
-
- const mdxSource = await serialize(source, {
- scope: {
- chCodeConfig: codeHikeOptions,
- },
- mdxOptions: {
- remarkPlugins: [
- remarkGfm,
- remarkMkDocsAdmonition,
- remarkPyMdownTabs,
- [removeTitle, meta.title],
- [remarkCodeHike, codeHikeOptions],
- ],
- rehypePlugins: [[linkTransform, urlTransform], rehypeSlug],
- },
- })
-
- return {
- props: {
- source: mdxSource,
- meta,
- editLink: `${org}/${repo}/blob/${branch}/${docsDir}/${slug}.md`,
- },
- }
-}) satisfies GetStaticProps
-
-export const getStaticPaths = (async () => {
- return {
- paths: pageMap.map(({ slug }) => ({
- params: {
- slug: slug ? [slug] : [],
- },
- })),
- fallback: false,
- }
-}) satisfies GetStaticPaths
diff --git a/apps/docs/pages/guides/realtime/[[...slug]].tsx b/apps/docs/pages/guides/realtime/[[...slug]].tsx
deleted file mode 100644
index 3a90134f5ad..00000000000
--- a/apps/docs/pages/guides/realtime/[[...slug]].tsx
+++ /dev/null
@@ -1,29 +0,0 @@
-import { type GetStaticPaths, type GetStaticProps, type InferGetStaticPropsType } from 'next'
-import { MDXRemote } from 'next-mdx-remote'
-
-import components from '~/components'
-import { MenuId } from '~/components/Navigation/NavigationMenu/NavigationMenu'
-import Layout from '~/layouts/DefaultGuideLayout'
-import { getGuidesStaticPaths, getGuidesStaticProps } from '~/lib/docs'
-
-export const getStaticPaths = (async () => {
- return getGuidesStaticPaths('realtime')
-}) satisfies GetStaticPaths
-
-export const getStaticProps = (async (args) => {
- return getGuidesStaticProps('realtime', args)
-}) satisfies GetStaticProps
-
-export default function RealtimeGuide({
- frontmatter,
- mdxSource,
- editLink,
-}: InferGetStaticPropsType) {
- const { hideToc, ...meta } = frontmatter
-
- return (
-
-
-
- )
-}
diff --git a/apps/docs/pages/guides/resources/[[...slug]].tsx b/apps/docs/pages/guides/resources/[[...slug]].tsx
deleted file mode 100644
index d73ad930fe5..00000000000
--- a/apps/docs/pages/guides/resources/[[...slug]].tsx
+++ /dev/null
@@ -1,29 +0,0 @@
-import { type GetStaticPaths, type GetStaticProps, type InferGetStaticPropsType } from 'next'
-import { MDXRemote } from 'next-mdx-remote'
-
-import components from '~/components'
-import { MenuId } from '~/components/Navigation/NavigationMenu/NavigationMenu'
-import Layout from '~/layouts/DefaultGuideLayout'
-import { getGuidesStaticPaths, getGuidesStaticProps } from '~/lib/docs'
-
-export const getStaticPaths = (async () => {
- return getGuidesStaticPaths('resources')
-}) satisfies GetStaticPaths
-
-export const getStaticProps = (async (args) => {
- return getGuidesStaticProps('resources', args)
-}) satisfies GetStaticProps
-
-export default function ResourcesGuide({
- frontmatter,
- mdxSource,
- editLink,
-}: InferGetStaticPropsType) {
- const { hideToc, ...meta } = frontmatter
-
- return (
-
-
-
- )
-}
diff --git a/apps/docs/pages/guides/self-hosting/[[...slug]].tsx b/apps/docs/pages/guides/self-hosting/[[...slug]].tsx
deleted file mode 100644
index c63d1c13b75..00000000000
--- a/apps/docs/pages/guides/self-hosting/[[...slug]].tsx
+++ /dev/null
@@ -1,29 +0,0 @@
-import { type GetStaticPaths, type GetStaticProps, type InferGetStaticPropsType } from 'next'
-import { MDXRemote } from 'next-mdx-remote'
-
-import components from '~/components'
-import { MenuId } from '~/components/Navigation/NavigationMenu/NavigationMenu'
-import Layout from '~/layouts/DefaultGuideLayout'
-import { getGuidesStaticPaths, getGuidesStaticProps } from '~/lib/docs'
-
-export const getStaticPaths = (async () => {
- return getGuidesStaticPaths('self-hosting')
-}) satisfies GetStaticPaths
-
-export const getStaticProps = (async (args) => {
- return getGuidesStaticProps('self-hosting', args)
-}) satisfies GetStaticProps
-
-export default function SelfHostingGuide({
- frontmatter,
- mdxSource,
- editLink,
-}: InferGetStaticPropsType) {
- const { hideToc, ...meta } = frontmatter
-
- return (
-
-
-
- )
-}
diff --git a/apps/docs/pages/guides/self-hosting/analytics/config.tsx b/apps/docs/pages/guides/self-hosting/analytics/config.tsx
deleted file mode 100644
index 3946fc2c55c..00000000000
--- a/apps/docs/pages/guides/self-hosting/analytics/config.tsx
+++ /dev/null
@@ -1,67 +0,0 @@
-import { type InferGetStaticPropsType, type GetStaticProps } from 'next'
-import { MDXRemote } from 'next-mdx-remote'
-import { serialize } from 'next-mdx-remote/serialize'
-
-import components from '~/components'
-import { MenuId } from '~/components/Navigation/NavigationMenu/NavigationMenu'
-import Param from '~/components/Params'
-import Layout from '~/layouts/DefaultGuideLayout'
-import { getAnalyticsConfigV0 } from '~/lib/mdx/getConfig'
-
-const meta = {
- title: 'Analytics Self-hosting Config',
- description: 'How to configure and deploy Supabase Analytics.',
-}
-
-export const getStaticProps = (async () => {
- const spec = getAnalyticsConfigV0()
- const descriptionSource = await serialize(spec.info.description)
- return {
- props: {
- descriptionSource,
- spec,
- },
- }
-}) satisfies GetStaticProps
-
-export const Page = (props: InferGetStaticPropsType) => (
-
-
-
-
- {props.spec.info.tags.map((tag: ReturnType
['info']['tags']) => {
- return (
- <>
- {tag.title}
- {tag.description}
-
-
Parameters
-
- {props.spec.parameters
- .filter((param: ReturnType['parameters']) =>
- param.tags.includes(tag.id)
- )
- .map((param: ReturnType['parameters']) => {
- return (
-
- )
- })}
-
-
- >
- )
- })}
-
-
-)
-
-export default Page
diff --git a/apps/docs/pages/guides/self-hosting/auth/config.tsx b/apps/docs/pages/guides/self-hosting/auth/config.tsx
deleted file mode 100644
index 5702f8a5379..00000000000
--- a/apps/docs/pages/guides/self-hosting/auth/config.tsx
+++ /dev/null
@@ -1,67 +0,0 @@
-import { type InferGetStaticPropsType, type GetStaticProps } from 'next'
-import { MDXRemote } from 'next-mdx-remote'
-import { serialize } from 'next-mdx-remote/serialize'
-
-import components from '~/components'
-import { MenuId } from '~/components/Navigation/NavigationMenu/NavigationMenu'
-import Param from '~/components/Params'
-import Layout from '~/layouts/DefaultGuideLayout'
-import { getAuthConfigV1 } from '~/lib/mdx/getConfig'
-
-const meta = {
- title: 'Auth Self-hosting Config',
- description: 'How to configure and deploy Supabase Auth.',
-}
-
-export const getStaticProps = (async () => {
- const spec = getAuthConfigV1()
- const descriptionSource = await serialize(spec.info.description)
- return {
- props: {
- descriptionSource,
- spec,
- },
- }
-}) satisfies GetStaticProps
-
-export const Page = (props: InferGetStaticPropsType) => (
-
-
-
-
- {props.spec.info.tags.map((tag: ReturnType
['info']['tags']) => {
- return (
- <>
- {tag.title}
- {tag.description}
-
-
Parameters
-
- {props.spec.parameters
- .filter((param: ReturnType['parameters']) =>
- param.tags.includes(tag.id)
- )
- .map((param: ReturnType['parameters']) => {
- return (
-
- )
- })}
-
-
- >
- )
- })}
-
-
-)
-
-export default Page
diff --git a/apps/docs/pages/guides/self-hosting/realtime/config.tsx b/apps/docs/pages/guides/self-hosting/realtime/config.tsx
deleted file mode 100644
index 09df809537c..00000000000
--- a/apps/docs/pages/guides/self-hosting/realtime/config.tsx
+++ /dev/null
@@ -1,67 +0,0 @@
-import { type InferGetStaticPropsType, type GetStaticProps } from 'next'
-import { MDXRemote } from 'next-mdx-remote'
-import { serialize } from 'next-mdx-remote/serialize'
-
-import components from '~/components'
-import { MenuId } from '~/components/Navigation/NavigationMenu/NavigationMenu'
-import Param from '~/components/Params'
-import Layout from '~/layouts/DefaultGuideLayout'
-import { getRealtimeConfigV0 } from '~/lib/mdx/getConfig'
-
-const meta = {
- title: 'Realtime Self-hosting Config',
- description: 'How to configure and deploy Supabase Realtime.',
-}
-
-export const getStaticProps = (async () => {
- const spec = getRealtimeConfigV0()
- const descriptionSource = await serialize(spec.info.description)
- return {
- props: {
- descriptionSource,
- spec,
- },
- }
-}) satisfies GetStaticProps
-
-export const Page = (props: InferGetStaticPropsType) => (
-
-
-
-
- {props.spec.info.tags.map((tag: ReturnType
['info']['tags']) => {
- return (
- <>
- {tag.title}
- {tag.description}
-
-
Parameters
-
- {props.spec.parameters
- .filter((param: ReturnType['parameters']) =>
- param.tags.includes(tag.id)
- )
- .map((param: ReturnType['parameters']) => {
- return (
-
- )
- })}
-
-
- >
- )
- })}
-
-
-)
-
-export default Page
diff --git a/apps/docs/pages/guides/self-hosting/storage/config.tsx b/apps/docs/pages/guides/self-hosting/storage/config.tsx
deleted file mode 100644
index 8a131f674ac..00000000000
--- a/apps/docs/pages/guides/self-hosting/storage/config.tsx
+++ /dev/null
@@ -1,67 +0,0 @@
-import { type InferGetStaticPropsType, type GetStaticProps } from 'next'
-import { MDXRemote } from 'next-mdx-remote'
-import { serialize } from 'next-mdx-remote/serialize'
-
-import components from '~/components'
-import { MenuId } from '~/components/Navigation/NavigationMenu/NavigationMenu'
-import Param from '~/components/Params'
-import Layout from '~/layouts/DefaultGuideLayout'
-import { getStorageConfigV0 } from '~/lib/mdx/getConfig'
-
-const meta = {
- title: 'Storage Self-hosting Config',
- description: 'How to configure and deploy Supabase Storage.',
-}
-
-export const getStaticProps = (async () => {
- const spec = getStorageConfigV0()
- const descriptionSource = await serialize(spec.info.description)
- return {
- props: {
- descriptionSource,
- spec,
- },
- }
-}) satisfies GetStaticProps
-
-export const Page = (props: InferGetStaticPropsType) => (
-
-
-
-
- {props.spec.info.tags.map((tag: ReturnType
['info']['tags']) => {
- return (
- <>
- {tag.title}
- {tag.description}
-
-
Parameters
-
- {props.spec.parameters
- .filter((param: ReturnType['parameters']) =>
- param.tags.includes(tag.id)
- )
- .map((param: ReturnType['parameters']) => {
- return (
-
- )
- })}
-
-
- >
- )
- })}
-
-
-)
-
-export default Page
diff --git a/apps/docs/pages/guides/storage/[[...slug]].tsx b/apps/docs/pages/guides/storage/[[...slug]].tsx
deleted file mode 100644
index 90c4b978d88..00000000000
--- a/apps/docs/pages/guides/storage/[[...slug]].tsx
+++ /dev/null
@@ -1,29 +0,0 @@
-import { type GetStaticPaths, type GetStaticProps, type InferGetStaticPropsType } from 'next'
-import { MDXRemote } from 'next-mdx-remote'
-
-import components from '~/components'
-import { MenuId } from '~/components/Navigation/NavigationMenu/NavigationMenu'
-import Layout from '~/layouts/DefaultGuideLayout'
-import { getGuidesStaticPaths, getGuidesStaticProps } from '~/lib/docs'
-
-export const getStaticPaths = (async () => {
- return getGuidesStaticPaths('storage')
-}) satisfies GetStaticPaths
-
-export const getStaticProps = (async (args) => {
- return getGuidesStaticProps('storage', args)
-}) satisfies GetStaticProps
-
-export default function StorageGuide({
- frontmatter,
- mdxSource,
- editLink,
-}: InferGetStaticPropsType) {
- const { hideToc, ...meta } = frontmatter
-
- return (
-
-
-
- )
-}
diff --git a/apps/docs/pages/index.mdx b/apps/docs/pages/index.mdx
deleted file mode 100644
index 5b912d11238..00000000000
--- a/apps/docs/pages/index.mdx
+++ /dev/null
@@ -1,363 +0,0 @@
-import HomeLayout from '~/layouts/HomeLayout'
-import Link from 'next/link'
-import { Button, IconBackground, IconChevronRight, IconPlay, TextLink } from 'ui'
-import { GlassPanel } from 'ui-patterns/GlassPanel'
-import { IconPanel } from 'ui-patterns/IconPanel'
-
-import HomeMenuIconPicker from '~/components/Navigation/NavigationMenu/HomeMenuIconPicker'
-
-export const meta = {
- title: 'Supabase Documentation',
- description:
- 'Supabase is an open source Firebase alternative providing all the backend features you need to build a product.',
- subtitle: 'Supabase Developer Documentation and API Reference',
-}
-
-
-
-
- ## Products
-
-
-
- {products.map((product) => {
- return (
-
-
- } background={true} showIconBg={true} showLink={false}>
- {product.description}
-
-
-
- )
- })}
-
-
-
-
-
-
-
-
- {/*
-
- */}
- ## Client Libraries
-
-
-
-
-
-
- {clientLibraries.map((product) => {
- return (
-
- }
- background={true}
- showIconBg={true}
- showLink={false}
- >
- {product.description}
-
-
- )
- })}
-
-
-
-
-
-
-
-
- ## Migrate to Supabase
-
-
Bring your existing data, auth and storage to Supabase following our migration guides.
-
-
-
-
-
- {migrationGuides.map((product) => {
- return (
-
-
-
- {product.description}
-
-
-
- )
- })}
-
-
-
-
-
-
-
-
-
-
- ### Additional resources
-
-
-
-
- {additionalResources.map((product) => {
- return (
-
-
- } background={false}>
- {product.description}
-
-
-
-
- )
- })}
-
-
-
-
-
-
-
-
-
-
-
-
-
- ### Self-Hosting
-
-
Get started with self-hosting Supabase.
-
-
-
-
-
-
-
- {selfHostingOptions.map((product) => {
- return (
-
-
- } background={true} showIconBg={true} showLink={false}>
- {product.description}
-
-
-
- )
- })}
-
-
-
-
-
-
-
-export const products = [
- {
- title: 'Database',
- icon: 'database',
- hasLightIcon: true,
- href: '/guides/database/overview',
- description:
- 'Supabase provides a full Postgres database for every project with Realtime functionality, database backups, extensions, and more.',
- },
- {
- title: 'Auth',
- icon: 'auth',
- hasLightIcon: true,
- href: '/guides/auth',
- description:
- 'Add and manage email and password, passwordless, OAuth, and mobile logins to your project through a suite of identity providers and APIs.',
- },
- {
- title: 'Storage',
- icon: 'storage',
- hasLightIcon: true,
- href: '/guides/storage',
- description:
- 'Store, organize, transform, and serve large files—fully integrated with your Postgres database with Row Level Security access policies.',
- },
- {
- title: 'AI & Vectors',
- icon: 'ai',
- hasLightIcon: true,
- href: '/guides/ai',
- description: 'Use Supabase to store and search embedding vectors.',
- },
- {
- title: 'Realtime',
- icon: 'realtime',
- hasLightIcon: true,
- href: '/guides/realtime',
- description:
- 'Listen to database changes, store and sync user states across clients, broadcast data to clients subscribed to a channel, and more.',
- },
- {
- title: 'Edge Functions',
- icon: 'edge-functions',
- hasLightIcon: true,
- href: '/guides/functions',
- description:
- 'Globally distributed, server-side functions to execute your code closest to your users for the lowest latency.',
- },
-]
-
-export const migrationGuides = [
- {
- title: 'Firebase Auth',
- icon: '/docs/img/icons/firebase-icon',
- href: '/guides/resources/migrating-to-supabase/firebase-auth',
- },
- {
- title: 'Firestore Data',
- icon: '/docs/img/icons/firebase-icon',
- href: '/guides/resources/migrating-to-supabase/firestore-data',
- },
- {
- title: 'Firebase Storage',
- icon: '/docs/img/icons/firebase-icon',
- href: '/guides/resources/migrating-to-supabase/firebase-storage',
- },
- {
- title: 'Heroku',
- icon: '/docs/img/icons/heroku-icon',
- href: '/guides/resources/migrating-to-supabase/heroku',
- },
- {
- title: 'Render',
- icon: '/docs/img/icons/render-icon',
- href: '/guides/resources/migrating-to-supabase/render',
- },
- {
- title: 'Amazon RDS',
- icon: '/docs/img/icons/aws-rds-icon',
- href: '/guides/resources/migrating-to-supabase/amazon-rds',
- },
- {
- title: 'Postgres',
- icon: '/docs/img/icons/postgres-icon',
- href: '/guides/resources/migrating-to-supabase/postgres',
- },
- {
- title: 'MySQL',
- icon: '/docs/img/icons/mysql-icon',
- href: '/guides/resources/migrating-to-supabase/mysql',
- },
- {
- title: 'MSSQL',
- icon: '/docs/img/icons/mssql-icon',
- href: '/guides/resources/migrating-to-supabase/mssql',
- },
-]
-
-export const selfHostingOptions = [
- {
- title: 'Auth',
- icon: 'auth',
- href: 'reference/self-hosting-auth/introduction',
- },
- {
- title: 'Realtime',
- icon: 'realtime',
- href: 'reference/self-hosting-realtime/introduction',
- },
- {
- title: 'Storage',
- icon: 'storage',
- href: 'reference/self-hosting-storage/introduction',
- },
- {
- title: 'Analytics',
- icon: 'analytics',
- href: 'reference/self-hosting-analytics/introduction',
- },
-]
-
-export const clientLibraries = [
- {
- title: 'Javascript',
- icon: 'reference-javascript',
- href: 'reference/javascript/introduction',
- },
- {
- title: 'Flutter',
- icon: 'reference-dart',
- href: 'reference/dart/introduction',
- },
- {
- title: 'Python',
- icon: 'reference-python',
- href: 'reference/python/introduction',
- },
- {
- title: 'C#',
- icon: 'reference-csharp',
- href: 'reference/csharp/introduction',
- },
- {
- title: 'Swift',
- icon: 'reference-swift',
- href: 'reference/swift/introduction',
- },
- {
- title: 'Kotlin',
- icon: 'reference-kotlin',
- href: 'reference/kotlin/introduction',
- },
-]
-
-export const additionalResources = [
- {
- title: 'Management API',
- description: 'Manage your Supabase projects and organizations.',
- icon: 'reference-api',
- href: 'reference/api/introduction',
- },
- {
- title: 'Supabase CLI',
- description: 'Use the CLI to develop, manage and deploy your projects.',
- icon: 'reference-cli',
- href: 'reference/cli/introduction',
- },
- {
- title: 'Platform Guides',
- description: 'Learn more about the tools and services powering Supabase.',
- icon: 'platform',
- href: 'guides/platform',
- },
- {
- title: 'Integrations',
- description: 'Explore a variety of integrations from Supabase partners.',
- icon: 'integrations',
- href: 'guides/integrations',
- },
-]
-
-export const Page = ({ children }) =>
-
-export default Page
diff --git a/apps/docs/pages/reference/csharp/crawlers/[...slug].tsx b/apps/docs/pages/reference/csharp/crawlers/[...slug].tsx
index d16769cb83a..88a3c92b5a9 100644
--- a/apps/docs/pages/reference/csharp/crawlers/[...slug].tsx
+++ b/apps/docs/pages/reference/csharp/crawlers/[...slug].tsx
@@ -1,11 +1,10 @@
import clientLibsCommonSections from '~/spec/common-client-libs-sections.json'
-import typeSpec from '~/spec/enrichments/tsdoc_v2/combined.json'
import spec from '~/spec/supabase_csharp_v1.yml' assert { type: 'yml' }
import RefSectionHandler from '~/components/reference/RefSectionHandler'
import { flattenSections } from '~/lib/helpers'
import handleRefGetStaticPaths from '~/lib/mdx/handleRefStaticPaths'
import handleRefStaticProps from '~/lib/mdx/handleRefStaticProps'
-import { useRouter } from 'next/router'
+import { useRouter } from 'next/compat/router'
import RefSEO from '~/components/reference/RefSEO'
import { MenuId } from '~/components/Navigation/NavigationMenu/NavigationMenu'
import type { TypeSpec } from '~/components/reference/Reference.types'
@@ -30,7 +29,6 @@ export default function CSharpReference(props) {
menuId={MenuId.RefCSharpV1}
sections={filteredSection}
spec={spec}
- typeSpec={typeSpec as TypeSpec}
pageProps={props}
type="client-lib"
/>
diff --git a/apps/docs/pages/reference/csharp/v0/crawlers/[...slug].tsx b/apps/docs/pages/reference/csharp/v0/crawlers/[...slug].tsx
index 101c289bddb..dbe2b37b63d 100644
--- a/apps/docs/pages/reference/csharp/v0/crawlers/[...slug].tsx
+++ b/apps/docs/pages/reference/csharp/v0/crawlers/[...slug].tsx
@@ -1,11 +1,10 @@
import clientLibsCommonSections from '~/spec/common-client-libs-sections.json'
-import typeSpec from '~/spec/enrichments/tsdoc_v2/combined.json'
import spec from '~/spec/supabase_csharp_v0.yml' assert { type: 'yml' }
import RefSectionHandler from '~/components/reference/RefSectionHandler'
import { flattenSections } from '~/lib/helpers'
import handleRefGetStaticPaths from '~/lib/mdx/handleRefStaticPaths'
import handleRefStaticProps from '~/lib/mdx/handleRefStaticProps'
-import { useRouter } from 'next/router'
+import { useRouter } from 'next/compat/router'
import RefSEO from '~/components/reference/RefSEO'
import { MenuId } from '~/components/Navigation/NavigationMenu/NavigationMenu'
@@ -28,7 +27,6 @@ export default function JSReference(props) {
menuId={MenuId.RefCSharpV0}
sections={filteredSection}
spec={spec}
- typeSpec={typeSpec}
pageProps={props}
type="client-lib"
/>
diff --git a/apps/docs/pages/reference/dart/crawlers/[...slug].tsx b/apps/docs/pages/reference/dart/crawlers/[...slug].tsx
index b18c2eeff9b..dbac0378cc2 100644
--- a/apps/docs/pages/reference/dart/crawlers/[...slug].tsx
+++ b/apps/docs/pages/reference/dart/crawlers/[...slug].tsx
@@ -1,11 +1,10 @@
import clientLibsCommonSections from '~/spec/common-client-libs-sections.json'
-import typeSpec from '~/spec/enrichments/tsdoc_v2/combined.json'
import spec from '~/spec/supabase_dart_v2.yml' assert { type: 'yml' }
import RefSectionHandler from '~/components/reference/RefSectionHandler'
import { flattenSections } from '~/lib/helpers'
import handleRefGetStaticPaths from '~/lib/mdx/handleRefStaticPaths'
import handleRefStaticProps from '~/lib/mdx/handleRefStaticProps'
-import { useRouter } from 'next/router'
+import { useRouter } from 'next/compat/router'
import RefSEO from '~/components/reference/RefSEO'
import { MenuId } from '~/components/Navigation/NavigationMenu/NavigationMenu'
@@ -29,7 +28,6 @@ export default function DartReference(props) {
menuId={MenuId.RefDartV2}
sections={filteredSection}
spec={spec}
- typeSpec={typeSpec}
pageProps={props}
type="client-lib"
/>
diff --git a/apps/docs/pages/reference/dart/v1/crawlers/[...slug].tsx b/apps/docs/pages/reference/dart/v1/crawlers/[...slug].tsx
index 1843e626e5f..f4cba86e1d0 100644
--- a/apps/docs/pages/reference/dart/v1/crawlers/[...slug].tsx
+++ b/apps/docs/pages/reference/dart/v1/crawlers/[...slug].tsx
@@ -1,11 +1,10 @@
import clientLibsCommonSections from '~/spec/common-client-libs-sections.json'
-import typeSpec from '~/spec/enrichments/tsdoc_v2/combined.json'
import spec from '~/spec/supabase_dart_v1.yml' assert { type: 'yml' }
import RefSectionHandler from '~/components/reference/RefSectionHandler'
import { flattenSections } from '~/lib/helpers'
import handleRefGetStaticPaths from '~/lib/mdx/handleRefStaticPaths'
import handleRefStaticProps from '~/lib/mdx/handleRefStaticProps'
-import { useRouter } from 'next/router'
+import { useRouter } from 'next/compat/router'
import RefSEO from '~/components/reference/RefSEO'
import { MenuId } from '~/components/Navigation/NavigationMenu/NavigationMenu'
@@ -28,7 +27,6 @@ export default function DartReference(props) {
menuId={MenuId.RefDartV1}
sections={filteredSection}
spec={spec}
- typeSpec={typeSpec}
pageProps={props}
type="client-lib"
/>
diff --git a/apps/docs/pages/reference/index.mdx b/apps/docs/pages/reference/index.mdx
deleted file mode 100644
index f6eeec0d70a..00000000000
--- a/apps/docs/pages/reference/index.mdx
+++ /dev/null
@@ -1,79 +0,0 @@
-import Layout from '~/layouts/DefaultGuideLayout'
-
-export const meta = {
- id: 'reference',
- title: 'Reference Documentation',
- sidebar_label: 'Reference Documentation',
- hide_table_of_contents: true,
-}
-
-Reference documentation for the official Supabase client libraries, APIs, and tools.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-## Self-hosting
-
-Reference documentation for self-hosting Supabase features.
-
-
-
-export const Page = ({ children }) =>
-
-export default Page
diff --git a/apps/docs/pages/reference/javascript/crawlers/[...slug].tsx b/apps/docs/pages/reference/javascript/crawlers/[...slug].tsx
index a307a3eac07..b213488f963 100644
--- a/apps/docs/pages/reference/javascript/crawlers/[...slug].tsx
+++ b/apps/docs/pages/reference/javascript/crawlers/[...slug].tsx
@@ -5,7 +5,7 @@ import RefSectionHandler from '~/components/reference/RefSectionHandler'
import { flattenSections } from '~/lib/helpers'
import handleRefGetStaticPaths from '~/lib/mdx/handleRefStaticPaths'
import handleRefStaticProps from '~/lib/mdx/handleRefStaticProps'
-import { useRouter } from 'next/router'
+import { useRouter } from 'next/compat/router'
import RefSEO from '~/components/reference/RefSEO'
import { MenuId } from '~/components/Navigation/NavigationMenu/NavigationMenu'
diff --git a/apps/docs/pages/reference/javascript/v1/crawlers/[...slug].tsx b/apps/docs/pages/reference/javascript/v1/crawlers/[...slug].tsx
index 09cd60e404c..436b17db4a9 100644
--- a/apps/docs/pages/reference/javascript/v1/crawlers/[...slug].tsx
+++ b/apps/docs/pages/reference/javascript/v1/crawlers/[...slug].tsx
@@ -1,11 +1,11 @@
import clientLibsCommonSections from '~/spec/common-client-libs-sections.json'
-import typeSpec from '~/spec/enrichments/tsdoc_v2/combined.json'
+import typeSpec from '~/spec/enrichments/tsdoc_v1/combined.json'
import spec from '~/spec/supabase_js_v1.yml' assert { type: 'yml' }
import RefSectionHandler from '~/components/reference/RefSectionHandler'
import { flattenSections } from '~/lib/helpers'
import handleRefGetStaticPaths from '~/lib/mdx/handleRefStaticPaths'
import handleRefStaticProps from '~/lib/mdx/handleRefStaticProps'
-import { useRouter } from 'next/router'
+import { useRouter } from 'next/compat/router'
import RefSEO from '~/components/reference/RefSEO'
import { MenuId } from '~/components/Navigation/NavigationMenu/NavigationMenu'
diff --git a/apps/docs/pages/reference/kotlin/crawlers/[...slug].tsx b/apps/docs/pages/reference/kotlin/crawlers/[...slug].tsx
index 2f3885d524b..984d6e26168 100644
--- a/apps/docs/pages/reference/kotlin/crawlers/[...slug].tsx
+++ b/apps/docs/pages/reference/kotlin/crawlers/[...slug].tsx
@@ -1,11 +1,10 @@
import clientLibsCommonSections from '~/spec/common-client-libs-sections.json'
-import typeSpec from '~/spec/enrichments/tsdoc_v2/combined.json'
import spec from '~/spec/supabase_kt_v2.yml' assert { type: 'yml' }
import RefSectionHandler from '~/components/reference/RefSectionHandler'
import { flattenSections } from '~/lib/helpers'
import handleRefGetStaticPaths from '~/lib/mdx/handleRefStaticPaths'
import handleRefStaticProps from '~/lib/mdx/handleRefStaticProps'
-import { useRouter } from 'next/router'
+import { useRouter } from 'next/compat/router'
import RefSEO from '~/components/reference/RefSEO'
import { MenuId } from '~/components/Navigation/NavigationMenu/NavigationMenu'
@@ -29,7 +28,6 @@ export default function KotlinReference(props) {
menuId={MenuId.RefKotlinV2}
sections={filteredSection}
spec={spec}
- typeSpec={typeSpec}
pageProps={props}
type="client-lib"
/>
diff --git a/apps/docs/pages/reference/kotlin/v1/crawlers/[...slug].tsx b/apps/docs/pages/reference/kotlin/v1/crawlers/[...slug].tsx
index 7a5ada7a194..cf1f619d02b 100644
--- a/apps/docs/pages/reference/kotlin/v1/crawlers/[...slug].tsx
+++ b/apps/docs/pages/reference/kotlin/v1/crawlers/[...slug].tsx
@@ -1,11 +1,10 @@
import clientLibsCommonSections from '~/spec/common-client-libs-sections.json'
-import typeSpec from '~/spec/enrichments/tsdoc_v2/combined.json'
import spec from '~/spec/supabase_kt_v1.yml' assert { type: 'yml' }
import RefSectionHandler from '~/components/reference/RefSectionHandler'
import { flattenSections } from '~/lib/helpers'
import handleRefGetStaticPaths from '~/lib/mdx/handleRefStaticPaths'
import handleRefStaticProps from '~/lib/mdx/handleRefStaticProps'
-import { useRouter } from 'next/router'
+import { useRouter } from 'next/compat/router'
import RefSEO from '~/components/reference/RefSEO'
import { MenuId } from '~/components/Navigation/NavigationMenu/NavigationMenu'
@@ -28,7 +27,6 @@ export default function KotlinReference(props) {
menuId={MenuId.RefKotlinV1}
sections={filteredSection}
spec={spec}
- typeSpec={typeSpec}
pageProps={props}
type="client-lib"
/>
diff --git a/apps/docs/pages/reference/python/[...slug].tsx b/apps/docs/pages/reference/python/[...slug].tsx
index 6cb06b74b6c..2dc649bf144 100644
--- a/apps/docs/pages/reference/python/[...slug].tsx
+++ b/apps/docs/pages/reference/python/[...slug].tsx
@@ -1,5 +1,4 @@
import clientLibsCommonSections from '~/spec/common-client-libs-sections.json'
-import typeSpec from '~/spec/enrichments/tsdoc_v2/combined.json'
import spec from '~/spec/supabase_py_v2.yml' assert { type: 'yml' }
import RefSectionHandler from '~/components/reference/RefSectionHandler'
import { flattenSections } from '~/lib/helpers'
@@ -16,7 +15,6 @@ export default function PyReference(props) {
menuId={MenuId.RefPythonV2}
sections={sections}
spec={spec}
- typeSpec={typeSpec}
pageProps={props}
type="client-lib"
/>
diff --git a/apps/docs/pages/reference/python/crawlers/[...slug].tsx b/apps/docs/pages/reference/python/crawlers/[...slug].tsx
index bb549d62305..e530945156e 100644
--- a/apps/docs/pages/reference/python/crawlers/[...slug].tsx
+++ b/apps/docs/pages/reference/python/crawlers/[...slug].tsx
@@ -1,11 +1,10 @@
import clientLibsCommonSections from '~/spec/common-client-libs-sections.json'
-import typeSpec from '~/spec/enrichments/tsdoc_v2/combined.json'
import spec from '~/spec/supabase_py_v2.yml' assert { type: 'yml' }
import RefSectionHandler from '~/components/reference/RefSectionHandler'
import { flattenSections } from '~/lib/helpers'
import handleRefGetStaticPaths from '~/lib/mdx/handleRefStaticPaths'
import handleRefStaticProps from '~/lib/mdx/handleRefStaticProps'
-import { useRouter } from 'next/router'
+import { useRouter } from 'next/compat/router'
import RefSEO from '~/components/reference/RefSEO'
import { MenuId } from '~/components/Navigation/NavigationMenu/NavigationMenu'
@@ -29,7 +28,6 @@ export default function PyReference(props) {
menuId={MenuId.RefPythonV2}
sections={filteredSection}
spec={spec}
- typeSpec={typeSpec}
pageProps={props}
type="client-lib"
/>
diff --git a/apps/docs/pages/reference/swift/crawlers/[...slug].tsx b/apps/docs/pages/reference/swift/crawlers/[...slug].tsx
index 69000ea9674..f47cb85ea6e 100644
--- a/apps/docs/pages/reference/swift/crawlers/[...slug].tsx
+++ b/apps/docs/pages/reference/swift/crawlers/[...slug].tsx
@@ -1,11 +1,10 @@
import clientLibsCommonSections from '~/spec/common-client-libs-sections.json'
-import typeSpec from '~/spec/enrichments/tsdoc_v2/combined.json'
import spec from '~/spec/supabase_swift_v2.yml' assert { type: 'yml' }
import RefSectionHandler from '~/components/reference/RefSectionHandler'
import { flattenSections } from '~/lib/helpers'
import handleRefGetStaticPaths from '~/lib/mdx/handleRefStaticPaths'
import handleRefStaticProps from '~/lib/mdx/handleRefStaticProps'
-import { useRouter } from 'next/router'
+import { useRouter } from 'next/compat/router'
import RefSEO from '~/components/reference/RefSEO'
import { MenuId } from '~/components/Navigation/NavigationMenu/NavigationMenu'
@@ -29,7 +28,6 @@ export default function SwiftReference(props) {
menuId={MenuId.RefSwiftV2}
sections={filteredSection}
spec={spec}
- typeSpec={typeSpec}
pageProps={props}
type="client-lib"
/>
diff --git a/apps/docs/pages/reference/swift/v1/crawlers/[...slug].tsx b/apps/docs/pages/reference/swift/v1/crawlers/[...slug].tsx
index 1ef50177ac2..d5838fe8d72 100644
--- a/apps/docs/pages/reference/swift/v1/crawlers/[...slug].tsx
+++ b/apps/docs/pages/reference/swift/v1/crawlers/[...slug].tsx
@@ -1,11 +1,10 @@
import clientLibsCommonSections from '~/spec/common-client-libs-sections.json'
-import typeSpec from '~/spec/enrichments/tsdoc_v2/combined.json'
import spec from '~/spec/supabase_swift_v2.yml' assert { type: 'yml' }
import RefSectionHandler from '~/components/reference/RefSectionHandler'
import { flattenSections } from '~/lib/helpers'
import handleRefGetStaticPaths from '~/lib/mdx/handleRefStaticPaths'
import handleRefStaticProps from '~/lib/mdx/handleRefStaticProps'
-import { useRouter } from 'next/router'
+import { useRouter } from 'next/compat/router'
import RefSEO from '~/components/reference/RefSEO'
import { MenuId } from '~/components/Navigation/NavigationMenu/NavigationMenu'
@@ -28,7 +27,6 @@ export default function SwiftReference(props) {
menuId={MenuId.RefSwiftV1}
sections={filteredSection}
spec={spec}
- typeSpec={typeSpec}
pageProps={props}
type="client-lib"
/>
diff --git a/apps/docs/public/.well-known/security.txt b/apps/docs/public/.well-known/security.txt
index 44d057d7c93..f431082ec87 100644
--- a/apps/docs/public/.well-known/security.txt
+++ b/apps/docs/public/.well-known/security.txt
@@ -1,4 +1,4 @@
-Contact: security@supabase.io
+Contact: https://hackerone.com/ca63b563-9661-4ac3-8d23-7581582ef451/embedded_submissions/new
Canonical: https://supabase.com/.well-known/security.txt
diff --git a/apps/docs/public/humans.txt b/apps/docs/public/humans.txt
index 3813ca9595e..ee2983ba130 100644
--- a/apps/docs/public/humans.txt
+++ b/apps/docs/public/humans.txt
@@ -3,6 +3,7 @@ TEAM
Supabase is 100% remote.
Alaister Young
+Aleksi Immonen
Alexander Korotkov
Amy Q
Angelico de los Reyes
@@ -12,17 +13,20 @@ Beng Eu
Bo Lu
Bobbie Soedirgo
Bruno Andrade
+Carel de Waal
Chandana Anumula
Charis Lam
Chase Granberry
Chris Caruso
Chris Copplestone
Chris Gwilliams
+Craig Cannon
Dave Wilson
Deji I
Div Arora
Divit D
Egor Romanov
+Etienne Stalmans
Fabrizio Fenoglio
Francesco Sansalvadore
Greg Richardson
@@ -37,6 +41,7 @@ Jon M
Jonny Summers-Muir
Jordi Enric
Joshen Lim
+Julien Goux
Kamil Ogórek
Kang Ming Tay
Karan S
@@ -49,6 +54,7 @@ Long Hoang
Margarita Sandomirskaia
Marijana Pavlinić
Mark Burggraf
+Michael Ridley
Monica El Khoury
Oli R
Pamela Chia
diff --git a/apps/docs/public/img/guides/auth-mfa/auth-mfa-flow.svg b/apps/docs/public/img/guides/auth-mfa/auth-mfa-flow.svg
new file mode 100644
index 00000000000..d7dd78a4bf0
--- /dev/null
+++ b/apps/docs/public/img/guides/auth-mfa/auth-mfa-flow.svg
@@ -0,0 +1 @@
+
Yes
No
1 or more factors
0 factors
Setup flow
Session is AAL1
Enroll API
Show QR code
User: Scan QR code in authenticator
User: Enter code
Challenge + Verify API
Is code correct?
Upgrade to AAL2
Done
Login flow
User: Sign-in
Upgrade to AAL1
List Factors API
User: Open authenticator
Setup flow
\ No newline at end of file
diff --git a/apps/docs/public/img/guides/auth-mfa/auth-mfa.mermaid b/apps/docs/public/img/guides/auth-mfa/auth-mfa.mermaid
new file mode 100644
index 00000000000..11c1e6bc51e
--- /dev/null
+++ b/apps/docs/public/img/guides/auth-mfa/auth-mfa.mermaid
@@ -0,0 +1,7 @@
+graph TD;
+ InitS((Setup flow)) --> SAAL1[/Session is AAL1/] --> Enroll[Enroll API] --> ShowQR[Show QR code] --> Scan([User: Scan QR code in authenticator]) --> Enter([User: Enter code]) --> Verify[Challenge + Verify API] --> Check{{Is code correct?}}
+ Check -->|Yes| AAL2[/Upgrade to AAL2/] --> Done((Done))
+ Check -->|No| Enter
+ InitA((Login flow)) --> SignIn([User: Sign-in]) --> AAL1[/Upgrade to AAL1/] --> ListFactors[List Factors API]
+ ListFactors -->|1 or more factors| OpenAuth([User: Open authenticator]) --> Enter
+ ListFactors -->|0 factors| Setup[[Setup flow]]
\ No newline at end of file
diff --git a/apps/docs/public/img/guides/cli/docker-mac-light.png b/apps/docs/public/img/guides/cli/docker-mac-light.png
new file mode 100644
index 00000000000..ca0c3f88543
Binary files /dev/null and b/apps/docs/public/img/guides/cli/docker-mac-light.png differ
diff --git a/apps/docs/public/img/guides/cli/docker-mac.png b/apps/docs/public/img/guides/cli/docker-mac.png
new file mode 100644
index 00000000000..733eada80a1
Binary files /dev/null and b/apps/docs/public/img/guides/cli/docker-mac.png differ
diff --git a/apps/docs/public/img/guides/cli/docker-win-light.png b/apps/docs/public/img/guides/cli/docker-win-light.png
new file mode 100644
index 00000000000..13778f64577
Binary files /dev/null and b/apps/docs/public/img/guides/cli/docker-win-light.png differ
diff --git a/apps/docs/public/img/guides/cli/docker-win.png b/apps/docs/public/img/guides/cli/docker-win.png
new file mode 100644
index 00000000000..9a2b389deb3
Binary files /dev/null and b/apps/docs/public/img/guides/cli/docker-win.png differ
diff --git a/apps/docs/public/img/icons/auth0-icon.svg b/apps/docs/public/img/icons/auth0-icon.svg
new file mode 100644
index 00000000000..e69ccc46f10
--- /dev/null
+++ b/apps/docs/public/img/icons/auth0-icon.svg
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/docs/public/img/icons/firebase-icon.svg b/apps/docs/public/img/icons/firebase-icon.svg
index 57bc1df1880..f7515edcb5f 100644
--- a/apps/docs/public/img/icons/firebase-icon.svg
+++ b/apps/docs/public/img/icons/firebase-icon.svg
@@ -1 +1,6 @@
-
\ No newline at end of file
+
+
+
+
+
+
diff --git a/apps/docs/public/img/platform/shared-responsibility-model--dark.png b/apps/docs/public/img/platform/shared-responsibility-model--dark.png
new file mode 100644
index 00000000000..43511b552c8
Binary files /dev/null and b/apps/docs/public/img/platform/shared-responsibility-model--dark.png differ
diff --git a/apps/docs/public/img/platform/shared-responsibility-model--light.png b/apps/docs/public/img/platform/shared-responsibility-model--light.png
new file mode 100644
index 00000000000..d2790b95c43
Binary files /dev/null and b/apps/docs/public/img/platform/shared-responsibility-model--light.png differ
diff --git a/apps/docs/public/lawyers.txt b/apps/docs/public/lawyers.txt
index 4aa599ea4d1..42fecf8ee21 100644
--- a/apps/docs/public/lawyers.txt
+++ b/apps/docs/public/lawyers.txt
@@ -9,7 +9,7 @@ Supabase™ is a trademark of Supabase Inc.
If you're a creator/contributor to one of these packages, thanks!
-Last updated: 2022-03-29
+Last updated: 2024-07-11
JavaScript/TypeScript
diff --git a/apps/docs/scripts/orphans/detect-orphan-mdx.ts b/apps/docs/scripts/orphans/detect-orphan-mdx.ts
index 9eb5c3a00bb..3041d54d284 100644
--- a/apps/docs/scripts/orphans/detect-orphan-mdx.ts
+++ b/apps/docs/scripts/orphans/detect-orphan-mdx.ts
@@ -1,7 +1,7 @@
import { readdir } from 'node:fs/promises'
import { extname, join } from 'node:path'
import {
- HOMEPAGE_MENU_ITEMS,
+ GLOBAL_MENU_ITEMS,
gettingstarted,
cli,
auth,
@@ -60,9 +60,9 @@ const main = async () => {
.filter((file) => extname(file) === '.mdx')
.map((file) => file.replace(/\.mdx$/, ''))
- const flattenedHomepageMenuItems = HOMEPAGE_MENU_ITEMS.flat() as RefItem[]
+ const flattenedGlobalMenuItems = GLOBAL_MENU_ITEMS.flat() as RefItem[]
const pagesToPublish = [
- flattenedHomepageMenuItems,
+ flattenedGlobalMenuItems,
gettingstarted.items,
cli.items,
auth.items,
diff --git a/apps/docs/scripts/search/sources/reference-doc.ts b/apps/docs/scripts/search/sources/reference-doc.ts
index 8b50e898a30..efb54e6bcdc 100644
--- a/apps/docs/scripts/search/sources/reference-doc.ts
+++ b/apps/docs/scripts/search/sources/reference-doc.ts
@@ -1,14 +1,14 @@
import { createHash } from 'crypto'
import { readFile } from 'fs/promises'
import yaml from 'js-yaml'
-import { OpenAPIV3 } from 'openapi-types'
-import {
+import type { OpenAPIV3 } from 'openapi-types'
+import type {
ICommonItem,
ICommonSection,
IFunctionDefinition,
ISpec,
} from '../../../components/reference/Reference.types'
-import { CliCommand, CliSpec } from '../../../generator/types/CliSpec'
+import type { CliCommand, CliSpec } from '../../../generator/types/CliSpec'
import { flattenSections } from '../../../lib/helpers'
import { enrichedOperation, gen_v3 } from '../../../lib/refGenerator/helpers'
import type { Json } from '../../helpers.mdx'
diff --git a/apps/docs/spec/api_v1_openapi.json b/apps/docs/spec/api_v1_openapi.json
index 05bfb70ef64..cbff105e2f1 100644
--- a/apps/docs/spec/api_v1_openapi.json
+++ b/apps/docs/spec/api_v1_openapi.json
@@ -1 +1 @@
-{"openapi":"3.0.0","paths":{"/v1/branches/{branch_id}":{"get":{"operationId":"v1-get-a-branch-config","summary":"Get database branch config","description":"Fetches configurations of the specified database branch","parameters":[{"name":"branch_id","required":true,"in":"path","description":"Branch ID","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BranchDetailResponse"}}}},"500":{"description":"Failed to retrieve database branch"}},"tags":["environments"],"security":[{"bearer":[]}]},"patch":{"operationId":"v1-update-a-branch-config","summary":"Update database branch config","description":"Updates the configuration of the specified database branch","parameters":[{"name":"branch_id","required":true,"in":"path","description":"Branch ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateBranchBody"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BranchResponse"}}}},"500":{"description":"Failed to update database branch"}},"tags":["environments"],"security":[{"bearer":[]}]},"delete":{"operationId":"v1-delete-a-branch","summary":"Delete a database branch","description":"Deletes the specified database branch","parameters":[{"name":"branch_id","required":true,"in":"path","description":"Branch ID","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BranchDeleteResponse"}}}},"500":{"description":"Failed to delete database branch"}},"tags":["environments"],"security":[{"bearer":[]}]}},"/v1/branches/{branch_id}/reset":{"post":{"operationId":"v1-reset-a-branch","summary":"Resets a database branch","description":"Resets the specified database branch","parameters":[{"name":"branch_id","required":true,"in":"path","description":"Branch ID","schema":{"type":"string"}}],"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BranchResetResponse"}}}},"500":{"description":"Failed to reset database branch"}},"tags":["environments"],"security":[{"bearer":[]}]}},"/v1/projects":{"get":{"operationId":"v1-list-all-projects","summary":"List all projects","description":"Returns a list of all projects you've previously created.","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/V1ProjectResponse"}}}}}},"tags":["projects"],"security":[{"bearer":[]}]},"post":{"operationId":"v1-create-a-project","summary":"Create a project","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1CreateProjectBody"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1ProjectResponse"}}}}},"tags":["projects"],"security":[{"bearer":[]}]}},"/v1/organizations":{"get":{"operationId":"v1-list-all-organizations","summary":"List all organizations","description":"Returns a list of organizations that you currently belong to.","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/OrganizationResponseV1"}}}}},"500":{"description":"Unexpected error listing organizations"}},"tags":["organizations"],"security":[{"bearer":[]}]},"post":{"operationId":"v1-create-an-organization","summary":"Create an organization","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationBodyV1"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationResponseV1"}}}},"500":{"description":"Unexpected error creating an organization"}},"tags":["organizations"],"security":[{"bearer":[]}]}},"/v1/oauth/authorize":{"get":{"operationId":"v1-authorize-user","summary":"[Beta] Authorize user through oauth","parameters":[{"name":"client_id","required":true,"in":"query","schema":{"type":"string"}},{"name":"response_type","required":true,"in":"query","schema":{"enum":["code","token","id_token token"],"type":"string"}},{"name":"redirect_uri","required":true,"in":"query","schema":{"type":"string"}},{"name":"scope","required":false,"in":"query","schema":{"type":"string"}},{"name":"state","required":false,"in":"query","schema":{"type":"string"}},{"name":"response_mode","required":false,"in":"query","schema":{"type":"string"}},{"name":"code_challenge","required":false,"in":"query","schema":{"type":"string"}},{"name":"code_challenge_method","required":false,"in":"query","schema":{"enum":["plain","sha256","S256"],"type":"string"}}],"responses":{"303":{"description":""}},"tags":["oauth"],"security":[{"oauth2":["read"]}]}},"/v1/oauth/token":{"post":{"operationId":"v1-exchange-oauth-token","summary":"[Beta] Exchange auth code for user's access and refresh token","parameters":[],"requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/OAuthTokenBody"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthTokenResponse"}}}}},"tags":["oauth"],"security":[{"oauth2":["write"]}]}},"/v1/snippets":{"get":{"operationId":"v1-list-all-snippets","summary":"Lists SQL snippets for the logged in user","parameters":[{"name":"project_ref","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SnippetList"}}}},"500":{"description":"Failed to list user's SQL snippets"}},"tags":["database"],"security":[{"bearer":[]}]}},"/v1/snippets/{id}":{"get":{"operationId":"v1-get-a-snippet","summary":"Gets a specific SQL snippet","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SnippetResponse"}}}},"500":{"description":"Failed to retrieve SQL snippet"}},"tags":["database"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/api-keys":{"get":{"operationId":"v1-get-project-api-keys","summary":"Get project api keys","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ApiKeyResponse"}}}}},"403":{"description":""}},"tags":["secrets"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/branches":{"get":{"operationId":"v1-list-all-branches","summary":"List all database branches","description":"Returns all database branches of the specified project.","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/BranchResponse"}}}}},"500":{"description":"Failed to retrieve database branches"}},"tags":["environments"],"security":[{"bearer":[]}]},"post":{"operationId":"v1-create-a-branch","summary":"Create a database branch","description":"Creates a database branch from the specified project.","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBranchBody"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BranchResponse"}}}},"500":{"description":"Failed to create database branch"}},"tags":["environments"],"security":[{"bearer":[]}]},"delete":{"operationId":"v1-disable-preview-branching","summary":"Disables preview branching","description":"Disables preview branching for the specified project","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":""},"500":{"description":"Failed to disable preview branching"}},"tags":["environments"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/custom-hostname":{"get":{"operationId":"v1-get-hostname-config","summary":"[Beta] Gets project's custom hostname config","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCustomHostnameResponse"}}}},"403":{"description":""},"500":{"description":"Failed to retrieve project's custom hostname config"}},"tags":["domains"],"security":[{"bearer":[]}]},"delete":{"operationId":"v1-Delete hostname config","summary":"[Beta] Deletes a project's custom hostname configuration","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":""},"403":{"description":""},"500":{"description":"Failed to delete project custom hostname configuration"}},"tags":["domains"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/custom-hostname/initialize":{"post":{"operationId":"v1-update-hostname-config","summary":"[Beta] Updates project's custom hostname configuration","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCustomHostnameBody"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCustomHostnameResponse"}}}},"403":{"description":""},"500":{"description":"Failed to update project custom hostname configuration"}},"tags":["domains"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/custom-hostname/reverify":{"post":{"operationId":"v1-verify-dns-config","summary":"[Beta] Attempts to verify the DNS configuration for project's custom hostname configuration","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCustomHostnameResponse"}}}},"403":{"description":""},"500":{"description":"Failed to verify project custom hostname configuration"}},"tags":["domains"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/custom-hostname/activate":{"post":{"operationId":"v1-activate-custom-hostname","summary":"[Beta] Activates a custom hostname for a project.","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCustomHostnameResponse"}}}},"403":{"description":""},"500":{"description":"Failed to activate project custom hostname configuration"}},"tags":["domains"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/network-bans/retrieve":{"post":{"operationId":"v1-list-all-network-bans","summary":"[Beta] Gets project's network bans","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NetworkBanResponse"}}}},"403":{"description":""},"500":{"description":"Failed to retrieve project's network bans"}},"tags":["projects"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/network-bans":{"delete":{"operationId":"v1-delete-network-bans","summary":"[Beta] Remove network bans.","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemoveNetworkBanRequest"}}}},"responses":{"200":{"description":""},"403":{"description":""},"500":{"description":"Failed to remove network bans."}},"tags":["projects"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/network-restrictions":{"get":{"operationId":"v1-get-network-restrictions","summary":"[Beta] Gets project's network restrictions","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NetworkRestrictionsResponse"}}}},"403":{"description":""},"500":{"description":"Failed to retrieve project's network restrictions"}},"tags":["projects"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/network-restrictions/apply":{"post":{"operationId":"v1-update-network-restrictions","summary":"[Beta] Updates project's network restrictions","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NetworkRestrictionsRequest"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NetworkRestrictionsResponse"}}}},"403":{"description":""},"500":{"description":"Failed to update project network restrictions"}},"tags":["projects"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/pgsodium":{"get":{"operationId":"v1-get-pgsodium-config","summary":"[Beta] Gets project's pgsodium config","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PgsodiumConfigResponse"}}}},"403":{"description":""},"500":{"description":"Failed to retrieve project's pgsodium config"}},"tags":["secrets"],"security":[{"bearer":[]}]},"put":{"operationId":"v1-update-pgsodium-config","summary":"[Beta] Updates project's pgsodium config. Updating the root_key can cause all data encrypted with the older key to become inaccessible.","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePgsodiumConfigBody"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PgsodiumConfigResponse"}}}},"403":{"description":""},"500":{"description":"Failed to update project's pgsodium config"}},"tags":["secrets"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/postgrest":{"get":{"operationId":"v1-get-postgrest-service-config","summary":"Gets project's postgrest config","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostgrestConfigWithJWTSecretResponse"}}}},"403":{"description":""},"500":{"description":"Failed to retrieve project's postgrest config"}},"tags":["rest"],"security":[{"bearer":[]}]},"patch":{"operationId":"v1-update-postgrest-service-config","summary":"Updates project's postgrest config","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePostgrestConfigBody"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1PostgrestConfigResponse"}}}},"403":{"description":""},"500":{"description":"Failed to update project's postgrest config"}},"tags":["rest"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}":{"delete":{"operationId":"v1-Delete a project","summary":"Deletes the given project","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1ProjectRefResponse"}}}},"403":{"description":""}},"tags":["projects"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/secrets":{"get":{"operationId":"v1-list-all-secrets","summary":"List all secrets","description":"Returns all secrets you've previously added to the specified project.","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SecretResponse"}}}}},"403":{"description":""},"500":{"description":"Failed to retrieve project's secrets"}},"tags":["secrets"],"security":[{"bearer":[]}]},"post":{"operationId":"v1-bulk-create-secrets","summary":"Bulk create secrets","description":"Creates multiple secrets and adds them to the specified project.","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CreateSecretBody"}}}}},"responses":{"201":{"description":""},"403":{"description":""},"500":{"description":"Failed to create project's secrets"}},"tags":["secrets"],"security":[{"bearer":[]}]},"delete":{"operationId":"v1-bulk-delete-secrets","summary":"Bulk delete secrets","description":"Deletes all secrets with the given names from the specified project","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"array","items":{"type":"string"}}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}},"403":{"description":""},"500":{"description":"Failed to delete secrets with given names"}},"tags":["secrets"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/ssl-enforcement":{"get":{"operationId":"v1-get-ssl-enforcement-config","summary":"[Beta] Get project's SSL enforcement configuration.","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SslEnforcementResponse"}}}},"403":{"description":""},"500":{"description":"Failed to retrieve project's SSL enforcement config"}},"tags":["database"],"security":[{"bearer":[]}]},"put":{"operationId":"v1-update-ssl-enforcement-config","summary":"[Beta] Update project's SSL enforcement configuration.","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SslEnforcementRequest"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SslEnforcementResponse"}}}},"403":{"description":""},"500":{"description":"Failed to update project's SSL enforcement configuration."}},"tags":["database"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/types/typescript":{"get":{"operationId":"v1-generate-typescript-types","summary":"Generate TypeScript types","description":"Returns the TypeScript types of your schema for use with supabase-js.","parameters":[{"name":"included_schemas","required":false,"in":"query","schema":{"default":"public","type":"string"}},{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TypescriptResponse"}}}},"403":{"description":""},"500":{"description":"Failed to generate TypeScript types"}},"tags":["database"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/vanity-subdomain":{"get":{"operationId":"v1-get-vanity-subdomain-config","summary":"[Beta] Gets current vanity subdomain config","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VanitySubdomainConfigResponse"}}}},"403":{"description":""},"500":{"description":"Failed to get project vanity subdomain configuration"}},"tags":["domains"],"security":[{"bearer":[]}]},"delete":{"operationId":"v1-deactivate-vanity-subdomain-config","summary":"[Beta] Deletes a project's vanity subdomain configuration","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":""},"403":{"description":""},"500":{"description":"Failed to delete project vanity subdomain configuration"}},"tags":["domains"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/vanity-subdomain/check-availability":{"post":{"operationId":"v1-check-vanity-subdomain-availability","summary":"[Beta] Checks vanity subdomain availability","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VanitySubdomainBody"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubdomainAvailabilityResponse"}}}},"403":{"description":""},"500":{"description":"Failed to check project vanity subdomain configuration"}},"tags":["domains"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/vanity-subdomain/activate":{"post":{"operationId":"v1-activate-vanity-subdomain-config","summary":"[Beta] Activates a vanity subdomain for a project.","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VanitySubdomainBody"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivateVanitySubdomainResponse"}}}},"403":{"description":""},"500":{"description":"Failed to activate project vanity subdomain configuration"}},"tags":["domains"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/upgrade":{"post":{"operationId":"v1-upgrade-postgres-version","summary":"[Beta] Upgrades the project's Postgres version","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeDatabaseBody"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectUpgradeInitiateResponse"}}}},"403":{"description":""},"500":{"description":"Failed to initiate project upgrade"}},"tags":["projects"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/upgrade/eligibility":{"get":{"operationId":"v1-get-postgrest-upgrade-eligibility","summary":"[Beta] Returns the project's eligibility for upgrades","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectUpgradeEligibilityResponse"}}}},"403":{"description":""},"500":{"description":"Failed to determine project upgrade eligibility"}},"tags":["projects"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/upgrade/status":{"get":{"operationId":"v1-get-postgrest-upgrade-status","summary":"[Beta] Gets the latest status of the project's upgrade","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DatabaseUpgradeStatusResponse"}}}},"403":{"description":""},"500":{"description":"Failed to retrieve project upgrade status"}},"tags":["projects"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/readonly":{"get":{"operationId":"v1-get-readonly-mode-status","summary":"Returns project's readonly mode status","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadOnlyStatusResponse"}}}},"500":{"description":"Failed to get project readonly mode status"}},"tags":["database"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/readonly/temporary-disable":{"post":{"operationId":"v1-disable-readonly-mode-temporarily","summary":"Disables project's readonly mode for the next 15 minutes","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"201":{"description":""},"500":{"description":"Failed to disable project's readonly mode"}},"tags":["database"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/read-replicas/setup":{"post":{"operationId":"v1-setup-a-read-replica","summary":"[Beta] Set up a read replica","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetUpReadReplicaBody"}}}},"responses":{"201":{"description":""},"500":{"description":"Failed to set up read replica"}},"tags":["database"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/read-replicas/remove":{"post":{"operationId":"v1-remove-a-read-replica","summary":"[Beta] Remove a read replica","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemoveReadReplicaBody"}}}},"responses":{"201":{"description":""},"500":{"description":"Failed to remove read replica"}},"tags":["database"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/health":{"get":{"operationId":"v1-get-services-health","summary":"Gets project's service health status","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}},{"name":"timeout_ms","required":false,"in":"query","schema":{"minimum":0,"maximum":10000,"type":"integer"}},{"name":"services","required":true,"in":"query","schema":{"type":"array","items":{"type":"string","enum":["auth","db","pooler","realtime","rest","storage"]}}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/V1ServiceHealthResponse"}}}}},"500":{"description":"Failed to retrieve project's service health status"}},"tags":["projects"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/config/database/postgres":{"get":{"operationId":"v1-get-postgres-config","summary":"Gets project's Postgres config","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostgresConfigResponse"}}}},"500":{"description":"Failed to retrieve project's Postgres config"}},"tags":["database"],"security":[{"bearer":[]}]},"put":{"operationId":"v1-update-postgres-config","summary":"Updates project's Postgres config","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePostgresConfigBody"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostgresConfigResponse"}}}},"500":{"description":"Failed to update project's Postgres config"}},"tags":["database"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/config/database/pgbouncer":{"get":{"operationId":"v1-get-project-pgbouncer-config","summary":"Get project's pgbouncer config","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1PgbouncerConfigResponse"}}}},"500":{"description":"Failed to retrieve project's pgbouncer config"}},"tags":["database"]}},"/v1/projects/{ref}/config/database/pooler":{"get":{"operationId":"v1-get-supavisor-config","summary":"Gets project's supavisor config","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SupavisorConfigResponse"}}}}},"500":{"description":"Failed to retrieve project's supavisor config"}},"tags":["database"],"security":[{"bearer":[]}]},"patch":{"operationId":"v1-update-supavisor-config","summary":"Updates project's supavisor config","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSupavisorConfigBody"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSupavisorConfigResponse"}}}},"403":{"description":""},"500":{"description":"Failed to update project's supavisor config"}},"tags":["database"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/config/auth":{"get":{"operationId":"v1-get-auth-service-config","summary":"Gets project's auth config","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthConfigResponse"}}}},"403":{"description":""},"500":{"description":"Failed to retrieve project's auth config"}},"tags":["auth"],"security":[{"bearer":[]}]},"patch":{"operationId":"v1-update-auth-service-config","summary":"Updates a project's auth config","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAuthConfigBody"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthConfigResponse"}}}},"403":{"description":""},"500":{"description":"Failed to update project's auth config"}},"tags":["auth"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/database/query":{"post":{"operationId":"v1-run-a-query","summary":"[Beta] Run sql query","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1RunQueryBody"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}},"403":{"description":""},"500":{"description":"Failed to run sql query"}},"tags":["database"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/database/webhooks/enable":{"post":{"operationId":"v1-enable-database-webhook","summary":"[Beta] Enables Database Webhooks on the project","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"201":{"description":""},"403":{"description":""},"500":{"description":"Failed to enable Database Webhooks on the project"}},"tags":["database"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/functions":{"post":{"operationId":"createFunction","summary":"Create a function","description":"Creates a function and adds it to the specified project.","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}},{"name":"slug","required":false,"in":"query","schema":{"pattern":"/^[A-Za-z0-9_-]+$/","type":"string"}},{"name":"name","required":false,"in":"query","schema":{"type":"string"}},{"name":"verify_jwt","required":false,"in":"query","schema":{"type":"boolean"}},{"name":"import_map","required":false,"in":"query","schema":{"type":"boolean"}},{"name":"entrypoint_path","required":false,"in":"query","schema":{"type":"string"}},{"name":"import_map_path","required":false,"in":"query","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1CreateFunctionBody"}},"application/vnd.denoland.eszip":{"schema":{"$ref":"#/components/schemas/V1CreateFunctionBody"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FunctionResponse"}}}},"403":{"description":""},"500":{"description":"Failed to create project's function"}},"tags":["edge functions"],"security":[{"bearer":[]}]},"get":{"operationId":"v1-list-all-functions","summary":"List all functions","description":"Returns all functions you've previously added to the specified project.","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FunctionResponse"}}}}},"403":{"description":""},"500":{"description":"Failed to retrieve project's functions"}},"tags":["edge functions"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/functions/{function_slug}":{"get":{"operationId":"v1-get-a-function","summary":"Retrieve a function","description":"Retrieves a function with the specified slug and project.","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}},{"name":"function_slug","required":true,"in":"path","description":"Function slug","schema":{"pattern":"/^[A-Za-z0-9_-]+$/","type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FunctionSlugResponse"}}}},"403":{"description":""},"500":{"description":"Failed to retrieve function with given slug"}},"tags":["edge functions"],"security":[{"bearer":[]}]},"patch":{"operationId":"v1-update-a-function","summary":"Update a function","description":"Updates a function with the specified slug and project.","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}},{"name":"function_slug","required":true,"in":"path","description":"Function slug","schema":{"pattern":"/^[A-Za-z0-9_-]+$/","type":"string"}},{"name":"slug","required":false,"in":"query","schema":{"pattern":"/^[A-Za-z0-9_-]+$/","type":"string"}},{"name":"name","required":false,"in":"query","schema":{"type":"string"}},{"name":"verify_jwt","required":false,"in":"query","schema":{"type":"boolean"}},{"name":"import_map","required":false,"in":"query","schema":{"type":"boolean"}},{"name":"entrypoint_path","required":false,"in":"query","schema":{"type":"string"}},{"name":"import_map_path","required":false,"in":"query","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1UpdateFunctionBody"}},"application/vnd.denoland.eszip":{"schema":{"$ref":"#/components/schemas/V1UpdateFunctionBody"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FunctionResponse"}}}},"403":{"description":""},"500":{"description":"Failed to update function with given slug"}},"tags":["edge functions"],"security":[{"bearer":[]}]},"delete":{"operationId":"v1-delete-a-function","summary":"Delete a function","description":"Deletes a function with the specified slug from the specified project.","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}},{"name":"function_slug","required":true,"in":"path","description":"Function slug","schema":{"pattern":"/^[A-Za-z0-9_-]+$/","type":"string"}}],"responses":{"200":{"description":""},"403":{"description":""},"500":{"description":"Failed to delete function with given slug"}},"tags":["edge functions"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/functions/{function_slug}/body":{"get":{"operationId":"v1-get-a-function-body","summary":"Retrieve a function body","description":"Retrieves a function body for the specified slug and project.","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}},{"name":"function_slug","required":true,"in":"path","description":"Function slug","schema":{"pattern":"/^[A-Za-z0-9_-]+$/","type":"string"}}],"responses":{"200":{"description":""},"403":{"description":""},"500":{"description":"Failed to retrieve function body with given slug"}},"tags":["edge functions"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/storage/buckets":{"get":{"operationId":"v1-list-all-buckets","summary":"Lists all buckets","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/V1StorageBucketResponse"}}}}},"403":{"description":""},"500":{"description":"Failed to get list of buckets"}},"tags":["storage"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/config/auth/sso/providers":{"post":{"operationId":"v1-create-a-sso-provider","summary":"Creates a new SSO provider","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProviderBody"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProviderResponse"}}}},"403":{"description":""},"404":{"description":"SAML 2.0 support is not enabled for this project"}},"tags":["auth"],"security":[{"bearer":[]}]},"get":{"operationId":"v1-list-all-sso-provider","summary":"Lists all SSO providers","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListProvidersResponse"}}}},"403":{"description":""},"404":{"description":"SAML 2.0 support is not enabled for this project"}},"tags":["auth"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/config/auth/sso/providers/{provider_id}":{"get":{"operationId":"v1-get-a-sso-provider","summary":"Gets a SSO provider by its UUID","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}},{"name":"provider_id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetProviderResponse"}}}},"403":{"description":""},"404":{"description":"Either SAML 2.0 was not enabled for this project, or the provider does not exist"}},"tags":["auth"],"security":[{"bearer":[]}]},"put":{"operationId":"v1-update-a-sso-provider","summary":"Updates a SSO provider by its UUID","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}},{"name":"provider_id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateProviderBody"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateProviderResponse"}}}},"403":{"description":""},"404":{"description":"Either SAML 2.0 was not enabled for this project, or the provider does not exist"}},"tags":["auth"],"security":[{"bearer":[]}]},"delete":{"operationId":"v1-delete-a-sso-provider","summary":"Removes a SSO provider by its UUID","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}},{"name":"provider_id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteProviderResponse"}}}},"403":{"description":""},"404":{"description":"Either SAML 2.0 was not enabled for this project, or the provider does not exist"}},"tags":["auth"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/database/backups":{"get":{"operationId":"v1-list-all-backups","summary":"Lists all backups","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1BackupsResponse"}}}},"500":{"description":"Failed to get backups"}},"tags":["database"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/database/backups/restore-pitr":{"post":{"operationId":"v1-restore-pitr-backup","summary":"Restores a PITR backup for a database","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1RestorePitrBody"}}}},"responses":{"201":{"description":""}},"tags":["database"],"security":[{"bearer":[]}]}},"/v1/organizations/{slug}/members":{"get":{"operationId":"v1-list-organization-members","summary":"List members of an organization","parameters":[{"name":"slug","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/V1OrganizationMemberResponse"}}}}}},"tags":["organizations"],"security":[{"bearer":[]}]}},"/v1/organizations/{slug}":{"get":{"operationId":"v1-get-an-organization","summary":"Gets information about the organization","parameters":[{"name":"slug","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1OrganizationSlugResponse"}}}}},"tags":["organizations"],"security":[{"bearer":[]}]}}},"info":{"title":"Supabase API (v1)","description":"","version":"1.0.0","contact":{}},"tags":[{"name":"organizations","description":"Organization endpoints"},{"name":"projects","description":"Project endpoints"}],"servers":[],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"BranchDetailResponse":{"type":"object","properties":{"db_port":{"type":"integer"},"ref":{"type":"string"},"postgres_version":{"type":"string"},"status":{"enum":["ACTIVE_HEALTHY","ACTIVE_UNHEALTHY","COMING_UP","GOING_DOWN","INACTIVE","INIT_FAILED","REMOVED","RESTORING","UNKNOWN","UPGRADING","PAUSING"],"type":"string"},"db_host":{"type":"string"},"db_user":{"type":"string"},"db_pass":{"type":"string"},"jwt_secret":{"type":"string"}},"required":["db_port","ref","postgres_version","status","db_host"]},"UpdateBranchBody":{"type":"object","properties":{"branch_name":{"type":"string"},"git_branch":{"type":"string"},"reset_on_push":{"type":"boolean"},"persistent":{"type":"boolean"}}},"BranchResponse":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"project_ref":{"type":"string"},"parent_project_ref":{"type":"string"},"is_default":{"type":"boolean"},"git_branch":{"type":"string"},"pr_number":{"type":"number"},"latest_check_run_id":{"type":"number"},"reset_on_push":{"type":"boolean"},"persistent":{"type":"boolean"},"status":{"enum":["CREATING_PROJECT","RUNNING_MIGRATIONS","MIGRATIONS_PASSED","MIGRATIONS_FAILED","FUNCTIONS_DEPLOYED","FUNCTIONS_FAILED"],"type":"string"},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id","name","project_ref","parent_project_ref","is_default","reset_on_push","persistent","status","created_at","updated_at"]},"BranchDeleteResponse":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]},"BranchResetResponse":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]},"V1DatabaseResponse":{"type":"object","properties":{"host":{"type":"string","description":"Database host"},"version":{"type":"string","description":"Database version"}},"required":["host","version"]},"V1ProjectResponse":{"type":"object","properties":{"id":{"type":"string","description":"Id of your project"},"organization_id":{"type":"string","description":"Slug of your organization"},"name":{"type":"string","description":"Name of your project"},"region":{"type":"string","description":"Region of your project","example":"us-east-1"},"created_at":{"type":"string","description":"Creation timestamp","example":"2023-03-29T16:32:59Z"},"database":{"$ref":"#/components/schemas/V1DatabaseResponse"},"status":{"enum":["ACTIVE_HEALTHY","ACTIVE_UNHEALTHY","COMING_UP","GOING_DOWN","INACTIVE","INIT_FAILED","REMOVED","RESTORING","UNKNOWN","UPGRADING","PAUSING"],"type":"string"}},"required":["id","organization_id","name","region","created_at","status"]},"DesiredInstanceSize":{"type":"string","enum":["micro","small","medium","large","xlarge","2xlarge","4xlarge","8xlarge","12xlarge","16xlarge"]},"V1CreateProjectBody":{"type":"object","properties":{"db_pass":{"type":"string","description":"Database password"},"name":{"type":"string","description":"Name of your project, should not contain dots"},"organization_id":{"type":"string","description":"Slug of your organization"},"plan":{"type":"string","enum":["free","pro"],"description":"Subscription plan is now set on organization level and is ignored in this request","example":"free","deprecated":true},"region":{"type":"string","enum":["us-east-1","us-west-1","us-west-2","ap-east-1","ap-southeast-1","ap-northeast-1","ap-northeast-2","ap-southeast-2","eu-west-1","eu-west-2","eu-west-3","eu-central-1","ca-central-1","ap-south-1","sa-east-1"],"description":"Region you want your server to reside in","example":"us-east-1"},"kps_enabled":{"type":"boolean","deprecated":true,"description":"This field is deprecated and is ignored in this request"},"desired_instance_size":{"$ref":"#/components/schemas/DesiredInstanceSize"},"template_url":{"type":"string","description":"Template URL used to create the project from the CLI.","example":"https://github.com/supabase/supabase/tree/master/examples/slack-clone/nextjs-slack-clone"}},"required":["db_pass","name","organization_id","region"]},"OrganizationResponseV1":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]},"CreateOrganizationBodyV1":{"type":"object","properties":{"name":{"type":"string"}},"required":["name"]},"OAuthTokenBody":{"type":"object","properties":{"grant_type":{"enum":["authorization_code","refresh_token"],"type":"string"},"client_id":{"type":"string"},"client_secret":{"type":"string"},"code":{"type":"string"},"code_verifier":{"type":"string"},"redirect_uri":{"type":"string"},"refresh_token":{"type":"string"}},"required":["grant_type","client_id","client_secret"]},"OAuthTokenResponse":{"type":"object","properties":{"token_type":{"type":"string","enum":["Bearer"]},"access_token":{"type":"string"},"refresh_token":{"type":"string"},"expires_in":{"type":"number"}},"required":["token_type","access_token","refresh_token","expires_in"]},"SnippetProject":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"}},"required":["id","name"]},"SnippetUser":{"type":"object","properties":{"id":{"type":"number"},"username":{"type":"string"}},"required":["id","username"]},"SnippetMeta":{"type":"object","properties":{"id":{"type":"string"},"inserted_at":{"type":"string"},"updated_at":{"type":"string"},"type":{"type":"string","enum":["sql"]},"visibility":{"type":"string","enum":["user","project","org","public"]},"name":{"type":"string"},"description":{"type":"string"},"project":{"$ref":"#/components/schemas/SnippetProject"},"owner":{"$ref":"#/components/schemas/SnippetUser"},"updated_by":{"$ref":"#/components/schemas/SnippetUser"}},"required":["id","inserted_at","updated_at","type","visibility","name","project","owner","updated_by"]},"SnippetList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/SnippetMeta"}}},"required":["data"]},"SnippetContent":{"type":"object","properties":{"favorite":{"type":"boolean"},"schema_version":{"type":"string"},"sql":{"type":"string"}},"required":["favorite","schema_version","sql"]},"SnippetResponse":{"type":"object","properties":{"id":{"type":"string"},"inserted_at":{"type":"string"},"updated_at":{"type":"string"},"type":{"type":"string","enum":["sql"]},"visibility":{"enum":["user","project","org","public"],"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"project":{"$ref":"#/components/schemas/SnippetProject"},"owner":{"$ref":"#/components/schemas/SnippetUser"},"updated_by":{"$ref":"#/components/schemas/SnippetUser"},"content":{"$ref":"#/components/schemas/SnippetContent"}},"required":["id","inserted_at","updated_at","type","visibility","name","project","owner","updated_by","content"]},"ApiKeyResponse":{"type":"object","properties":{"name":{"type":"string"},"api_key":{"type":"string"}},"required":["name","api_key"]},"CreateBranchBody":{"type":"object","properties":{"branch_name":{"type":"string"},"git_branch":{"type":"string"},"region":{"type":"string"}},"required":["branch_name"]},"UpdateCustomHostnameResponse":{"type":"object","properties":{"status":{"enum":["1_not_started","2_initiated","3_challenge_verified","4_origin_setup_completed","5_services_reconfigured"],"type":"string"},"custom_hostname":{"type":"string"},"data":{"type":"object"}},"required":["status","custom_hostname","data"]},"UpdateCustomHostnameBody":{"type":"object","properties":{"custom_hostname":{"type":"string"}},"required":["custom_hostname"]},"NetworkBanResponse":{"type":"object","properties":{"banned_ipv4_addresses":{"type":"array","items":{"type":"string"}}},"required":["banned_ipv4_addresses"]},"RemoveNetworkBanRequest":{"type":"object","properties":{"ipv4_addresses":{"type":"array","items":{"type":"string"}}},"required":["ipv4_addresses"]},"NetworkRestrictionsRequest":{"type":"object","properties":{"dbAllowedCidrs":{"type":"array","items":{"type":"string"}},"dbAllowedCidrsV6":{"type":"array","items":{"type":"string"}}}},"NetworkRestrictionsResponse":{"type":"object","properties":{"entitlement":{"enum":["disallowed","allowed"],"type":"string"},"config":{"$ref":"#/components/schemas/NetworkRestrictionsRequest"},"old_config":{"$ref":"#/components/schemas/NetworkRestrictionsRequest"},"status":{"enum":["stored","applied"],"type":"string"}},"required":["entitlement","config","status"]},"PgsodiumConfigResponse":{"type":"object","properties":{"root_key":{"type":"string"}},"required":["root_key"]},"UpdatePgsodiumConfigBody":{"type":"object","properties":{"root_key":{"type":"string"}},"required":["root_key"]},"PostgrestConfigWithJWTSecretResponse":{"type":"object","properties":{"max_rows":{"type":"integer"},"db_pool":{"type":"integer","nullable":true,"description":"If `null`, the value is automatically configured based on compute size."},"db_schema":{"type":"string"},"db_extra_search_path":{"type":"string"},"jwt_secret":{"type":"string"}},"required":["max_rows","db_pool","db_schema","db_extra_search_path"]},"UpdatePostgrestConfigBody":{"type":"object","properties":{"max_rows":{"type":"integer","minimum":0,"maximum":1000000},"db_pool":{"type":"integer","minimum":0,"maximum":1000},"db_extra_search_path":{"type":"string"},"db_schema":{"type":"string"}}},"V1PostgrestConfigResponse":{"type":"object","properties":{"max_rows":{"type":"integer"},"db_pool":{"type":"integer","nullable":true,"description":"If `null`, the value is automatically configured based on compute size."},"db_schema":{"type":"string"},"db_extra_search_path":{"type":"string"}},"required":["max_rows","db_pool","db_schema","db_extra_search_path"]},"V1ProjectRefResponse":{"type":"object","properties":{"id":{"type":"number"},"ref":{"type":"string"},"name":{"type":"string"}},"required":["id","ref","name"]},"SecretResponse":{"type":"object","properties":{"name":{"type":"string"},"value":{"type":"string"}},"required":["name","value"]},"CreateSecretBody":{"type":"object","properties":{"name":{"type":"string","maxLength":256,"pattern":"/^(?!SUPABASE_).*/","description":"Secret name must not start with the SUPABASE_ prefix.","example":"string"},"value":{"type":"string","maxLength":24576}},"required":["name","value"]},"SslEnforcements":{"type":"object","properties":{"database":{"type":"boolean"}},"required":["database"]},"SslEnforcementResponse":{"type":"object","properties":{"currentConfig":{"$ref":"#/components/schemas/SslEnforcements"},"appliedSuccessfully":{"type":"boolean"}},"required":["currentConfig","appliedSuccessfully"]},"SslEnforcementRequest":{"type":"object","properties":{"requestedConfig":{"$ref":"#/components/schemas/SslEnforcements"}},"required":["requestedConfig"]},"TypescriptResponse":{"type":"object","properties":{"types":{"type":"string"}},"required":["types"]},"VanitySubdomainConfigResponse":{"type":"object","properties":{"status":{"enum":["not-used","custom-domain-used","active"],"type":"string"},"custom_domain":{"type":"string"}},"required":["status"]},"VanitySubdomainBody":{"type":"object","properties":{"vanity_subdomain":{"type":"string"}},"required":["vanity_subdomain"]},"SubdomainAvailabilityResponse":{"type":"object","properties":{"available":{"type":"boolean"}},"required":["available"]},"ActivateVanitySubdomainResponse":{"type":"object","properties":{"custom_domain":{"type":"string"}},"required":["custom_domain"]},"UpgradeDatabaseBody":{"type":"object","properties":{"target_version":{"type":"number"}},"required":["target_version"]},"ProjectUpgradeInitiateResponse":{"type":"object","properties":{"tracking_id":{"type":"string"}},"required":["tracking_id"]},"ProjectVersion":{"type":"object","properties":{"postgres_version":{"type":"number"},"app_version":{"type":"string"}},"required":["postgres_version","app_version"]},"ProjectUpgradeEligibilityResponse":{"type":"object","properties":{"eligible":{"type":"boolean"},"current_app_version":{"type":"string"},"latest_app_version":{"type":"string"},"target_upgrade_versions":{"type":"array","items":{"$ref":"#/components/schemas/ProjectVersion"}},"potential_breaking_changes":{"type":"array","items":{"type":"string"}},"duration_estimate_hours":{"type":"number"},"legacy_auth_custom_roles":{"type":"array","items":{"type":"string"}},"extension_dependent_objects":{"type":"array","items":{"type":"string"}}},"required":["eligible","current_app_version","latest_app_version","target_upgrade_versions","potential_breaking_changes","duration_estimate_hours","legacy_auth_custom_roles","extension_dependent_objects"]},"DatabaseUpgradeStatus":{"type":"object","properties":{"initiated_at":{"type":"string"},"target_version":{"type":"number"},"error":{"type":"string","enum":["1_upgraded_instance_launch_failed","2_volume_detachchment_from_upgraded_instance_failed","3_volume_attachment_to_original_instance_failed","4_data_upgrade_initiation_failed","5_data_upgrade_completion_failed","6_volume_detachchment_from_original_instance_failed","7_volume_attachment_to_upgraded_instance_failed","8_upgrade_completion_failed"]},"progress":{"type":"string","enum":["0_requested","1_started","2_launched_upgraded_instance","3_detached_volume_from_upgraded_instance","4_attached_volume_to_original_instance","5_initiated_data_upgrade","6_completed_data_upgrade","7_detached_volume_from_original_instance","8_attached_volume_to_upgraded_instance","9_completed_upgrade"]},"status":{"type":"number","enum":[0,1,2]}},"required":["initiated_at","target_version","status"]},"DatabaseUpgradeStatusResponse":{"type":"object","properties":{"databaseUpgradeStatus":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/DatabaseUpgradeStatus"}]}},"required":["databaseUpgradeStatus"]},"ReadOnlyStatusResponse":{"type":"object","properties":{"enabled":{"type":"boolean"},"override_enabled":{"type":"boolean"},"override_active_until":{"type":"string"}},"required":["enabled","override_enabled","override_active_until"]},"SetUpReadReplicaBody":{"type":"object","properties":{"read_replica_region":{"type":"string","enum":["us-east-1","us-west-1","us-west-2","ap-east-1","ap-southeast-1","ap-northeast-1","ap-northeast-2","ap-southeast-2","eu-west-1","eu-west-2","eu-west-3","eu-central-1","ca-central-1","ap-south-1","sa-east-1"],"description":"Region you want your read replica to reside in","example":"us-east-1"}},"required":["read_replica_region"]},"RemoveReadReplicaBody":{"type":"object","properties":{"database_identifier":{"type":"string"}},"required":["database_identifier"]},"AuthHealthResponse":{"type":"object","properties":{"name":{"type":"string"},"version":{"type":"string"},"description":{"type":"string"}},"required":["name","version","description"]},"RealtimeHealthResponse":{"type":"object","properties":{"healthy":{"type":"boolean"},"db_connected":{"type":"boolean"},"connected_cluster":{"type":"number"}},"required":["healthy","db_connected","connected_cluster"]},"V1ServiceHealthResponse":{"type":"object","properties":{"info":{"oneOf":[{"$ref":"#/components/schemas/AuthHealthResponse"},{"$ref":"#/components/schemas/RealtimeHealthResponse"}]},"name":{"enum":["auth","db","pooler","realtime","rest","storage"],"type":"string"},"healthy":{"type":"boolean"},"status":{"enum":["COMING_UP","ACTIVE_HEALTHY","UNHEALTHY"],"type":"string"},"error":{"type":"string"}},"required":["name","healthy","status"]},"PostgresConfigResponse":{"type":"object","properties":{"statement_timeout":{"type":"string"},"effective_cache_size":{"type":"string"},"maintenance_work_mem":{"type":"string"},"max_connections":{"type":"integer","minimum":1,"maximum":262143},"max_locks_per_transaction":{"type":"integer","minimum":10,"maximum":2147483640},"max_parallel_maintenance_workers":{"type":"integer","minimum":0,"maximum":1024},"max_parallel_workers":{"type":"integer","minimum":0,"maximum":1024},"max_parallel_workers_per_gather":{"type":"integer","minimum":0,"maximum":1024},"max_standby_archive_delay":{"type":"string"},"max_standby_streaming_delay":{"type":"string"},"max_worker_processes":{"type":"integer","minimum":0,"maximum":262143},"shared_buffers":{"type":"string"},"work_mem":{"type":"string"},"session_replication_role":{"enum":["origin","replica","local"],"type":"string"}}},"UpdatePostgresConfigBody":{"type":"object","properties":{"statement_timeout":{"type":"string"},"effective_cache_size":{"type":"string"},"maintenance_work_mem":{"type":"string"},"max_connections":{"type":"integer","minimum":1,"maximum":262143},"max_locks_per_transaction":{"type":"integer","minimum":10,"maximum":2147483640},"max_parallel_maintenance_workers":{"type":"integer","minimum":0,"maximum":1024},"max_parallel_workers":{"type":"integer","minimum":0,"maximum":1024},"max_parallel_workers_per_gather":{"type":"integer","minimum":0,"maximum":1024},"max_standby_archive_delay":{"type":"string"},"max_standby_streaming_delay":{"type":"string"},"max_worker_processes":{"type":"integer","minimum":0,"maximum":262143},"shared_buffers":{"type":"string"},"work_mem":{"type":"string"},"session_replication_role":{"enum":["origin","replica","local"],"type":"string"}}},"V1PgbouncerConfigResponse":{"type":"object","properties":{"pool_mode":{"type":"string","enum":["transaction","session","statement"]},"default_pool_size":{"type":"number"},"ignore_startup_parameters":{"type":"string"},"max_client_conn":{"type":"number"},"connection_string":{"type":"string"}}},"SupavisorConfigResponse":{"type":"object","properties":{"identifier":{"type":"string"},"database_type":{"enum":["PRIMARY","READ_REPLICA"],"type":"string"},"is_using_scram_auth":{"type":"boolean"},"db_user":{"type":"string"},"db_host":{"type":"string"},"db_port":{"type":"number"},"db_name":{"type":"string"},"connectionString":{"type":"string"},"default_pool_size":{"type":"number","nullable":true},"max_client_conn":{"type":"number","nullable":true},"pool_mode":{"enum":["transaction","session"],"type":"string"}},"required":["identifier","database_type","is_using_scram_auth","db_user","db_host","db_port","db_name","connectionString","default_pool_size","max_client_conn","pool_mode"]},"UpdateSupavisorConfigBody":{"type":"object","properties":{"default_pool_size":{"type":"integer","nullable":true,"minimum":0,"maximum":1000},"pool_mode":{"enum":["transaction","session"],"type":"string","deprecated":true,"description":"This field is deprecated and is ignored in this request"}}},"UpdateSupavisorConfigResponse":{"type":"object","properties":{"default_pool_size":{"type":"number","nullable":true},"pool_mode":{"enum":["transaction","session"],"type":"string"}},"required":["default_pool_size","pool_mode"]},"AuthConfigResponse":{"type":"object","properties":{"api_max_request_duration":{"type":"number","nullable":true},"db_max_pool_size":{"type":"number","nullable":true},"disable_signup":{"type":"boolean","nullable":true},"external_anonymous_users_enabled":{"type":"boolean","nullable":true},"external_apple_additional_client_ids":{"type":"string","nullable":true},"external_apple_client_id":{"type":"string","nullable":true},"external_apple_enabled":{"type":"boolean","nullable":true},"external_apple_secret":{"type":"string","nullable":true},"external_azure_client_id":{"type":"string","nullable":true},"external_azure_enabled":{"type":"boolean","nullable":true},"external_azure_secret":{"type":"string","nullable":true},"external_azure_url":{"type":"string","nullable":true},"external_bitbucket_client_id":{"type":"string","nullable":true},"external_bitbucket_enabled":{"type":"boolean","nullable":true},"external_bitbucket_secret":{"type":"string","nullable":true},"external_discord_client_id":{"type":"string","nullable":true},"external_discord_enabled":{"type":"boolean","nullable":true},"external_discord_secret":{"type":"string","nullable":true},"external_email_enabled":{"type":"boolean","nullable":true},"external_facebook_client_id":{"type":"string","nullable":true},"external_facebook_enabled":{"type":"boolean","nullable":true},"external_facebook_secret":{"type":"string","nullable":true},"external_figma_client_id":{"type":"string","nullable":true},"external_figma_enabled":{"type":"boolean","nullable":true},"external_figma_secret":{"type":"string","nullable":true},"external_github_client_id":{"type":"string","nullable":true},"external_github_enabled":{"type":"boolean","nullable":true},"external_github_secret":{"type":"string","nullable":true},"external_gitlab_client_id":{"type":"string","nullable":true},"external_gitlab_enabled":{"type":"boolean","nullable":true},"external_gitlab_secret":{"type":"string","nullable":true},"external_gitlab_url":{"type":"string","nullable":true},"external_google_additional_client_ids":{"type":"string","nullable":true},"external_google_client_id":{"type":"string","nullable":true},"external_google_enabled":{"type":"boolean","nullable":true},"external_google_secret":{"type":"string","nullable":true},"external_google_skip_nonce_check":{"type":"boolean","nullable":true},"external_kakao_client_id":{"type":"string","nullable":true},"external_kakao_enabled":{"type":"boolean","nullable":true},"external_kakao_secret":{"type":"string","nullable":true},"external_keycloak_client_id":{"type":"string","nullable":true},"external_keycloak_enabled":{"type":"boolean","nullable":true},"external_keycloak_secret":{"type":"string","nullable":true},"external_keycloak_url":{"type":"string","nullable":true},"external_linkedin_oidc_client_id":{"type":"string","nullable":true},"external_linkedin_oidc_enabled":{"type":"boolean","nullable":true},"external_linkedin_oidc_secret":{"type":"string","nullable":true},"external_notion_client_id":{"type":"string","nullable":true},"external_notion_enabled":{"type":"boolean","nullable":true},"external_notion_secret":{"type":"string","nullable":true},"external_phone_enabled":{"type":"boolean","nullable":true},"external_slack_client_id":{"type":"string","nullable":true},"external_slack_enabled":{"type":"boolean","nullable":true},"external_slack_secret":{"type":"string","nullable":true},"external_spotify_client_id":{"type":"string","nullable":true},"external_spotify_enabled":{"type":"boolean","nullable":true},"external_spotify_secret":{"type":"string","nullable":true},"external_twitch_client_id":{"type":"string","nullable":true},"external_twitch_enabled":{"type":"boolean","nullable":true},"external_twitch_secret":{"type":"string","nullable":true},"external_twitter_client_id":{"type":"string","nullable":true},"external_twitter_enabled":{"type":"boolean","nullable":true},"external_twitter_secret":{"type":"string","nullable":true},"external_workos_client_id":{"type":"string","nullable":true},"external_workos_enabled":{"type":"boolean","nullable":true},"external_workos_secret":{"type":"string","nullable":true},"external_workos_url":{"type":"string","nullable":true},"external_zoom_client_id":{"type":"string","nullable":true},"external_zoom_enabled":{"type":"boolean","nullable":true},"external_zoom_secret":{"type":"string","nullable":true},"hook_custom_access_token_enabled":{"type":"boolean","nullable":true},"hook_custom_access_token_uri":{"type":"string","nullable":true},"hook_custom_access_token_secrets":{"type":"string","nullable":true},"hook_mfa_verification_attempt_enabled":{"type":"boolean","nullable":true},"hook_mfa_verification_attempt_uri":{"type":"string","nullable":true},"hook_mfa_verification_attempt_secrets":{"type":"string","nullable":true},"hook_password_verification_attempt_enabled":{"type":"boolean","nullable":true},"hook_password_verification_attempt_uri":{"type":"string","nullable":true},"hook_password_verification_attempt_secrets":{"type":"string","nullable":true},"hook_send_sms_enabled":{"type":"boolean","nullable":true},"hook_send_sms_uri":{"type":"string","nullable":true},"hook_send_sms_secrets":{"type":"string","nullable":true},"hook_send_email_enabled":{"type":"boolean","nullable":true},"hook_send_email_uri":{"type":"string","nullable":true},"hook_send_email_secrets":{"type":"string","nullable":true},"jwt_exp":{"type":"number","nullable":true},"mailer_allow_unverified_email_sign_ins":{"type":"boolean","nullable":true},"mailer_autoconfirm":{"type":"boolean","nullable":true},"mailer_otp_exp":{"type":"number"},"mailer_otp_length":{"type":"number","nullable":true},"mailer_secure_email_change_enabled":{"type":"boolean","nullable":true},"mailer_subjects_confirmation":{"type":"string","nullable":true},"mailer_subjects_email_change":{"type":"string","nullable":true},"mailer_subjects_invite":{"type":"string","nullable":true},"mailer_subjects_magic_link":{"type":"string","nullable":true},"mailer_subjects_reauthentication":{"type":"string","nullable":true},"mailer_subjects_recovery":{"type":"string","nullable":true},"mailer_templates_confirmation_content":{"type":"string","nullable":true},"mailer_templates_email_change_content":{"type":"string","nullable":true},"mailer_templates_invite_content":{"type":"string","nullable":true},"mailer_templates_magic_link_content":{"type":"string","nullable":true},"mailer_templates_reauthentication_content":{"type":"string","nullable":true},"mailer_templates_recovery_content":{"type":"string","nullable":true},"mfa_max_enrolled_factors":{"type":"number","nullable":true},"password_hibp_enabled":{"type":"boolean","nullable":true},"password_min_length":{"type":"number","nullable":true},"password_required_characters":{"type":"string","nullable":true},"rate_limit_anonymous_users":{"type":"number","nullable":true},"rate_limit_email_sent":{"type":"number","nullable":true},"rate_limit_sms_sent":{"type":"number","nullable":true},"rate_limit_token_refresh":{"type":"number","nullable":true},"rate_limit_verify":{"type":"number","nullable":true},"refresh_token_rotation_enabled":{"type":"boolean","nullable":true},"saml_enabled":{"type":"boolean","nullable":true},"security_captcha_enabled":{"type":"boolean","nullable":true},"security_captcha_provider":{"type":"string","nullable":true},"security_captcha_secret":{"type":"string","nullable":true},"security_manual_linking_enabled":{"type":"boolean","nullable":true},"security_refresh_token_reuse_interval":{"type":"number","nullable":true},"security_update_password_require_reauthentication":{"type":"boolean","nullable":true},"sessions_inactivity_timeout":{"type":"number","nullable":true},"sessions_single_per_user":{"type":"boolean","nullable":true},"sessions_tags":{"type":"string","nullable":true},"sessions_timebox":{"type":"number","nullable":true},"site_url":{"type":"string","nullable":true},"sms_autoconfirm":{"type":"boolean","nullable":true},"sms_max_frequency":{"type":"number","nullable":true},"sms_messagebird_access_key":{"type":"string","nullable":true},"sms_messagebird_originator":{"type":"string","nullable":true},"sms_otp_exp":{"type":"number","nullable":true},"sms_otp_length":{"type":"number"},"sms_provider":{"type":"string","nullable":true},"sms_template":{"type":"string","nullable":true},"sms_test_otp":{"type":"string","nullable":true},"sms_test_otp_valid_until":{"type":"string","nullable":true},"sms_textlocal_api_key":{"type":"string","nullable":true},"sms_textlocal_sender":{"type":"string","nullable":true},"sms_twilio_account_sid":{"type":"string","nullable":true},"sms_twilio_auth_token":{"type":"string","nullable":true},"sms_twilio_content_sid":{"type":"string","nullable":true},"sms_twilio_message_service_sid":{"type":"string","nullable":true},"sms_twilio_verify_account_sid":{"type":"string","nullable":true},"sms_twilio_verify_auth_token":{"type":"string","nullable":true},"sms_twilio_verify_message_service_sid":{"type":"string","nullable":true},"sms_vonage_api_key":{"type":"string","nullable":true},"sms_vonage_api_secret":{"type":"string","nullable":true},"sms_vonage_from":{"type":"string","nullable":true},"smtp_admin_email":{"type":"string","nullable":true},"smtp_host":{"type":"string","nullable":true},"smtp_max_frequency":{"type":"number","nullable":true},"smtp_pass":{"type":"string","nullable":true},"smtp_port":{"type":"string","nullable":true},"smtp_sender_name":{"type":"string","nullable":true},"smtp_user":{"type":"string","nullable":true},"uri_allow_list":{"type":"string","nullable":true}},"required":["api_max_request_duration","db_max_pool_size","disable_signup","external_anonymous_users_enabled","external_apple_additional_client_ids","external_apple_client_id","external_apple_enabled","external_apple_secret","external_azure_client_id","external_azure_enabled","external_azure_secret","external_azure_url","external_bitbucket_client_id","external_bitbucket_enabled","external_bitbucket_secret","external_discord_client_id","external_discord_enabled","external_discord_secret","external_email_enabled","external_facebook_client_id","external_facebook_enabled","external_facebook_secret","external_figma_client_id","external_figma_enabled","external_figma_secret","external_github_client_id","external_github_enabled","external_github_secret","external_gitlab_client_id","external_gitlab_enabled","external_gitlab_secret","external_gitlab_url","external_google_additional_client_ids","external_google_client_id","external_google_enabled","external_google_secret","external_google_skip_nonce_check","external_kakao_client_id","external_kakao_enabled","external_kakao_secret","external_keycloak_client_id","external_keycloak_enabled","external_keycloak_secret","external_keycloak_url","external_linkedin_oidc_client_id","external_linkedin_oidc_enabled","external_linkedin_oidc_secret","external_notion_client_id","external_notion_enabled","external_notion_secret","external_phone_enabled","external_slack_client_id","external_slack_enabled","external_slack_secret","external_spotify_client_id","external_spotify_enabled","external_spotify_secret","external_twitch_client_id","external_twitch_enabled","external_twitch_secret","external_twitter_client_id","external_twitter_enabled","external_twitter_secret","external_workos_client_id","external_workos_enabled","external_workos_secret","external_workos_url","external_zoom_client_id","external_zoom_enabled","external_zoom_secret","hook_custom_access_token_enabled","hook_custom_access_token_uri","hook_custom_access_token_secrets","hook_mfa_verification_attempt_enabled","hook_mfa_verification_attempt_uri","hook_mfa_verification_attempt_secrets","hook_password_verification_attempt_enabled","hook_password_verification_attempt_uri","hook_password_verification_attempt_secrets","hook_send_sms_enabled","hook_send_sms_uri","hook_send_sms_secrets","hook_send_email_enabled","hook_send_email_uri","hook_send_email_secrets","jwt_exp","mailer_allow_unverified_email_sign_ins","mailer_autoconfirm","mailer_otp_exp","mailer_otp_length","mailer_secure_email_change_enabled","mailer_subjects_confirmation","mailer_subjects_email_change","mailer_subjects_invite","mailer_subjects_magic_link","mailer_subjects_reauthentication","mailer_subjects_recovery","mailer_templates_confirmation_content","mailer_templates_email_change_content","mailer_templates_invite_content","mailer_templates_magic_link_content","mailer_templates_reauthentication_content","mailer_templates_recovery_content","mfa_max_enrolled_factors","password_hibp_enabled","password_min_length","password_required_characters","rate_limit_anonymous_users","rate_limit_email_sent","rate_limit_sms_sent","rate_limit_token_refresh","rate_limit_verify","refresh_token_rotation_enabled","saml_enabled","security_captcha_enabled","security_captcha_provider","security_captcha_secret","security_manual_linking_enabled","security_refresh_token_reuse_interval","security_update_password_require_reauthentication","sessions_inactivity_timeout","sessions_single_per_user","sessions_tags","sessions_timebox","site_url","sms_autoconfirm","sms_max_frequency","sms_messagebird_access_key","sms_messagebird_originator","sms_otp_exp","sms_otp_length","sms_provider","sms_template","sms_test_otp","sms_test_otp_valid_until","sms_textlocal_api_key","sms_textlocal_sender","sms_twilio_account_sid","sms_twilio_auth_token","sms_twilio_content_sid","sms_twilio_message_service_sid","sms_twilio_verify_account_sid","sms_twilio_verify_auth_token","sms_twilio_verify_message_service_sid","sms_vonage_api_key","sms_vonage_api_secret","sms_vonage_from","smtp_admin_email","smtp_host","smtp_max_frequency","smtp_pass","smtp_port","smtp_sender_name","smtp_user","uri_allow_list"]},"UpdateAuthConfigBody":{"type":"object","properties":{"site_url":{"type":"string","pattern":"/^[^,]+$/"},"disable_signup":{"type":"boolean"},"jwt_exp":{"type":"number","minimum":0,"maximum":604800},"smtp_admin_email":{"type":"string"},"smtp_host":{"type":"string"},"smtp_port":{"type":"string"},"smtp_user":{"type":"string"},"smtp_pass":{"type":"string"},"smtp_max_frequency":{"type":"number","minimum":0,"maximum":32767},"smtp_sender_name":{"type":"string"},"mailer_allow_unverified_email_sign_ins":{"type":"boolean"},"mailer_autoconfirm":{"type":"boolean"},"mailer_subjects_invite":{"type":"string"},"mailer_subjects_confirmation":{"type":"string"},"mailer_subjects_recovery":{"type":"string"},"mailer_subjects_email_change":{"type":"string"},"mailer_subjects_magic_link":{"type":"string"},"mailer_subjects_reauthentication":{"type":"string"},"mailer_templates_invite_content":{"type":"string"},"mailer_templates_confirmation_content":{"type":"string"},"mailer_templates_recovery_content":{"type":"string"},"mailer_templates_email_change_content":{"type":"string"},"mailer_templates_magic_link_content":{"type":"string"},"mailer_templates_reauthentication_content":{"type":"string"},"mfa_max_enrolled_factors":{"type":"number","minimum":0,"maximum":2147483647},"uri_allow_list":{"type":"string"},"external_anonymous_users_enabled":{"type":"boolean"},"external_email_enabled":{"type":"boolean"},"external_phone_enabled":{"type":"boolean"},"saml_enabled":{"type":"boolean"},"security_captcha_enabled":{"type":"boolean"},"security_captcha_provider":{"type":"string"},"security_captcha_secret":{"type":"string"},"sessions_timebox":{"type":"number","minimum":0},"sessions_inactivity_timeout":{"type":"number","minimum":0},"sessions_single_per_user":{"type":"boolean"},"sessions_tags":{"type":"string","pattern":"/^\\s*([a-z0-9_-]+(\\s*,+\\s*)?)*\\s*$/i"},"rate_limit_anonymous_users":{"type":"number","minimum":1,"maximum":2147483647},"rate_limit_email_sent":{"type":"number","minimum":1,"maximum":2147483647},"rate_limit_sms_sent":{"type":"number","minimum":1,"maximum":2147483647},"rate_limit_verify":{"type":"number","minimum":1,"maximum":2147483647},"rate_limit_token_refresh":{"type":"number","minimum":1,"maximum":2147483647},"mailer_secure_email_change_enabled":{"type":"boolean"},"refresh_token_rotation_enabled":{"type":"boolean"},"password_hibp_enabled":{"type":"boolean"},"password_min_length":{"type":"number","minimum":6,"maximum":32767},"password_required_characters":{"type":"string","enum":["abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ:0123456789","abcdefghijklmnopqrstuvwxyz:ABCDEFGHIJKLMNOPQRSTUVWXYZ:0123456789","abcdefghijklmnopqrstuvwxyz:ABCDEFGHIJKLMNOPQRSTUVWXYZ:0123456789:!@#$%^&*()_+-=[]{};'\\\\:\"|<>?,./`~",""]},"security_manual_linking_enabled":{"type":"boolean"},"security_update_password_require_reauthentication":{"type":"boolean"},"security_refresh_token_reuse_interval":{"type":"number","minimum":0,"maximum":2147483647},"mailer_otp_exp":{"type":"number","minimum":0,"maximum":2147483647},"mailer_otp_length":{"type":"number","minimum":6,"maximum":10},"sms_autoconfirm":{"type":"boolean"},"sms_max_frequency":{"type":"number","minimum":0,"maximum":32767},"sms_otp_exp":{"type":"number","minimum":0,"maximum":2147483647},"sms_otp_length":{"type":"number","minimum":0,"maximum":32767},"sms_provider":{"type":"string"},"sms_messagebird_access_key":{"type":"string"},"sms_messagebird_originator":{"type":"string"},"sms_test_otp":{"type":"string","pattern":"/^([0-9]{1,15}=[0-9]+,?)*$/"},"sms_test_otp_valid_until":{"type":"string"},"sms_textlocal_api_key":{"type":"string"},"sms_textlocal_sender":{"type":"string"},"sms_twilio_account_sid":{"type":"string"},"sms_twilio_auth_token":{"type":"string"},"sms_twilio_content_sid":{"type":"string"},"sms_twilio_message_service_sid":{"type":"string"},"sms_twilio_verify_account_sid":{"type":"string"},"sms_twilio_verify_auth_token":{"type":"string"},"sms_twilio_verify_message_service_sid":{"type":"string"},"sms_vonage_api_key":{"type":"string"},"sms_vonage_api_secret":{"type":"string"},"sms_vonage_from":{"type":"string"},"sms_template":{"type":"string"},"hook_mfa_verification_attempt_enabled":{"type":"boolean"},"hook_mfa_verification_attempt_uri":{"type":"string"},"hook_mfa_verification_attempt_secrets":{"type":"string"},"hook_password_verification_attempt_enabled":{"type":"boolean"},"hook_password_verification_attempt_uri":{"type":"string"},"hook_password_verification_attempt_secrets":{"type":"string"},"hook_custom_access_token_enabled":{"type":"boolean"},"hook_custom_access_token_uri":{"type":"string"},"hook_custom_access_token_secrets":{"type":"string"},"hook_send_sms_enabled":{"type":"boolean"},"hook_send_sms_uri":{"type":"string"},"hook_send_sms_secrets":{"type":"string"},"hook_send_email_enabled":{"type":"boolean"},"hook_send_email_uri":{"type":"string"},"hook_send_email_secrets":{"type":"string"},"external_apple_enabled":{"type":"boolean"},"external_apple_client_id":{"type":"string"},"external_apple_secret":{"type":"string"},"external_apple_additional_client_ids":{"type":"string"},"external_azure_enabled":{"type":"boolean"},"external_azure_client_id":{"type":"string"},"external_azure_secret":{"type":"string"},"external_azure_url":{"type":"string"},"external_bitbucket_enabled":{"type":"boolean"},"external_bitbucket_client_id":{"type":"string"},"external_bitbucket_secret":{"type":"string"},"external_discord_enabled":{"type":"boolean"},"external_discord_client_id":{"type":"string"},"external_discord_secret":{"type":"string"},"external_facebook_enabled":{"type":"boolean"},"external_facebook_client_id":{"type":"string"},"external_facebook_secret":{"type":"string"},"external_figma_enabled":{"type":"boolean"},"external_figma_client_id":{"type":"string"},"external_figma_secret":{"type":"string"},"external_github_enabled":{"type":"boolean"},"external_github_client_id":{"type":"string"},"external_github_secret":{"type":"string"},"external_gitlab_enabled":{"type":"boolean"},"external_gitlab_client_id":{"type":"string"},"external_gitlab_secret":{"type":"string"},"external_gitlab_url":{"type":"string"},"external_google_enabled":{"type":"boolean"},"external_google_client_id":{"type":"string"},"external_google_secret":{"type":"string"},"external_google_additional_client_ids":{"type":"string"},"external_google_skip_nonce_check":{"type":"boolean"},"external_kakao_enabled":{"type":"boolean"},"external_kakao_client_id":{"type":"string"},"external_kakao_secret":{"type":"string"},"external_keycloak_enabled":{"type":"boolean"},"external_keycloak_client_id":{"type":"string"},"external_keycloak_secret":{"type":"string"},"external_keycloak_url":{"type":"string"},"external_linkedin_oidc_enabled":{"type":"boolean"},"external_linkedin_oidc_client_id":{"type":"string"},"external_linkedin_oidc_secret":{"type":"string"},"external_notion_enabled":{"type":"boolean"},"external_notion_client_id":{"type":"string"},"external_notion_secret":{"type":"string"},"external_slack_enabled":{"type":"boolean"},"external_slack_client_id":{"type":"string"},"external_slack_secret":{"type":"string"},"external_spotify_enabled":{"type":"boolean"},"external_spotify_client_id":{"type":"string"},"external_spotify_secret":{"type":"string"},"external_twitch_enabled":{"type":"boolean"},"external_twitch_client_id":{"type":"string"},"external_twitch_secret":{"type":"string"},"external_twitter_enabled":{"type":"boolean"},"external_twitter_client_id":{"type":"string"},"external_twitter_secret":{"type":"string"},"external_workos_enabled":{"type":"boolean"},"external_workos_client_id":{"type":"string"},"external_workos_secret":{"type":"string"},"external_workos_url":{"type":"string"},"external_zoom_enabled":{"type":"boolean"},"external_zoom_client_id":{"type":"string"},"external_zoom_secret":{"type":"string"},"db_max_pool_size":{"type":"number"},"api_max_request_duration":{"type":"number"}}},"V1RunQueryBody":{"type":"object","properties":{"query":{"type":"string"}},"required":["query"]},"V1CreateFunctionBody":{"type":"object","properties":{"slug":{"type":"string","pattern":"/^[A-Za-z0-9_-]+$/"},"name":{"type":"string"},"body":{"type":"string"},"verify_jwt":{"type":"boolean"}},"required":["slug","name","body"]},"FunctionResponse":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"status":{"enum":["ACTIVE","REMOVED","THROTTLED"],"type":"string"},"version":{"type":"number"},"created_at":{"type":"number"},"updated_at":{"type":"number"},"verify_jwt":{"type":"boolean"},"import_map":{"type":"boolean"},"entrypoint_path":{"type":"string"},"import_map_path":{"type":"string"}},"required":["id","slug","name","status","version","created_at","updated_at"]},"FunctionSlugResponse":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"status":{"enum":["ACTIVE","REMOVED","THROTTLED"],"type":"string"},"version":{"type":"number"},"created_at":{"type":"number"},"updated_at":{"type":"number"},"verify_jwt":{"type":"boolean"},"import_map":{"type":"boolean"},"entrypoint_path":{"type":"string"},"import_map_path":{"type":"string"}},"required":["id","slug","name","status","version","created_at","updated_at"]},"V1UpdateFunctionBody":{"type":"object","properties":{"name":{"type":"string"},"body":{"type":"string"},"verify_jwt":{"type":"boolean"}}},"V1StorageBucketResponse":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"owner":{"type":"string"},"created_at":{"type":"string"},"updated_at":{"type":"string"},"public":{"type":"boolean"}},"required":["id","name","owner","created_at","updated_at","public"]},"AttributeValue":{"type":"object","properties":{"default":{"oneOf":[{"type":"object"},{"type":"number"},{"type":"string"},{"type":"boolean"}]},"name":{"type":"string"},"names":{"type":"array","items":{"type":"string"}}}},"AttributeMapping":{"type":"object","properties":{"keys":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/AttributeValue"}}},"required":["keys"]},"CreateProviderBody":{"type":"object","properties":{"type":{"type":"string","enum":["saml"],"description":"What type of provider will be created"},"metadata_xml":{"type":"string"},"metadata_url":{"type":"string"},"domains":{"type":"array","items":{"type":"string"}},"attribute_mapping":{"$ref":"#/components/schemas/AttributeMapping"}},"required":["type"]},"SamlDescriptor":{"type":"object","properties":{"id":{"type":"string"},"entity_id":{"type":"string"},"metadata_url":{"type":"string"},"metadata_xml":{"type":"string"},"attribute_mapping":{"$ref":"#/components/schemas/AttributeMapping"}},"required":["id","entity_id"]},"Domain":{"type":"object","properties":{"id":{"type":"string"},"domain":{"type":"string"},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id"]},"CreateProviderResponse":{"type":"object","properties":{"id":{"type":"string"},"saml":{"$ref":"#/components/schemas/SamlDescriptor"},"domains":{"type":"array","items":{"$ref":"#/components/schemas/Domain"}},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id"]},"Provider":{"type":"object","properties":{"id":{"type":"string"},"saml":{"$ref":"#/components/schemas/SamlDescriptor"},"domains":{"type":"array","items":{"$ref":"#/components/schemas/Domain"}},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id"]},"ListProvidersResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Provider"}}},"required":["items"]},"GetProviderResponse":{"type":"object","properties":{"id":{"type":"string"},"saml":{"$ref":"#/components/schemas/SamlDescriptor"},"domains":{"type":"array","items":{"$ref":"#/components/schemas/Domain"}},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id"]},"UpdateProviderBody":{"type":"object","properties":{"metadata_xml":{"type":"string"},"metadata_url":{"type":"string"},"domains":{"type":"array","items":{"type":"string"}},"attribute_mapping":{"$ref":"#/components/schemas/AttributeMapping"}}},"UpdateProviderResponse":{"type":"object","properties":{"id":{"type":"string"},"saml":{"$ref":"#/components/schemas/SamlDescriptor"},"domains":{"type":"array","items":{"$ref":"#/components/schemas/Domain"}},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id"]},"DeleteProviderResponse":{"type":"object","properties":{"id":{"type":"string"},"saml":{"$ref":"#/components/schemas/SamlDescriptor"},"domains":{"type":"array","items":{"$ref":"#/components/schemas/Domain"}},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id"]},"V1Backup":{"type":"object","properties":{"status":{"type":"string","enum":["COMPLETED","FAILED","PENDING","REMOVED","ARCHIVED"]},"is_physical_backup":{"type":"boolean"},"inserted_at":{"type":"string"}},"required":["status","is_physical_backup","inserted_at"]},"V1PhysicalBackup":{"type":"object","properties":{"earliest_physical_backup_date_unix":{"type":"number"},"latest_physical_backup_date_unix":{"type":"number"}}},"V1BackupsResponse":{"type":"object","properties":{"region":{"type":"string"},"walg_enabled":{"type":"boolean"},"pitr_enabled":{"type":"boolean"},"backups":{"type":"array","items":{"$ref":"#/components/schemas/V1Backup"}},"physical_backup_data":{"$ref":"#/components/schemas/V1PhysicalBackup"}},"required":["region","walg_enabled","pitr_enabled","backups","physical_backup_data"]},"V1RestorePitrBody":{"type":"object","properties":{"recovery_time_target_unix":{"type":"number"}},"required":["recovery_time_target_unix"]},"V1OrganizationMemberResponse":{"type":"object","properties":{"user_id":{"type":"string"},"user_name":{"type":"string"},"email":{"type":"string"},"role_name":{"type":"string"},"mfa_enabled":{"type":"boolean"}},"required":["user_id","user_name","role_name","mfa_enabled"]},"BillingPlanId":{"type":"string","enum":["free","pro","team","enterprise"]},"V1OrganizationSlugResponse":{"type":"object","properties":{"plan":{"$ref":"#/components/schemas/BillingPlanId"},"opt_in_tags":{"type":"array","items":{"type":"string","enum":["AI_SQL_GENERATOR_OPT_IN"]}},"id":{"type":"string"},"name":{"type":"string"}},"required":["opt_in_tags","id","name"]}}}}
\ No newline at end of file
+{"openapi":"3.0.0","paths":{"/v1/branches/{branch_id}":{"get":{"operationId":"v1-get-a-branch-config","summary":"Get database branch config","description":"Fetches configurations of the specified database branch","parameters":[{"name":"branch_id","required":true,"in":"path","description":"Branch ID","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BranchDetailResponse"}}}},"500":{"description":"Failed to retrieve database branch"}},"tags":["Environments"],"security":[{"bearer":[]}]},"patch":{"operationId":"v1-update-a-branch-config","summary":"Update database branch config","description":"Updates the configuration of the specified database branch","parameters":[{"name":"branch_id","required":true,"in":"path","description":"Branch ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateBranchBody"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BranchResponse"}}}},"500":{"description":"Failed to update database branch"}},"tags":["Environments"],"security":[{"bearer":[]}]},"delete":{"operationId":"v1-delete-a-branch","summary":"Delete a database branch","description":"Deletes the specified database branch","parameters":[{"name":"branch_id","required":true,"in":"path","description":"Branch ID","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BranchDeleteResponse"}}}},"500":{"description":"Failed to delete database branch"}},"tags":["Environments"],"security":[{"bearer":[]}]}},"/v1/branches/{branch_id}/reset":{"post":{"operationId":"v1-reset-a-branch","summary":"Resets a database branch","description":"Resets the specified database branch","parameters":[{"name":"branch_id","required":true,"in":"path","description":"Branch ID","schema":{"type":"string"}}],"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BranchResetResponse"}}}},"500":{"description":"Failed to reset database branch"}},"tags":["Environments"],"security":[{"bearer":[]}]}},"/v1/projects":{"get":{"operationId":"v1-list-all-projects","summary":"List all projects","description":"Returns a list of all projects you've previously created.","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/V1ProjectResponse"}}}}}},"tags":["Projects"],"security":[{"bearer":[]}]},"post":{"operationId":"v1-create-a-project","summary":"Create a project","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1CreateProjectBody"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1ProjectResponse"}}}}},"tags":["Projects"],"security":[{"bearer":[]}]}},"/v1/organizations":{"get":{"operationId":"v1-list-all-organizations","summary":"List all organizations","description":"Returns a list of organizations that you currently belong to.","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/OrganizationResponseV1"}}}}},"500":{"description":"Unexpected error listing organizations"}},"tags":["Organizations"],"security":[{"bearer":[]}]},"post":{"operationId":"v1-create-an-organization","summary":"Create an organization","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationBodyV1"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationResponseV1"}}}},"500":{"description":"Unexpected error creating an organization"}},"tags":["Organizations"],"security":[{"bearer":[]}]}},"/v1/oauth/authorize":{"get":{"operationId":"v1-authorize-user","summary":"[Beta] Authorize user through oauth","parameters":[{"name":"client_id","required":true,"in":"query","schema":{"type":"string"}},{"name":"response_type","required":true,"in":"query","schema":{"enum":["code","token","id_token token"],"type":"string"}},{"name":"redirect_uri","required":true,"in":"query","schema":{"type":"string"}},{"name":"scope","required":false,"in":"query","schema":{"type":"string"}},{"name":"state","required":false,"in":"query","schema":{"type":"string"}},{"name":"response_mode","required":false,"in":"query","schema":{"type":"string"}},{"name":"code_challenge","required":false,"in":"query","schema":{"type":"string"}},{"name":"code_challenge_method","required":false,"in":"query","schema":{"enum":["plain","sha256","S256"],"type":"string"}}],"responses":{"303":{"description":""}},"tags":["OAuth"],"security":[{"oauth2":["read"]}]}},"/v1/oauth/token":{"post":{"operationId":"v1-exchange-oauth-token","summary":"[Beta] Exchange auth code for user's access and refresh token","parameters":[],"requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/OAuthTokenBody"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthTokenResponse"}}}}},"tags":["OAuth"],"security":[{"oauth2":["write"]}]}},"/v1/snippets":{"get":{"operationId":"v1-list-all-snippets","summary":"Lists SQL snippets for the logged in user","parameters":[{"name":"project_ref","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SnippetList"}}}},"500":{"description":"Failed to list user's SQL snippets"}},"tags":["Database"],"security":[{"bearer":[]}]}},"/v1/snippets/{id}":{"get":{"operationId":"v1-get-a-snippet","summary":"Gets a specific SQL snippet","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SnippetResponse"}}}},"500":{"description":"Failed to retrieve SQL snippet"}},"tags":["Database"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/api-keys":{"get":{"operationId":"v1-get-project-api-keys","summary":"Get project api keys","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ApiKeyResponse"}}}}},"403":{"description":""}},"tags":["Secrets"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/branches":{"get":{"operationId":"v1-list-all-branches","summary":"List all database branches","description":"Returns all database branches of the specified project.","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/BranchResponse"}}}}},"500":{"description":"Failed to retrieve database branches"}},"tags":["Environments"],"security":[{"bearer":[]}]},"post":{"operationId":"v1-create-a-branch","summary":"Create a database branch","description":"Creates a database branch from the specified project.","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBranchBody"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BranchResponse"}}}},"500":{"description":"Failed to create database branch"}},"tags":["Environments"],"security":[{"bearer":[]}]},"delete":{"operationId":"v1-disable-preview-branching","summary":"Disables preview branching","description":"Disables preview branching for the specified project","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":""},"500":{"description":"Failed to disable preview branching"}},"tags":["Environments"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/custom-hostname":{"get":{"operationId":"v1-get-hostname-config","summary":"[Beta] Gets project's custom hostname config","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCustomHostnameResponse"}}}},"403":{"description":""},"500":{"description":"Failed to retrieve project's custom hostname config"}},"tags":["Domains"],"security":[{"bearer":[]}]},"delete":{"operationId":"v1-Delete hostname config","summary":"[Beta] Deletes a project's custom hostname configuration","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":""},"403":{"description":""},"500":{"description":"Failed to delete project custom hostname configuration"}},"tags":["Domains"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/custom-hostname/initialize":{"post":{"operationId":"v1-update-hostname-config","summary":"[Beta] Updates project's custom hostname configuration","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCustomHostnameBody"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCustomHostnameResponse"}}}},"403":{"description":""},"500":{"description":"Failed to update project custom hostname configuration"}},"tags":["Domains"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/custom-hostname/reverify":{"post":{"operationId":"v1-verify-dns-config","summary":"[Beta] Attempts to verify the DNS configuration for project's custom hostname configuration","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCustomHostnameResponse"}}}},"403":{"description":""},"500":{"description":"Failed to verify project custom hostname configuration"}},"tags":["Domains"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/custom-hostname/activate":{"post":{"operationId":"v1-activate-custom-hostname","summary":"[Beta] Activates a custom hostname for a project.","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCustomHostnameResponse"}}}},"403":{"description":""},"500":{"description":"Failed to activate project custom hostname configuration"}},"tags":["Domains"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/network-bans/retrieve":{"post":{"operationId":"v1-list-all-network-bans","summary":"[Beta] Gets project's network bans","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NetworkBanResponse"}}}},"403":{"description":""},"500":{"description":"Failed to retrieve project's network bans"}},"tags":["Projects"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/network-bans":{"delete":{"operationId":"v1-delete-network-bans","summary":"[Beta] Remove network bans.","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemoveNetworkBanRequest"}}}},"responses":{"200":{"description":""},"403":{"description":""},"500":{"description":"Failed to remove network bans."}},"tags":["Projects"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/network-restrictions":{"get":{"operationId":"v1-get-network-restrictions","summary":"[Beta] Gets project's network restrictions","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NetworkRestrictionsResponse"}}}},"403":{"description":""},"500":{"description":"Failed to retrieve project's network restrictions"}},"tags":["Projects"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/network-restrictions/apply":{"post":{"operationId":"v1-update-network-restrictions","summary":"[Beta] Updates project's network restrictions","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NetworkRestrictionsRequest"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NetworkRestrictionsResponse"}}}},"403":{"description":""},"500":{"description":"Failed to update project network restrictions"}},"tags":["Projects"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/pgsodium":{"get":{"operationId":"v1-get-pgsodium-config","summary":"[Beta] Gets project's pgsodium config","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PgsodiumConfigResponse"}}}},"403":{"description":""},"500":{"description":"Failed to retrieve project's pgsodium config"}},"tags":["Secrets"],"security":[{"bearer":[]}]},"put":{"operationId":"v1-update-pgsodium-config","summary":"[Beta] Updates project's pgsodium config. Updating the root_key can cause all data encrypted with the older key to become inaccessible.","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePgsodiumConfigBody"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PgsodiumConfigResponse"}}}},"403":{"description":""},"500":{"description":"Failed to update project's pgsodium config"}},"tags":["Secrets"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/postgrest":{"get":{"operationId":"v1-get-postgrest-service-config","summary":"Gets project's postgrest config","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostgrestConfigWithJWTSecretResponse"}}}},"403":{"description":""},"500":{"description":"Failed to retrieve project's postgrest config"}},"tags":["Rest"],"security":[{"bearer":[]}]},"patch":{"operationId":"v1-update-postgrest-service-config","summary":"Updates project's postgrest config","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePostgrestConfigBody"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1PostgrestConfigResponse"}}}},"403":{"description":""},"500":{"description":"Failed to update project's postgrest config"}},"tags":["Rest"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}":{"delete":{"operationId":"v1-delete-a-project","summary":"Deletes the given project","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1ProjectRefResponse"}}}},"403":{"description":""}},"tags":["Projects"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/secrets":{"get":{"operationId":"v1-list-all-secrets","summary":"List all secrets","description":"Returns all secrets you've previously added to the specified project.","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SecretResponse"}}}}},"403":{"description":""},"500":{"description":"Failed to retrieve project's secrets"}},"tags":["Secrets"],"security":[{"bearer":[]}]},"post":{"operationId":"v1-bulk-create-secrets","summary":"Bulk create secrets","description":"Creates multiple secrets and adds them to the specified project.","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CreateSecretBody"}}}}},"responses":{"201":{"description":""},"403":{"description":""},"500":{"description":"Failed to create project's secrets"}},"tags":["Secrets"],"security":[{"bearer":[]}]},"delete":{"operationId":"v1-bulk-delete-secrets","summary":"Bulk delete secrets","description":"Deletes all secrets with the given names from the specified project","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"array","items":{"type":"string"}}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}},"403":{"description":""},"500":{"description":"Failed to delete secrets with given names"}},"tags":["Secrets"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/ssl-enforcement":{"get":{"operationId":"v1-get-ssl-enforcement-config","summary":"[Beta] Get project's SSL enforcement configuration.","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SslEnforcementResponse"}}}},"403":{"description":""},"500":{"description":"Failed to retrieve project's SSL enforcement config"}},"tags":["Database"],"security":[{"bearer":[]}]},"put":{"operationId":"v1-update-ssl-enforcement-config","summary":"[Beta] Update project's SSL enforcement configuration.","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SslEnforcementRequest"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SslEnforcementResponse"}}}},"403":{"description":""},"500":{"description":"Failed to update project's SSL enforcement configuration."}},"tags":["Database"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/types/typescript":{"get":{"operationId":"v1-generate-typescript-types","summary":"Generate TypeScript types","description":"Returns the TypeScript types of your schema for use with supabase-js.","parameters":[{"name":"included_schemas","required":false,"in":"query","schema":{"default":"public","type":"string"}},{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TypescriptResponse"}}}},"403":{"description":""},"500":{"description":"Failed to generate TypeScript types"}},"tags":["Database"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/vanity-subdomain":{"get":{"operationId":"v1-get-vanity-subdomain-config","summary":"[Beta] Gets current vanity subdomain config","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VanitySubdomainConfigResponse"}}}},"403":{"description":""},"500":{"description":"Failed to get project vanity subdomain configuration"}},"tags":["Domains"],"security":[{"bearer":[]}]},"delete":{"operationId":"v1-deactivate-vanity-subdomain-config","summary":"[Beta] Deletes a project's vanity subdomain configuration","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":""},"403":{"description":""},"500":{"description":"Failed to delete project vanity subdomain configuration"}},"tags":["Domains"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/vanity-subdomain/check-availability":{"post":{"operationId":"v1-check-vanity-subdomain-availability","summary":"[Beta] Checks vanity subdomain availability","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VanitySubdomainBody"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubdomainAvailabilityResponse"}}}},"403":{"description":""},"500":{"description":"Failed to check project vanity subdomain configuration"}},"tags":["Domains"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/vanity-subdomain/activate":{"post":{"operationId":"v1-activate-vanity-subdomain-config","summary":"[Beta] Activates a vanity subdomain for a project.","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VanitySubdomainBody"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivateVanitySubdomainResponse"}}}},"403":{"description":""},"500":{"description":"Failed to activate project vanity subdomain configuration"}},"tags":["Domains"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/upgrade":{"post":{"operationId":"v1-upgrade-postgres-version","summary":"[Beta] Upgrades the project's Postgres version","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeDatabaseBody"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectUpgradeInitiateResponse"}}}},"403":{"description":""},"500":{"description":"Failed to initiate project upgrade"}},"tags":["Projects"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/upgrade/eligibility":{"get":{"operationId":"v1-get-postgrest-upgrade-eligibility","summary":"[Beta] Returns the project's eligibility for upgrades","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectUpgradeEligibilityResponse"}}}},"403":{"description":""},"500":{"description":"Failed to determine project upgrade eligibility"}},"tags":["Projects"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/upgrade/status":{"get":{"operationId":"v1-get-postgrest-upgrade-status","summary":"[Beta] Gets the latest status of the project's upgrade","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DatabaseUpgradeStatusResponse"}}}},"403":{"description":""},"500":{"description":"Failed to retrieve project upgrade status"}},"tags":["Projects"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/readonly":{"get":{"operationId":"v1-get-readonly-mode-status","summary":"Returns project's readonly mode status","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadOnlyStatusResponse"}}}},"500":{"description":"Failed to get project readonly mode status"}},"tags":["Database"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/readonly/temporary-disable":{"post":{"operationId":"v1-disable-readonly-mode-temporarily","summary":"Disables project's readonly mode for the next 15 minutes","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"201":{"description":""},"500":{"description":"Failed to disable project's readonly mode"}},"tags":["Database"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/read-replicas/setup":{"post":{"operationId":"v1-setup-a-read-replica","summary":"[Beta] Set up a read replica","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetUpReadReplicaBody"}}}},"responses":{"201":{"description":""},"500":{"description":"Failed to set up read replica"}},"tags":["Database"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/read-replicas/remove":{"post":{"operationId":"v1-remove-a-read-replica","summary":"[Beta] Remove a read replica","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemoveReadReplicaBody"}}}},"responses":{"201":{"description":""},"500":{"description":"Failed to remove read replica"}},"tags":["Database"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/health":{"get":{"operationId":"v1-get-services-health","summary":"Gets project's service health status","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}},{"name":"timeout_ms","required":false,"in":"query","schema":{"minimum":0,"maximum":10000,"type":"integer"}},{"name":"services","required":true,"in":"query","schema":{"type":"array","items":{"type":"string","enum":["auth","db","pooler","realtime","rest","storage"]}}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/V1ServiceHealthResponse"}}}}},"500":{"description":"Failed to retrieve project's service health status"}},"tags":["Projects"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/config/database/postgres":{"get":{"operationId":"v1-get-postgres-config","summary":"Gets project's Postgres config","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostgresConfigResponse"}}}},"500":{"description":"Failed to retrieve project's Postgres config"}},"tags":["Database"],"security":[{"bearer":[]}]},"put":{"operationId":"v1-update-postgres-config","summary":"Updates project's Postgres config","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePostgresConfigBody"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostgresConfigResponse"}}}},"500":{"description":"Failed to update project's Postgres config"}},"tags":["Database"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/config/database/pgbouncer":{"get":{"operationId":"v1-get-project-pgbouncer-config","summary":"Get project's pgbouncer config","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1PgbouncerConfigResponse"}}}},"500":{"description":"Failed to retrieve project's pgbouncer config"}},"tags":["Database"]}},"/v1/projects/{ref}/config/database/pooler":{"get":{"operationId":"v1-get-supavisor-config","summary":"Gets project's supavisor config","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SupavisorConfigResponse"}}}}},"500":{"description":"Failed to retrieve project's supavisor config"}},"tags":["Database"],"security":[{"bearer":[]}]},"patch":{"operationId":"v1-update-supavisor-config","summary":"Updates project's supavisor config","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSupavisorConfigBody"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSupavisorConfigResponse"}}}},"403":{"description":""},"500":{"description":"Failed to update project's supavisor config"}},"tags":["Database"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/config/auth":{"get":{"operationId":"v1-get-auth-service-config","summary":"Gets project's auth config","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthConfigResponse"}}}},"403":{"description":""},"500":{"description":"Failed to retrieve project's auth config"}},"tags":["Auth"],"security":[{"bearer":[]}]},"patch":{"operationId":"v1-update-auth-service-config","summary":"Updates a project's auth config","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAuthConfigBody"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthConfigResponse"}}}},"403":{"description":""},"500":{"description":"Failed to update project's auth config"}},"tags":["Auth"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/config/auth/third-party-auth":{"post":{"operationId":"createTPAForProject","summary":"[Alpha] Creates a new third-party auth integration","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateThirdPartyAuthBody"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ThirdPartyAuth"}}}},"403":{"description":""}},"tags":["Auth"],"security":[{"bearer":[]}]},"get":{"operationId":"listTPAForProject","summary":"[Alpha] Lists all third-party auth integrations","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ThirdPartyAuth"}}}}},"403":{"description":""}},"tags":["Auth"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/config/auth/third-party-auth/{tpa_id}":{"delete":{"operationId":"deleteTPAForProject","summary":"[Alpha] Removes a third-party auth integration","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}},{"name":"tpa_id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ThirdPartyAuth"}}}},"403":{"description":""}},"tags":["Auth"],"security":[{"bearer":[]}]},"get":{"operationId":"getTPAForProject","summary":"[Alpha] Get a third-party integration","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}},{"name":"tpa_id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ThirdPartyAuth"}}}},"403":{"description":""}},"tags":["Auth"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/database/query":{"post":{"operationId":"v1-run-a-query","summary":"[Beta] Run sql query","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1RunQueryBody"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}},"403":{"description":""},"500":{"description":"Failed to run sql query"}},"tags":["Database"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/database/webhooks/enable":{"post":{"operationId":"v1-enable-database-webhook","summary":"[Beta] Enables Database Webhooks on the project","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"201":{"description":""},"403":{"description":""},"500":{"description":"Failed to enable Database Webhooks on the project"}},"tags":["Database"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/functions":{"post":{"operationId":"createFunction","summary":"Create a function","description":"Creates a function and adds it to the specified project.","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}},{"name":"slug","required":false,"in":"query","schema":{"pattern":"/^[A-Za-z0-9_-]+$/","type":"string"}},{"name":"name","required":false,"in":"query","schema":{"type":"string"}},{"name":"verify_jwt","required":false,"in":"query","schema":{"type":"boolean"}},{"name":"import_map","required":false,"in":"query","schema":{"type":"boolean"}},{"name":"entrypoint_path","required":false,"in":"query","schema":{"type":"string"}},{"name":"import_map_path","required":false,"in":"query","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1CreateFunctionBody"}},"application/vnd.denoland.eszip":{"schema":{"$ref":"#/components/schemas/V1CreateFunctionBody"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FunctionResponse"}}}},"403":{"description":""},"500":{"description":"Failed to create project's function"}},"tags":["Edge Functions"],"security":[{"bearer":[]}]},"get":{"operationId":"v1-list-all-functions","summary":"List all functions","description":"Returns all functions you've previously added to the specified project.","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FunctionResponse"}}}}},"403":{"description":""},"500":{"description":"Failed to retrieve project's functions"}},"tags":["Edge Functions"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/functions/{function_slug}":{"get":{"operationId":"v1-get-a-function","summary":"Retrieve a function","description":"Retrieves a function with the specified slug and project.","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}},{"name":"function_slug","required":true,"in":"path","description":"Function slug","schema":{"pattern":"/^[A-Za-z0-9_-]+$/","type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FunctionSlugResponse"}}}},"403":{"description":""},"500":{"description":"Failed to retrieve function with given slug"}},"tags":["Edge Functions"],"security":[{"bearer":[]}]},"patch":{"operationId":"v1-update-a-function","summary":"Update a function","description":"Updates a function with the specified slug and project.","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}},{"name":"function_slug","required":true,"in":"path","description":"Function slug","schema":{"pattern":"/^[A-Za-z0-9_-]+$/","type":"string"}},{"name":"slug","required":false,"in":"query","schema":{"pattern":"/^[A-Za-z0-9_-]+$/","type":"string"}},{"name":"name","required":false,"in":"query","schema":{"type":"string"}},{"name":"verify_jwt","required":false,"in":"query","schema":{"type":"boolean"}},{"name":"import_map","required":false,"in":"query","schema":{"type":"boolean"}},{"name":"entrypoint_path","required":false,"in":"query","schema":{"type":"string"}},{"name":"import_map_path","required":false,"in":"query","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1UpdateFunctionBody"}},"application/vnd.denoland.eszip":{"schema":{"$ref":"#/components/schemas/V1UpdateFunctionBody"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FunctionResponse"}}}},"403":{"description":""},"500":{"description":"Failed to update function with given slug"}},"tags":["Edge Functions"],"security":[{"bearer":[]}]},"delete":{"operationId":"v1-delete-a-function","summary":"Delete a function","description":"Deletes a function with the specified slug from the specified project.","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}},{"name":"function_slug","required":true,"in":"path","description":"Function slug","schema":{"pattern":"/^[A-Za-z0-9_-]+$/","type":"string"}}],"responses":{"200":{"description":""},"403":{"description":""},"500":{"description":"Failed to delete function with given slug"}},"tags":["Edge Functions"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/functions/{function_slug}/body":{"get":{"operationId":"v1-get-a-function-body","summary":"Retrieve a function body","description":"Retrieves a function body for the specified slug and project.","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}},{"name":"function_slug","required":true,"in":"path","description":"Function slug","schema":{"pattern":"/^[A-Za-z0-9_-]+$/","type":"string"}}],"responses":{"200":{"description":""},"403":{"description":""},"500":{"description":"Failed to retrieve function body with given slug"}},"tags":["Edge Functions"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/storage/buckets":{"get":{"operationId":"v1-list-all-buckets","summary":"Lists all buckets","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/V1StorageBucketResponse"}}}}},"403":{"description":""},"500":{"description":"Failed to get list of buckets"}},"tags":["Storage"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/config/auth/sso/providers":{"post":{"operationId":"v1-create-a-sso-provider","summary":"Creates a new SSO provider","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProviderBody"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProviderResponse"}}}},"403":{"description":""},"404":{"description":"SAML 2.0 support is not enabled for this project"}},"tags":["Auth"],"security":[{"bearer":[]}]},"get":{"operationId":"v1-list-all-sso-provider","summary":"Lists all SSO providers","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListProvidersResponse"}}}},"403":{"description":""},"404":{"description":"SAML 2.0 support is not enabled for this project"}},"tags":["Auth"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/config/auth/sso/providers/{provider_id}":{"get":{"operationId":"v1-get-a-sso-provider","summary":"Gets a SSO provider by its UUID","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}},{"name":"provider_id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetProviderResponse"}}}},"403":{"description":""},"404":{"description":"Either SAML 2.0 was not enabled for this project, or the provider does not exist"}},"tags":["Auth"],"security":[{"bearer":[]}]},"put":{"operationId":"v1-update-a-sso-provider","summary":"Updates a SSO provider by its UUID","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}},{"name":"provider_id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateProviderBody"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateProviderResponse"}}}},"403":{"description":""},"404":{"description":"Either SAML 2.0 was not enabled for this project, or the provider does not exist"}},"tags":["Auth"],"security":[{"bearer":[]}]},"delete":{"operationId":"v1-delete-a-sso-provider","summary":"Removes a SSO provider by its UUID","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}},{"name":"provider_id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteProviderResponse"}}}},"403":{"description":""},"404":{"description":"Either SAML 2.0 was not enabled for this project, or the provider does not exist"}},"tags":["Auth"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/database/backups":{"get":{"operationId":"v1-list-all-backups","summary":"Lists all backups","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1BackupsResponse"}}}},"500":{"description":"Failed to get backups"}},"tags":["Database"],"security":[{"bearer":[]}]}},"/v1/projects/{ref}/database/backups/restore-pitr":{"post":{"operationId":"v1-restore-pitr-backup","summary":"Restores a PITR backup for a database","parameters":[{"name":"ref","required":true,"in":"path","description":"Project ref","schema":{"minLength":20,"maxLength":20,"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1RestorePitrBody"}}}},"responses":{"201":{"description":""}},"tags":["Database"],"security":[{"bearer":[]}]}},"/v1/organizations/{slug}/members":{"get":{"operationId":"v1-list-organization-members","summary":"List members of an organization","parameters":[{"name":"slug","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/V1OrganizationMemberResponse"}}}}}},"tags":["Organizations"],"security":[{"bearer":[]}]}},"/v1/organizations/{slug}":{"get":{"operationId":"v1-get-an-organization","summary":"Gets information about the organization","parameters":[{"name":"slug","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1OrganizationSlugResponse"}}}}},"tags":["Organizations"],"security":[{"bearer":[]}]}}},"info":{"title":"Supabase API (v1)","description":"Supabase API generated from the OpenAPI specification. Visit [https://supabase.com/docs](https://supabase.com/docs) for a complete documentation.","version":"1.0.0","contact":{}},"tags":[{"name":"Auth","description":"Auth related endpoints"},{"name":"Database","description":"Database related endpoints"},{"name":"Domains","description":"Domains related endpoints"},{"name":"Edge Functions","description":"Edge related endpoints"},{"name":"Environments","description":"Environments related endpoints"},{"name":"OAuth","description":"OAuth related endpoints"},{"name":"Organizations","description":"Organizations related endpoints"},{"name":"Projects","description":"Projects related endpoints"},{"name":"Rest","description":"Rest related endpoints"},{"name":"Secrets","description":"Secrets related endpoints"},{"name":"Storage","description":"Storage related endpoints"}],"servers":[],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"BranchDetailResponse":{"type":"object","properties":{"db_port":{"type":"integer"},"ref":{"type":"string"},"postgres_version":{"type":"string"},"status":{"enum":["ACTIVE_HEALTHY","ACTIVE_UNHEALTHY","COMING_UP","GOING_DOWN","INACTIVE","INIT_FAILED","REMOVED","RESTARTING","UNKNOWN","UPGRADING","PAUSING","RESTORING","RESTORE_FAILED","PAUSE_FAILED"],"type":"string"},"db_host":{"type":"string"},"db_user":{"type":"string"},"db_pass":{"type":"string"},"jwt_secret":{"type":"string"}},"required":["db_port","ref","postgres_version","status","db_host"]},"UpdateBranchBody":{"type":"object","properties":{"branch_name":{"type":"string"},"git_branch":{"type":"string"},"reset_on_push":{"type":"boolean"},"persistent":{"type":"boolean"}}},"BranchResponse":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"project_ref":{"type":"string"},"parent_project_ref":{"type":"string"},"is_default":{"type":"boolean"},"git_branch":{"type":"string"},"pr_number":{"type":"number"},"latest_check_run_id":{"type":"number"},"reset_on_push":{"type":"boolean"},"persistent":{"type":"boolean"},"status":{"enum":["CREATING_PROJECT","RUNNING_MIGRATIONS","MIGRATIONS_PASSED","MIGRATIONS_FAILED","FUNCTIONS_DEPLOYED","FUNCTIONS_FAILED"],"type":"string"},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id","name","project_ref","parent_project_ref","is_default","reset_on_push","persistent","status","created_at","updated_at"]},"BranchDeleteResponse":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]},"BranchResetResponse":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]},"V1DatabaseResponse":{"type":"object","properties":{"host":{"type":"string","description":"Database host"},"version":{"type":"string","description":"Database version"}},"required":["host","version"]},"V1ProjectResponse":{"type":"object","properties":{"id":{"type":"string","description":"Id of your project"},"organization_id":{"type":"string","description":"Slug of your organization"},"name":{"type":"string","description":"Name of your project"},"region":{"type":"string","description":"Region of your project","example":"us-east-1"},"created_at":{"type":"string","description":"Creation timestamp","example":"2023-03-29T16:32:59Z"},"database":{"$ref":"#/components/schemas/V1DatabaseResponse"},"status":{"enum":["ACTIVE_HEALTHY","ACTIVE_UNHEALTHY","COMING_UP","GOING_DOWN","INACTIVE","INIT_FAILED","REMOVED","RESTARTING","UNKNOWN","UPGRADING","PAUSING","RESTORING","RESTORE_FAILED","PAUSE_FAILED"],"type":"string"}},"required":["id","organization_id","name","region","created_at","status"]},"DesiredInstanceSize":{"type":"string","enum":["micro","small","medium","large","xlarge","2xlarge","4xlarge","8xlarge","12xlarge","16xlarge"]},"V1CreateProjectBody":{"type":"object","properties":{"db_pass":{"type":"string","description":"Database password"},"name":{"type":"string","description":"Name of your project, should not contain dots"},"organization_id":{"type":"string","description":"Slug of your organization"},"plan":{"type":"string","enum":["free","pro"],"description":"Subscription plan is now set on organization level and is ignored in this request","example":"free","deprecated":true},"region":{"type":"string","enum":["us-east-1","us-west-1","us-west-2","ap-east-1","ap-southeast-1","ap-northeast-1","ap-northeast-2","ap-southeast-2","eu-west-1","eu-west-2","eu-west-3","eu-central-1","ca-central-1","ap-south-1","sa-east-1"],"description":"Region you want your server to reside in","example":"us-east-1"},"kps_enabled":{"type":"boolean","deprecated":true,"description":"This field is deprecated and is ignored in this request"},"desired_instance_size":{"$ref":"#/components/schemas/DesiredInstanceSize"},"template_url":{"type":"string","description":"Template URL used to create the project from the CLI.","example":"https://github.com/supabase/supabase/tree/master/examples/slack-clone/nextjs-slack-clone"}},"required":["db_pass","name","organization_id","region"]},"OrganizationResponseV1":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]},"CreateOrganizationBodyV1":{"type":"object","properties":{"name":{"type":"string"}},"required":["name"]},"OAuthTokenBody":{"type":"object","properties":{"grant_type":{"enum":["authorization_code","refresh_token"],"type":"string"},"client_id":{"type":"string"},"client_secret":{"type":"string"},"code":{"type":"string"},"code_verifier":{"type":"string"},"redirect_uri":{"type":"string"},"refresh_token":{"type":"string"}},"required":["grant_type","client_id","client_secret"]},"OAuthTokenResponse":{"type":"object","properties":{"token_type":{"type":"string","enum":["Bearer"]},"access_token":{"type":"string"},"refresh_token":{"type":"string"},"expires_in":{"type":"number"}},"required":["token_type","access_token","refresh_token","expires_in"]},"SnippetProject":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"}},"required":["id","name"]},"SnippetUser":{"type":"object","properties":{"id":{"type":"number"},"username":{"type":"string"}},"required":["id","username"]},"SnippetMeta":{"type":"object","properties":{"id":{"type":"string"},"inserted_at":{"type":"string"},"updated_at":{"type":"string"},"type":{"type":"string","enum":["sql"]},"visibility":{"type":"string","enum":["user","project","org","public"]},"name":{"type":"string"},"description":{"type":"string"},"project":{"$ref":"#/components/schemas/SnippetProject"},"owner":{"$ref":"#/components/schemas/SnippetUser"},"updated_by":{"$ref":"#/components/schemas/SnippetUser"}},"required":["id","inserted_at","updated_at","type","visibility","name","project","owner","updated_by"]},"SnippetList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/SnippetMeta"}}},"required":["data"]},"SnippetContent":{"type":"object","properties":{"favorite":{"type":"boolean"},"schema_version":{"type":"string"},"sql":{"type":"string"}},"required":["favorite","schema_version","sql"]},"SnippetResponse":{"type":"object","properties":{"id":{"type":"string"},"inserted_at":{"type":"string"},"updated_at":{"type":"string"},"type":{"type":"string","enum":["sql"]},"visibility":{"enum":["user","project","org","public"],"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"project":{"$ref":"#/components/schemas/SnippetProject"},"owner":{"$ref":"#/components/schemas/SnippetUser"},"updated_by":{"$ref":"#/components/schemas/SnippetUser"},"content":{"$ref":"#/components/schemas/SnippetContent"}},"required":["id","inserted_at","updated_at","type","visibility","name","project","owner","updated_by","content"]},"ApiKeyResponse":{"type":"object","properties":{"name":{"type":"string"},"api_key":{"type":"string"}},"required":["name","api_key"]},"CreateBranchBody":{"type":"object","properties":{"branch_name":{"type":"string"},"git_branch":{"type":"string"},"region":{"type":"string"}},"required":["branch_name"]},"ValidationRecord":{"type":"object","properties":{"txt_name":{"type":"string"},"txt_value":{"type":"string"}},"required":["txt_name","txt_value"]},"ValidationError":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]},"CustomHostnameDetails":{"type":"object","properties":{"id":{"type":"string"},"hostname":{"type":"string"},"ssl":{"type":"object","properties":{"status":{"required":true,"type":"string"},"validation_records":{"required":true,"type":"array","items":{"$ref":"#/components/schemas/ValidationRecord"}},"validation_errors":{"required":false,"type":"array","items":{"$ref":"#/components/schemas/ValidationError"}}}},"ownership_verification":{"type":"object","properties":{"type":{"required":true,"type":"string"},"name":{"required":true,"type":"string"},"value":{"required":true,"type":"string"}}},"custom_origin_server":{"type":"string"},"verification_errors":{"type":"array","items":{"type":"string"}},"status":{"type":"string"}},"required":["id","hostname","ssl","ownership_verification","custom_origin_server","status"]},"CfResponse":{"type":"object","properties":{"success":{"type":"boolean"},"errors":{"type":"array","items":{"type":"object"}},"messages":{"type":"array","items":{"type":"object"}},"result":{"$ref":"#/components/schemas/CustomHostnameDetails"}},"required":["success","errors","messages","result"]},"UpdateCustomHostnameResponse":{"type":"object","properties":{"status":{"enum":["1_not_started","2_initiated","3_challenge_verified","4_origin_setup_completed","5_services_reconfigured"],"type":"string"},"custom_hostname":{"type":"string"},"data":{"$ref":"#/components/schemas/CfResponse"}},"required":["status","custom_hostname","data"]},"UpdateCustomHostnameBody":{"type":"object","properties":{"custom_hostname":{"type":"string"}},"required":["custom_hostname"]},"NetworkBanResponse":{"type":"object","properties":{"banned_ipv4_addresses":{"type":"array","items":{"type":"string"}}},"required":["banned_ipv4_addresses"]},"RemoveNetworkBanRequest":{"type":"object","properties":{"ipv4_addresses":{"type":"array","items":{"type":"string"}}},"required":["ipv4_addresses"]},"NetworkRestrictionsRequest":{"type":"object","properties":{"dbAllowedCidrs":{"type":"array","items":{"type":"string"}},"dbAllowedCidrsV6":{"type":"array","items":{"type":"string"}}}},"NetworkRestrictionsResponse":{"type":"object","properties":{"entitlement":{"enum":["disallowed","allowed"],"type":"string"},"config":{"$ref":"#/components/schemas/NetworkRestrictionsRequest"},"old_config":{"$ref":"#/components/schemas/NetworkRestrictionsRequest"},"status":{"enum":["stored","applied"],"type":"string"}},"required":["entitlement","config","status"]},"PgsodiumConfigResponse":{"type":"object","properties":{"root_key":{"type":"string"}},"required":["root_key"]},"UpdatePgsodiumConfigBody":{"type":"object","properties":{"root_key":{"type":"string"}},"required":["root_key"]},"PostgrestConfigWithJWTSecretResponse":{"type":"object","properties":{"max_rows":{"type":"integer"},"db_pool":{"type":"integer","nullable":true,"description":"If `null`, the value is automatically configured based on compute size."},"db_schema":{"type":"string"},"db_extra_search_path":{"type":"string"},"jwt_secret":{"type":"string"}},"required":["max_rows","db_pool","db_schema","db_extra_search_path"]},"UpdatePostgrestConfigBody":{"type":"object","properties":{"max_rows":{"type":"integer","minimum":0,"maximum":1000000},"db_pool":{"type":"integer","minimum":0,"maximum":1000},"db_extra_search_path":{"type":"string"},"db_schema":{"type":"string"}}},"V1PostgrestConfigResponse":{"type":"object","properties":{"max_rows":{"type":"integer"},"db_pool":{"type":"integer","nullable":true,"description":"If `null`, the value is automatically configured based on compute size."},"db_schema":{"type":"string"},"db_extra_search_path":{"type":"string"}},"required":["max_rows","db_pool","db_schema","db_extra_search_path"]},"V1ProjectRefResponse":{"type":"object","properties":{"id":{"type":"number"},"ref":{"type":"string"},"name":{"type":"string"}},"required":["id","ref","name"]},"SecretResponse":{"type":"object","properties":{"name":{"type":"string"},"value":{"type":"string"}},"required":["name","value"]},"CreateSecretBody":{"type":"object","properties":{"name":{"type":"string","maxLength":256,"pattern":"/^(?!SUPABASE_).*/","description":"Secret name must not start with the SUPABASE_ prefix.","example":"string"},"value":{"type":"string","maxLength":24576}},"required":["name","value"]},"SslEnforcements":{"type":"object","properties":{"database":{"type":"boolean"}},"required":["database"]},"SslEnforcementResponse":{"type":"object","properties":{"currentConfig":{"$ref":"#/components/schemas/SslEnforcements"},"appliedSuccessfully":{"type":"boolean"}},"required":["currentConfig","appliedSuccessfully"]},"SslEnforcementRequest":{"type":"object","properties":{"requestedConfig":{"$ref":"#/components/schemas/SslEnforcements"}},"required":["requestedConfig"]},"TypescriptResponse":{"type":"object","properties":{"types":{"type":"string"}},"required":["types"]},"VanitySubdomainConfigResponse":{"type":"object","properties":{"status":{"enum":["not-used","custom-domain-used","active"],"type":"string"},"custom_domain":{"type":"string"}},"required":["status"]},"VanitySubdomainBody":{"type":"object","properties":{"vanity_subdomain":{"type":"string"}},"required":["vanity_subdomain"]},"SubdomainAvailabilityResponse":{"type":"object","properties":{"available":{"type":"boolean"}},"required":["available"]},"ActivateVanitySubdomainResponse":{"type":"object","properties":{"custom_domain":{"type":"string"}},"required":["custom_domain"]},"UpgradeDatabaseBody":{"type":"object","properties":{"target_version":{"type":"number"}},"required":["target_version"]},"ProjectUpgradeInitiateResponse":{"type":"object","properties":{"tracking_id":{"type":"string"}},"required":["tracking_id"]},"ProjectVersion":{"type":"object","properties":{"postgres_version":{"type":"number"},"app_version":{"type":"string"}},"required":["postgres_version","app_version"]},"ProjectUpgradeEligibilityResponse":{"type":"object","properties":{"eligible":{"type":"boolean"},"current_app_version":{"type":"string"},"latest_app_version":{"type":"string"},"target_upgrade_versions":{"type":"array","items":{"$ref":"#/components/schemas/ProjectVersion"}},"potential_breaking_changes":{"type":"array","items":{"type":"string"}},"duration_estimate_hours":{"type":"number"},"legacy_auth_custom_roles":{"type":"array","items":{"type":"string"}},"extension_dependent_objects":{"type":"array","items":{"type":"string"}}},"required":["eligible","current_app_version","latest_app_version","target_upgrade_versions","potential_breaking_changes","duration_estimate_hours","legacy_auth_custom_roles","extension_dependent_objects"]},"DatabaseUpgradeStatus":{"type":"object","properties":{"initiated_at":{"type":"string"},"latest_status_at":{"type":"string"},"target_version":{"type":"number"},"error":{"type":"string","enum":["1_upgraded_instance_launch_failed","2_volume_detachchment_from_upgraded_instance_failed","3_volume_attachment_to_original_instance_failed","4_data_upgrade_initiation_failed","5_data_upgrade_completion_failed","6_volume_detachchment_from_original_instance_failed","7_volume_attachment_to_upgraded_instance_failed","8_upgrade_completion_failed","9_post_physical_backup_failed"]},"progress":{"type":"string","enum":["0_requested","1_started","2_launched_upgraded_instance","3_detached_volume_from_upgraded_instance","4_attached_volume_to_original_instance","5_initiated_data_upgrade","6_completed_data_upgrade","7_detached_volume_from_original_instance","8_attached_volume_to_upgraded_instance","9_completed_upgrade","10_completed_post_physical_backup"]},"status":{"type":"number","enum":[0,1,2]}},"required":["initiated_at","latest_status_at","target_version","status"]},"DatabaseUpgradeStatusResponse":{"type":"object","properties":{"databaseUpgradeStatus":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/DatabaseUpgradeStatus"}]}},"required":["databaseUpgradeStatus"]},"ReadOnlyStatusResponse":{"type":"object","properties":{"enabled":{"type":"boolean"},"override_enabled":{"type":"boolean"},"override_active_until":{"type":"string"}},"required":["enabled","override_enabled","override_active_until"]},"SetUpReadReplicaBody":{"type":"object","properties":{"read_replica_region":{"type":"string","enum":["us-east-1","us-west-1","us-west-2","ap-east-1","ap-southeast-1","ap-northeast-1","ap-northeast-2","ap-southeast-2","eu-west-1","eu-west-2","eu-west-3","eu-central-1","ca-central-1","ap-south-1","sa-east-1"],"description":"Region you want your read replica to reside in","example":"us-east-1"}},"required":["read_replica_region"]},"RemoveReadReplicaBody":{"type":"object","properties":{"database_identifier":{"type":"string"}},"required":["database_identifier"]},"AuthHealthResponse":{"type":"object","properties":{"name":{"type":"string"},"version":{"type":"string"},"description":{"type":"string"}},"required":["name","version","description"]},"RealtimeHealthResponse":{"type":"object","properties":{"healthy":{"type":"boolean"},"db_connected":{"type":"boolean"},"connected_cluster":{"type":"number"}},"required":["healthy","db_connected","connected_cluster"]},"V1ServiceHealthResponse":{"type":"object","properties":{"info":{"oneOf":[{"$ref":"#/components/schemas/AuthHealthResponse"},{"$ref":"#/components/schemas/RealtimeHealthResponse"}]},"name":{"enum":["auth","db","pooler","realtime","rest","storage"],"type":"string"},"healthy":{"type":"boolean"},"status":{"enum":["COMING_UP","ACTIVE_HEALTHY","UNHEALTHY"],"type":"string"},"error":{"type":"string"}},"required":["name","healthy","status"]},"PostgresConfigResponse":{"type":"object","properties":{"statement_timeout":{"type":"string"},"effective_cache_size":{"type":"string"},"maintenance_work_mem":{"type":"string"},"max_connections":{"type":"integer","minimum":1,"maximum":262143},"max_locks_per_transaction":{"type":"integer","minimum":10,"maximum":2147483640},"max_parallel_maintenance_workers":{"type":"integer","minimum":0,"maximum":1024},"max_parallel_workers":{"type":"integer","minimum":0,"maximum":1024},"max_parallel_workers_per_gather":{"type":"integer","minimum":0,"maximum":1024},"max_standby_archive_delay":{"type":"string"},"max_standby_streaming_delay":{"type":"string"},"max_worker_processes":{"type":"integer","minimum":0,"maximum":262143},"shared_buffers":{"type":"string"},"work_mem":{"type":"string"},"session_replication_role":{"enum":["origin","replica","local"],"type":"string"}}},"UpdatePostgresConfigBody":{"type":"object","properties":{"statement_timeout":{"type":"string"},"effective_cache_size":{"type":"string"},"maintenance_work_mem":{"type":"string"},"max_connections":{"type":"integer","minimum":1,"maximum":262143},"max_locks_per_transaction":{"type":"integer","minimum":10,"maximum":2147483640},"max_parallel_maintenance_workers":{"type":"integer","minimum":0,"maximum":1024},"max_parallel_workers":{"type":"integer","minimum":0,"maximum":1024},"max_parallel_workers_per_gather":{"type":"integer","minimum":0,"maximum":1024},"max_standby_archive_delay":{"type":"string"},"max_standby_streaming_delay":{"type":"string"},"max_worker_processes":{"type":"integer","minimum":0,"maximum":262143},"shared_buffers":{"type":"string"},"work_mem":{"type":"string"},"session_replication_role":{"enum":["origin","replica","local"],"type":"string"}}},"V1PgbouncerConfigResponse":{"type":"object","properties":{"pool_mode":{"type":"string","enum":["transaction","session","statement"]},"default_pool_size":{"type":"number"},"ignore_startup_parameters":{"type":"string"},"max_client_conn":{"type":"number"},"connection_string":{"type":"string"}}},"SupavisorConfigResponse":{"type":"object","properties":{"identifier":{"type":"string"},"database_type":{"enum":["PRIMARY","READ_REPLICA"],"type":"string"},"is_using_scram_auth":{"type":"boolean"},"db_user":{"type":"string"},"db_host":{"type":"string"},"db_port":{"type":"number"},"db_name":{"type":"string"},"connectionString":{"type":"string"},"default_pool_size":{"type":"number","nullable":true},"max_client_conn":{"type":"number","nullable":true},"pool_mode":{"enum":["transaction","session"],"type":"string"}},"required":["identifier","database_type","is_using_scram_auth","db_user","db_host","db_port","db_name","connectionString","default_pool_size","max_client_conn","pool_mode"]},"UpdateSupavisorConfigBody":{"type":"object","properties":{"default_pool_size":{"type":"integer","nullable":true,"minimum":0,"maximum":1000},"pool_mode":{"enum":["transaction","session"],"type":"string","deprecated":true,"description":"This field is deprecated and is ignored in this request"}}},"UpdateSupavisorConfigResponse":{"type":"object","properties":{"default_pool_size":{"type":"number","nullable":true},"pool_mode":{"enum":["transaction","session"],"type":"string"}},"required":["default_pool_size","pool_mode"]},"AuthConfigResponse":{"type":"object","properties":{"api_max_request_duration":{"type":"number","nullable":true},"db_max_pool_size":{"type":"number","nullable":true},"disable_signup":{"type":"boolean","nullable":true},"external_anonymous_users_enabled":{"type":"boolean","nullable":true},"external_apple_additional_client_ids":{"type":"string","nullable":true},"external_apple_client_id":{"type":"string","nullable":true},"external_apple_enabled":{"type":"boolean","nullable":true},"external_apple_secret":{"type":"string","nullable":true},"external_azure_client_id":{"type":"string","nullable":true},"external_azure_enabled":{"type":"boolean","nullable":true},"external_azure_secret":{"type":"string","nullable":true},"external_azure_url":{"type":"string","nullable":true},"external_bitbucket_client_id":{"type":"string","nullable":true},"external_bitbucket_enabled":{"type":"boolean","nullable":true},"external_bitbucket_secret":{"type":"string","nullable":true},"external_discord_client_id":{"type":"string","nullable":true},"external_discord_enabled":{"type":"boolean","nullable":true},"external_discord_secret":{"type":"string","nullable":true},"external_email_enabled":{"type":"boolean","nullable":true},"external_facebook_client_id":{"type":"string","nullable":true},"external_facebook_enabled":{"type":"boolean","nullable":true},"external_facebook_secret":{"type":"string","nullable":true},"external_figma_client_id":{"type":"string","nullable":true},"external_figma_enabled":{"type":"boolean","nullable":true},"external_figma_secret":{"type":"string","nullable":true},"external_github_client_id":{"type":"string","nullable":true},"external_github_enabled":{"type":"boolean","nullable":true},"external_github_secret":{"type":"string","nullable":true},"external_gitlab_client_id":{"type":"string","nullable":true},"external_gitlab_enabled":{"type":"boolean","nullable":true},"external_gitlab_secret":{"type":"string","nullable":true},"external_gitlab_url":{"type":"string","nullable":true},"external_google_additional_client_ids":{"type":"string","nullable":true},"external_google_client_id":{"type":"string","nullable":true},"external_google_enabled":{"type":"boolean","nullable":true},"external_google_secret":{"type":"string","nullable":true},"external_google_skip_nonce_check":{"type":"boolean","nullable":true},"external_kakao_client_id":{"type":"string","nullable":true},"external_kakao_enabled":{"type":"boolean","nullable":true},"external_kakao_secret":{"type":"string","nullable":true},"external_keycloak_client_id":{"type":"string","nullable":true},"external_keycloak_enabled":{"type":"boolean","nullable":true},"external_keycloak_secret":{"type":"string","nullable":true},"external_keycloak_url":{"type":"string","nullable":true},"external_linkedin_oidc_client_id":{"type":"string","nullable":true},"external_linkedin_oidc_enabled":{"type":"boolean","nullable":true},"external_linkedin_oidc_secret":{"type":"string","nullable":true},"external_slack_oidc_client_id":{"type":"string","nullable":true},"external_slack_oidc_enabled":{"type":"boolean","nullable":true},"external_slack_oidc_secret":{"type":"string","nullable":true},"external_notion_client_id":{"type":"string","nullable":true},"external_notion_enabled":{"type":"boolean","nullable":true},"external_notion_secret":{"type":"string","nullable":true},"external_phone_enabled":{"type":"boolean","nullable":true},"external_slack_client_id":{"type":"string","nullable":true},"external_slack_enabled":{"type":"boolean","nullable":true},"external_slack_secret":{"type":"string","nullable":true},"external_spotify_client_id":{"type":"string","nullable":true},"external_spotify_enabled":{"type":"boolean","nullable":true},"external_spotify_secret":{"type":"string","nullable":true},"external_twitch_client_id":{"type":"string","nullable":true},"external_twitch_enabled":{"type":"boolean","nullable":true},"external_twitch_secret":{"type":"string","nullable":true},"external_twitter_client_id":{"type":"string","nullable":true},"external_twitter_enabled":{"type":"boolean","nullable":true},"external_twitter_secret":{"type":"string","nullable":true},"external_workos_client_id":{"type":"string","nullable":true},"external_workos_enabled":{"type":"boolean","nullable":true},"external_workos_secret":{"type":"string","nullable":true},"external_workos_url":{"type":"string","nullable":true},"external_zoom_client_id":{"type":"string","nullable":true},"external_zoom_enabled":{"type":"boolean","nullable":true},"external_zoom_secret":{"type":"string","nullable":true},"hook_custom_access_token_enabled":{"type":"boolean","nullable":true},"hook_custom_access_token_uri":{"type":"string","nullable":true},"hook_custom_access_token_secrets":{"type":"string","nullable":true},"hook_mfa_verification_attempt_enabled":{"type":"boolean","nullable":true},"hook_mfa_verification_attempt_uri":{"type":"string","nullable":true},"hook_mfa_verification_attempt_secrets":{"type":"string","nullable":true},"hook_password_verification_attempt_enabled":{"type":"boolean","nullable":true},"hook_password_verification_attempt_uri":{"type":"string","nullable":true},"hook_password_verification_attempt_secrets":{"type":"string","nullable":true},"hook_send_sms_enabled":{"type":"boolean","nullable":true},"hook_send_sms_uri":{"type":"string","nullable":true},"hook_send_sms_secrets":{"type":"string","nullable":true},"hook_send_email_enabled":{"type":"boolean","nullable":true},"hook_send_email_uri":{"type":"string","nullable":true},"hook_send_email_secrets":{"type":"string","nullable":true},"jwt_exp":{"type":"number","nullable":true},"mailer_allow_unverified_email_sign_ins":{"type":"boolean","nullable":true},"mailer_autoconfirm":{"type":"boolean","nullable":true},"mailer_otp_exp":{"type":"number"},"mailer_otp_length":{"type":"number","nullable":true},"mailer_secure_email_change_enabled":{"type":"boolean","nullable":true},"mailer_subjects_confirmation":{"type":"string","nullable":true},"mailer_subjects_email_change":{"type":"string","nullable":true},"mailer_subjects_invite":{"type":"string","nullable":true},"mailer_subjects_magic_link":{"type":"string","nullable":true},"mailer_subjects_reauthentication":{"type":"string","nullable":true},"mailer_subjects_recovery":{"type":"string","nullable":true},"mailer_templates_confirmation_content":{"type":"string","nullable":true},"mailer_templates_email_change_content":{"type":"string","nullable":true},"mailer_templates_invite_content":{"type":"string","nullable":true},"mailer_templates_magic_link_content":{"type":"string","nullable":true},"mailer_templates_reauthentication_content":{"type":"string","nullable":true},"mailer_templates_recovery_content":{"type":"string","nullable":true},"mfa_max_enrolled_factors":{"type":"number","nullable":true},"password_hibp_enabled":{"type":"boolean","nullable":true},"password_min_length":{"type":"number","nullable":true},"password_required_characters":{"type":"string","nullable":true},"rate_limit_anonymous_users":{"type":"number","nullable":true},"rate_limit_email_sent":{"type":"number","nullable":true},"rate_limit_sms_sent":{"type":"number","nullable":true},"rate_limit_token_refresh":{"type":"number","nullable":true},"rate_limit_verify":{"type":"number","nullable":true},"rate_limit_otp":{"type":"number","nullable":true},"refresh_token_rotation_enabled":{"type":"boolean","nullable":true},"saml_enabled":{"type":"boolean","nullable":true},"saml_external_url":{"type":"string","nullable":true},"security_captcha_enabled":{"type":"boolean","nullable":true},"security_captcha_provider":{"type":"string","nullable":true},"security_captcha_secret":{"type":"string","nullable":true},"security_manual_linking_enabled":{"type":"boolean","nullable":true},"security_refresh_token_reuse_interval":{"type":"number","nullable":true},"security_update_password_require_reauthentication":{"type":"boolean","nullable":true},"sessions_inactivity_timeout":{"type":"number","nullable":true},"sessions_single_per_user":{"type":"boolean","nullable":true},"sessions_tags":{"type":"string","nullable":true},"sessions_timebox":{"type":"number","nullable":true},"site_url":{"type":"string","nullable":true},"sms_autoconfirm":{"type":"boolean","nullable":true},"sms_max_frequency":{"type":"number","nullable":true},"sms_messagebird_access_key":{"type":"string","nullable":true},"sms_messagebird_originator":{"type":"string","nullable":true},"sms_otp_exp":{"type":"number","nullable":true},"sms_otp_length":{"type":"number"},"sms_provider":{"type":"string","nullable":true},"sms_template":{"type":"string","nullable":true},"sms_test_otp":{"type":"string","nullable":true},"sms_test_otp_valid_until":{"type":"string","nullable":true},"sms_textlocal_api_key":{"type":"string","nullable":true},"sms_textlocal_sender":{"type":"string","nullable":true},"sms_twilio_account_sid":{"type":"string","nullable":true},"sms_twilio_auth_token":{"type":"string","nullable":true},"sms_twilio_content_sid":{"type":"string","nullable":true},"sms_twilio_message_service_sid":{"type":"string","nullable":true},"sms_twilio_verify_account_sid":{"type":"string","nullable":true},"sms_twilio_verify_auth_token":{"type":"string","nullable":true},"sms_twilio_verify_message_service_sid":{"type":"string","nullable":true},"sms_vonage_api_key":{"type":"string","nullable":true},"sms_vonage_api_secret":{"type":"string","nullable":true},"sms_vonage_from":{"type":"string","nullable":true},"smtp_admin_email":{"type":"string","nullable":true},"smtp_host":{"type":"string","nullable":true},"smtp_max_frequency":{"type":"number","nullable":true},"smtp_pass":{"type":"string","nullable":true},"smtp_port":{"type":"string","nullable":true},"smtp_sender_name":{"type":"string","nullable":true},"smtp_user":{"type":"string","nullable":true},"uri_allow_list":{"type":"string","nullable":true}},"required":["api_max_request_duration","db_max_pool_size","disable_signup","external_anonymous_users_enabled","external_apple_additional_client_ids","external_apple_client_id","external_apple_enabled","external_apple_secret","external_azure_client_id","external_azure_enabled","external_azure_secret","external_azure_url","external_bitbucket_client_id","external_bitbucket_enabled","external_bitbucket_secret","external_discord_client_id","external_discord_enabled","external_discord_secret","external_email_enabled","external_facebook_client_id","external_facebook_enabled","external_facebook_secret","external_figma_client_id","external_figma_enabled","external_figma_secret","external_github_client_id","external_github_enabled","external_github_secret","external_gitlab_client_id","external_gitlab_enabled","external_gitlab_secret","external_gitlab_url","external_google_additional_client_ids","external_google_client_id","external_google_enabled","external_google_secret","external_google_skip_nonce_check","external_kakao_client_id","external_kakao_enabled","external_kakao_secret","external_keycloak_client_id","external_keycloak_enabled","external_keycloak_secret","external_keycloak_url","external_linkedin_oidc_client_id","external_linkedin_oidc_enabled","external_linkedin_oidc_secret","external_slack_oidc_client_id","external_slack_oidc_enabled","external_slack_oidc_secret","external_notion_client_id","external_notion_enabled","external_notion_secret","external_phone_enabled","external_slack_client_id","external_slack_enabled","external_slack_secret","external_spotify_client_id","external_spotify_enabled","external_spotify_secret","external_twitch_client_id","external_twitch_enabled","external_twitch_secret","external_twitter_client_id","external_twitter_enabled","external_twitter_secret","external_workos_client_id","external_workos_enabled","external_workos_secret","external_workos_url","external_zoom_client_id","external_zoom_enabled","external_zoom_secret","hook_custom_access_token_enabled","hook_custom_access_token_uri","hook_custom_access_token_secrets","hook_mfa_verification_attempt_enabled","hook_mfa_verification_attempt_uri","hook_mfa_verification_attempt_secrets","hook_password_verification_attempt_enabled","hook_password_verification_attempt_uri","hook_password_verification_attempt_secrets","hook_send_sms_enabled","hook_send_sms_uri","hook_send_sms_secrets","hook_send_email_enabled","hook_send_email_uri","hook_send_email_secrets","jwt_exp","mailer_allow_unverified_email_sign_ins","mailer_autoconfirm","mailer_otp_exp","mailer_otp_length","mailer_secure_email_change_enabled","mailer_subjects_confirmation","mailer_subjects_email_change","mailer_subjects_invite","mailer_subjects_magic_link","mailer_subjects_reauthentication","mailer_subjects_recovery","mailer_templates_confirmation_content","mailer_templates_email_change_content","mailer_templates_invite_content","mailer_templates_magic_link_content","mailer_templates_reauthentication_content","mailer_templates_recovery_content","mfa_max_enrolled_factors","password_hibp_enabled","password_min_length","password_required_characters","rate_limit_anonymous_users","rate_limit_email_sent","rate_limit_sms_sent","rate_limit_token_refresh","rate_limit_verify","rate_limit_otp","refresh_token_rotation_enabled","saml_enabled","saml_external_url","security_captcha_enabled","security_captcha_provider","security_captcha_secret","security_manual_linking_enabled","security_refresh_token_reuse_interval","security_update_password_require_reauthentication","sessions_inactivity_timeout","sessions_single_per_user","sessions_tags","sessions_timebox","site_url","sms_autoconfirm","sms_max_frequency","sms_messagebird_access_key","sms_messagebird_originator","sms_otp_exp","sms_otp_length","sms_provider","sms_template","sms_test_otp","sms_test_otp_valid_until","sms_textlocal_api_key","sms_textlocal_sender","sms_twilio_account_sid","sms_twilio_auth_token","sms_twilio_content_sid","sms_twilio_message_service_sid","sms_twilio_verify_account_sid","sms_twilio_verify_auth_token","sms_twilio_verify_message_service_sid","sms_vonage_api_key","sms_vonage_api_secret","sms_vonage_from","smtp_admin_email","smtp_host","smtp_max_frequency","smtp_pass","smtp_port","smtp_sender_name","smtp_user","uri_allow_list"]},"UpdateAuthConfigBody":{"type":"object","properties":{"site_url":{"type":"string","pattern":"/^[^,]+$/"},"disable_signup":{"type":"boolean"},"jwt_exp":{"type":"number","minimum":0,"maximum":604800},"smtp_admin_email":{"type":"string"},"smtp_host":{"type":"string"},"smtp_port":{"type":"string"},"smtp_user":{"type":"string"},"smtp_pass":{"type":"string"},"smtp_max_frequency":{"type":"number","minimum":0,"maximum":32767},"smtp_sender_name":{"type":"string"},"mailer_allow_unverified_email_sign_ins":{"type":"boolean"},"mailer_autoconfirm":{"type":"boolean"},"mailer_subjects_invite":{"type":"string"},"mailer_subjects_confirmation":{"type":"string"},"mailer_subjects_recovery":{"type":"string"},"mailer_subjects_email_change":{"type":"string"},"mailer_subjects_magic_link":{"type":"string"},"mailer_subjects_reauthentication":{"type":"string"},"mailer_templates_invite_content":{"type":"string"},"mailer_templates_confirmation_content":{"type":"string"},"mailer_templates_recovery_content":{"type":"string"},"mailer_templates_email_change_content":{"type":"string"},"mailer_templates_magic_link_content":{"type":"string"},"mailer_templates_reauthentication_content":{"type":"string"},"mfa_max_enrolled_factors":{"type":"number","minimum":0,"maximum":2147483647},"uri_allow_list":{"type":"string"},"external_anonymous_users_enabled":{"type":"boolean"},"external_email_enabled":{"type":"boolean"},"external_phone_enabled":{"type":"boolean"},"saml_enabled":{"type":"boolean"},"saml_external_url":{"type":"string","pattern":"/^[^,]+$/"},"security_captcha_enabled":{"type":"boolean"},"security_captcha_provider":{"type":"string"},"security_captcha_secret":{"type":"string"},"sessions_timebox":{"type":"number","minimum":0},"sessions_inactivity_timeout":{"type":"number","minimum":0},"sessions_single_per_user":{"type":"boolean"},"sessions_tags":{"type":"string","pattern":"/^\\s*([a-z0-9_-]+(\\s*,+\\s*)?)*\\s*$/i"},"rate_limit_anonymous_users":{"type":"number","minimum":1,"maximum":2147483647},"rate_limit_email_sent":{"type":"number","minimum":1,"maximum":2147483647},"rate_limit_sms_sent":{"type":"number","minimum":1,"maximum":2147483647},"rate_limit_verify":{"type":"number","minimum":1,"maximum":2147483647},"rate_limit_token_refresh":{"type":"number","minimum":1,"maximum":2147483647},"rate_limit_otp":{"type":"number","minimum":1,"maximum":2147483647},"mailer_secure_email_change_enabled":{"type":"boolean"},"refresh_token_rotation_enabled":{"type":"boolean"},"password_hibp_enabled":{"type":"boolean"},"password_min_length":{"type":"number","minimum":6,"maximum":32767},"password_required_characters":{"type":"string","enum":["abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ:0123456789","abcdefghijklmnopqrstuvwxyz:ABCDEFGHIJKLMNOPQRSTUVWXYZ:0123456789","abcdefghijklmnopqrstuvwxyz:ABCDEFGHIJKLMNOPQRSTUVWXYZ:0123456789:!@#$%^&*()_+-=[]{};'\\\\:\"|<>?,./`~",""]},"security_manual_linking_enabled":{"type":"boolean"},"security_update_password_require_reauthentication":{"type":"boolean"},"security_refresh_token_reuse_interval":{"type":"number","minimum":0,"maximum":2147483647},"mailer_otp_exp":{"type":"number","minimum":0,"maximum":2147483647},"mailer_otp_length":{"type":"number","minimum":6,"maximum":10},"sms_autoconfirm":{"type":"boolean"},"sms_max_frequency":{"type":"number","minimum":0,"maximum":32767},"sms_otp_exp":{"type":"number","minimum":0,"maximum":2147483647},"sms_otp_length":{"type":"number","minimum":0,"maximum":32767},"sms_provider":{"type":"string"},"sms_messagebird_access_key":{"type":"string"},"sms_messagebird_originator":{"type":"string"},"sms_test_otp":{"type":"string","pattern":"/^([0-9]{1,15}=[0-9]+,?)*$/"},"sms_test_otp_valid_until":{"type":"string"},"sms_textlocal_api_key":{"type":"string"},"sms_textlocal_sender":{"type":"string"},"sms_twilio_account_sid":{"type":"string"},"sms_twilio_auth_token":{"type":"string"},"sms_twilio_content_sid":{"type":"string"},"sms_twilio_message_service_sid":{"type":"string"},"sms_twilio_verify_account_sid":{"type":"string"},"sms_twilio_verify_auth_token":{"type":"string"},"sms_twilio_verify_message_service_sid":{"type":"string"},"sms_vonage_api_key":{"type":"string"},"sms_vonage_api_secret":{"type":"string"},"sms_vonage_from":{"type":"string"},"sms_template":{"type":"string"},"hook_mfa_verification_attempt_enabled":{"type":"boolean"},"hook_mfa_verification_attempt_uri":{"type":"string"},"hook_mfa_verification_attempt_secrets":{"type":"string"},"hook_password_verification_attempt_enabled":{"type":"boolean"},"hook_password_verification_attempt_uri":{"type":"string"},"hook_password_verification_attempt_secrets":{"type":"string"},"hook_custom_access_token_enabled":{"type":"boolean"},"hook_custom_access_token_uri":{"type":"string"},"hook_custom_access_token_secrets":{"type":"string"},"hook_send_sms_enabled":{"type":"boolean"},"hook_send_sms_uri":{"type":"string"},"hook_send_sms_secrets":{"type":"string"},"hook_send_email_enabled":{"type":"boolean"},"hook_send_email_uri":{"type":"string"},"hook_send_email_secrets":{"type":"string"},"external_apple_enabled":{"type":"boolean"},"external_apple_client_id":{"type":"string"},"external_apple_secret":{"type":"string"},"external_apple_additional_client_ids":{"type":"string"},"external_azure_enabled":{"type":"boolean"},"external_azure_client_id":{"type":"string"},"external_azure_secret":{"type":"string"},"external_azure_url":{"type":"string"},"external_bitbucket_enabled":{"type":"boolean"},"external_bitbucket_client_id":{"type":"string"},"external_bitbucket_secret":{"type":"string"},"external_discord_enabled":{"type":"boolean"},"external_discord_client_id":{"type":"string"},"external_discord_secret":{"type":"string"},"external_facebook_enabled":{"type":"boolean"},"external_facebook_client_id":{"type":"string"},"external_facebook_secret":{"type":"string"},"external_figma_enabled":{"type":"boolean"},"external_figma_client_id":{"type":"string"},"external_figma_secret":{"type":"string"},"external_github_enabled":{"type":"boolean"},"external_github_client_id":{"type":"string"},"external_github_secret":{"type":"string"},"external_gitlab_enabled":{"type":"boolean"},"external_gitlab_client_id":{"type":"string"},"external_gitlab_secret":{"type":"string"},"external_gitlab_url":{"type":"string"},"external_google_enabled":{"type":"boolean"},"external_google_client_id":{"type":"string"},"external_google_secret":{"type":"string"},"external_google_additional_client_ids":{"type":"string"},"external_google_skip_nonce_check":{"type":"boolean"},"external_kakao_enabled":{"type":"boolean"},"external_kakao_client_id":{"type":"string"},"external_kakao_secret":{"type":"string"},"external_keycloak_enabled":{"type":"boolean"},"external_keycloak_client_id":{"type":"string"},"external_keycloak_secret":{"type":"string"},"external_keycloak_url":{"type":"string"},"external_linkedin_oidc_enabled":{"type":"boolean"},"external_linkedin_oidc_client_id":{"type":"string"},"external_linkedin_oidc_secret":{"type":"string"},"external_slack_oidc_enabled":{"type":"boolean"},"external_slack_oidc_client_id":{"type":"string"},"external_slack_oidc_secret":{"type":"string"},"external_notion_enabled":{"type":"boolean"},"external_notion_client_id":{"type":"string"},"external_notion_secret":{"type":"string"},"external_slack_enabled":{"type":"boolean"},"external_slack_client_id":{"type":"string"},"external_slack_secret":{"type":"string"},"external_spotify_enabled":{"type":"boolean"},"external_spotify_client_id":{"type":"string"},"external_spotify_secret":{"type":"string"},"external_twitch_enabled":{"type":"boolean"},"external_twitch_client_id":{"type":"string"},"external_twitch_secret":{"type":"string"},"external_twitter_enabled":{"type":"boolean"},"external_twitter_client_id":{"type":"string"},"external_twitter_secret":{"type":"string"},"external_workos_enabled":{"type":"boolean"},"external_workos_client_id":{"type":"string"},"external_workos_secret":{"type":"string"},"external_workos_url":{"type":"string"},"external_zoom_enabled":{"type":"boolean"},"external_zoom_client_id":{"type":"string"},"external_zoom_secret":{"type":"string"},"db_max_pool_size":{"type":"number"},"api_max_request_duration":{"type":"number"}}},"CreateThirdPartyAuthBody":{"type":"object","properties":{"oidc_issuer_url":{"type":"string"},"jwks_url":{"type":"string"},"custom_jwks":{"type":"object"}}},"ThirdPartyAuth":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string"},"oidc_issuer_url":{"type":"string","nullable":true},"jwks_url":{"type":"string","nullable":true},"custom_jwks":{"type":"object","nullable":true},"resolved_jwks":{"type":"object","nullable":true},"inserted_at":{"type":"string"},"updated_at":{"type":"string"},"resolved_at":{"type":"string","nullable":true}},"required":["id","type","inserted_at","updated_at"]},"V1RunQueryBody":{"type":"object","properties":{"query":{"type":"string"}},"required":["query"]},"V1CreateFunctionBody":{"type":"object","properties":{"slug":{"type":"string","pattern":"/^[A-Za-z0-9_-]+$/"},"name":{"type":"string"},"body":{"type":"string"},"verify_jwt":{"type":"boolean"}},"required":["slug","name","body"]},"FunctionResponse":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"status":{"enum":["ACTIVE","REMOVED","THROTTLED"],"type":"string"},"version":{"type":"number"},"created_at":{"type":"number"},"updated_at":{"type":"number"},"verify_jwt":{"type":"boolean"},"import_map":{"type":"boolean"},"entrypoint_path":{"type":"string"},"import_map_path":{"type":"string"}},"required":["id","slug","name","status","version","created_at","updated_at"]},"FunctionSlugResponse":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"status":{"enum":["ACTIVE","REMOVED","THROTTLED"],"type":"string"},"version":{"type":"number"},"created_at":{"type":"number"},"updated_at":{"type":"number"},"verify_jwt":{"type":"boolean"},"import_map":{"type":"boolean"},"entrypoint_path":{"type":"string"},"import_map_path":{"type":"string"}},"required":["id","slug","name","status","version","created_at","updated_at"]},"V1UpdateFunctionBody":{"type":"object","properties":{"name":{"type":"string"},"body":{"type":"string"},"verify_jwt":{"type":"boolean"}}},"V1StorageBucketResponse":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"owner":{"type":"string"},"created_at":{"type":"string"},"updated_at":{"type":"string"},"public":{"type":"boolean"}},"required":["id","name","owner","created_at","updated_at","public"]},"AttributeValue":{"type":"object","properties":{"default":{"oneOf":[{"type":"object"},{"type":"number"},{"type":"string"},{"type":"boolean"}]},"name":{"type":"string"},"names":{"type":"array","items":{"type":"string"}},"array":{"type":"boolean"}}},"AttributeMapping":{"type":"object","properties":{"keys":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/AttributeValue"}}},"required":["keys"]},"CreateProviderBody":{"type":"object","properties":{"type":{"type":"string","enum":["saml"],"description":"What type of provider will be created"},"metadata_xml":{"type":"string"},"metadata_url":{"type":"string"},"domains":{"type":"array","items":{"type":"string"}},"attribute_mapping":{"$ref":"#/components/schemas/AttributeMapping"}},"required":["type"]},"SamlDescriptor":{"type":"object","properties":{"id":{"type":"string"},"entity_id":{"type":"string"},"metadata_url":{"type":"string"},"metadata_xml":{"type":"string"},"attribute_mapping":{"$ref":"#/components/schemas/AttributeMapping"}},"required":["id","entity_id"]},"Domain":{"type":"object","properties":{"id":{"type":"string"},"domain":{"type":"string"},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id"]},"CreateProviderResponse":{"type":"object","properties":{"id":{"type":"string"},"saml":{"$ref":"#/components/schemas/SamlDescriptor"},"domains":{"type":"array","items":{"$ref":"#/components/schemas/Domain"}},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id"]},"Provider":{"type":"object","properties":{"id":{"type":"string"},"saml":{"$ref":"#/components/schemas/SamlDescriptor"},"domains":{"type":"array","items":{"$ref":"#/components/schemas/Domain"}},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id"]},"ListProvidersResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Provider"}}},"required":["items"]},"GetProviderResponse":{"type":"object","properties":{"id":{"type":"string"},"saml":{"$ref":"#/components/schemas/SamlDescriptor"},"domains":{"type":"array","items":{"$ref":"#/components/schemas/Domain"}},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id"]},"UpdateProviderBody":{"type":"object","properties":{"metadata_xml":{"type":"string"},"metadata_url":{"type":"string"},"domains":{"type":"array","items":{"type":"string"}},"attribute_mapping":{"$ref":"#/components/schemas/AttributeMapping"}}},"UpdateProviderResponse":{"type":"object","properties":{"id":{"type":"string"},"saml":{"$ref":"#/components/schemas/SamlDescriptor"},"domains":{"type":"array","items":{"$ref":"#/components/schemas/Domain"}},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id"]},"DeleteProviderResponse":{"type":"object","properties":{"id":{"type":"string"},"saml":{"$ref":"#/components/schemas/SamlDescriptor"},"domains":{"type":"array","items":{"$ref":"#/components/schemas/Domain"}},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id"]},"V1Backup":{"type":"object","properties":{"status":{"type":"string","enum":["COMPLETED","FAILED","PENDING","REMOVED","ARCHIVED"]},"is_physical_backup":{"type":"boolean"},"inserted_at":{"type":"string"}},"required":["status","is_physical_backup","inserted_at"]},"V1PhysicalBackup":{"type":"object","properties":{"earliest_physical_backup_date_unix":{"type":"number"},"latest_physical_backup_date_unix":{"type":"number"}}},"V1BackupsResponse":{"type":"object","properties":{"region":{"type":"string"},"walg_enabled":{"type":"boolean"},"pitr_enabled":{"type":"boolean"},"backups":{"type":"array","items":{"$ref":"#/components/schemas/V1Backup"}},"physical_backup_data":{"$ref":"#/components/schemas/V1PhysicalBackup"}},"required":["region","walg_enabled","pitr_enabled","backups","physical_backup_data"]},"V1RestorePitrBody":{"type":"object","properties":{"recovery_time_target_unix":{"type":"number"}},"required":["recovery_time_target_unix"]},"V1OrganizationMemberResponse":{"type":"object","properties":{"user_id":{"type":"string"},"user_name":{"type":"string"},"email":{"type":"string"},"role_name":{"type":"string"},"mfa_enabled":{"type":"boolean"}},"required":["user_id","user_name","role_name","mfa_enabled"]},"BillingPlanId":{"type":"string","enum":["free","pro","team","enterprise"]},"V1OrganizationSlugResponse":{"type":"object","properties":{"plan":{"$ref":"#/components/schemas/BillingPlanId"},"opt_in_tags":{"type":"array","items":{"type":"string","enum":["AI_SQL_GENERATOR_OPT_IN"]}},"id":{"type":"string"},"name":{"type":"string"}},"required":["opt_in_tags","id","name"]}}}}
\ No newline at end of file
diff --git a/apps/docs/spec/cli_v1_commands.yaml b/apps/docs/spec/cli_v1_commands.yaml
index 81bc3d8afe7..27da229776d 100644
--- a/apps/docs/spec/cli_v1_commands.yaml
+++ b/apps/docs/spec/cli_v1_commands.yaml
@@ -1,7 +1,7 @@
clispec: '001'
info:
id: cli
- version: 1.178.2
+ version: 1.187.3
title: Supabase CLI
language: sh
source: https://github.com/supabase/cli
@@ -963,6 +963,31 @@ commands:
usage: supabase services
subcommands: []
flags: []
+ - id: supabase-seed
+ title: supabase seed
+ summary: Seed a Supabase project from supabase/config.toml
+ tags:
+ - local-dev
+ links: []
+ subcommands:
+ - supabase-seed-buckets
+ flags: []
+ - id: supabase-seed-buckets
+ title: supabase seed buckets
+ summary: Seed buckets declared in [storage.buckets]
+ tags: []
+ links: []
+ usage: supabase seed buckets
+ subcommands: []
+ flags:
+ - id: linked
+ name: --linked
+ description: Seeds the linked project.
+ default_value: 'false'
+ - id: local
+ name: --local
+ description: Seeds the local database.
+ default_value: 'true'
- id: supabase-secrets
title: supabase secrets
summary: Manage Supabase secrets
@@ -2466,21 +2491,27 @@ commands:
summary: Generate types from Postgres schema
tags: []
links: []
- subcommands:
- - supabase-gen-types-typescript
- flags: []
- - id: supabase-gen-types-typescript
- title: supabase gen types typescript
- summary: Generate types for TypeScript
- tags: []
- links: []
- usage: supabase gen types typescript [flags]
+ usage: supabase gen types [flags]
subcommands: []
flags:
- id: db-url
name: --db-url
description: Generate types from a database url.
default_value: ''
+ - id: lang
+ name: --lang <[ typescript | go | swift ]>
+ description: Output language of the generated types.
+ default_value: typescript
+ accepted_values:
+ - id: typescript
+ name: typescript
+ type: '[ typescript | go | swift ]'
+ - id: go
+ name: go
+ type: '[ typescript | go | swift ]'
+ - id: swift
+ name: swift
+ type: '[ typescript | go | swift ]'
- id: linked
name: --linked
description: Generate types from the linked project.
@@ -2502,6 +2533,17 @@ commands:
name: -s, --schema
description: Comma separated list of schema to include.
default_value: '[]'
+ - id: swift-access-control
+ name: --swift-access-control <[ internal | public ]>
+ description: Access control for Swift generated types.
+ default_value: internal
+ accepted_values:
+ - id: internal
+ name: internal
+ type: '[ internal | public ]'
+ - id: public
+ name: public
+ type: '[ internal | public ]'
- id: supabase-gen-keys
title: supabase gen keys
summary: Generate keys for preview branch
@@ -2827,11 +2869,13 @@ commands:
- id: supabase-domains-activate
title: supabase domains activate
summary: Activate the custom hostname for a project
- description: |-
+ description: |2
+
Activates the custom hostname configuration for a project.
This reconfigures your Supabase project to respond to requests on your custom hostname.
- After the custom hostname is activated, your project's auth services will no longer function on the Supabase-provisioned subdomain.
+
+ After the custom hostname is activated, your project's third-party auth providers will no longer function on the Supabase-provisioned subdomain. Please refer to [Prepare to activate your domain](/docs/guides/platform/custom-domains#prepare-to-activate-your-domain) section in our documentation to learn more about the steps you need to follow.
tags: []
links: []
usage: supabase domains activate
diff --git a/apps/docs/spec/cli_v1_config.yaml b/apps/docs/spec/cli_v1_config.yaml
index 2b312d449a8..dc00f66b64d 100644
--- a/apps/docs/spec/cli_v1_config.yaml
+++ b/apps/docs/spec/cli_v1_config.yaml
@@ -443,6 +443,51 @@ parameters:
- name: 'Auth Server configuration'
link: 'https://supabase.com/docs/reference/auth'
+ - id: 'auth.email.smtp.host'
+ title: 'auth.email.smtp.host'
+ tags: ['auth']
+ required: false
+ default: 'inbucket'
+ description: |
+ Hostname or IP address of the SMTP server.
+
+ - id: 'auth.email.smtp.port'
+ title: 'auth.email.smtp.port'
+ tags: ['auth']
+ required: false
+ default: 2500
+ description: |
+ Port number of the SMTP server.
+
+ - id: 'auth.email.smtp.user'
+ title: 'auth.email.smtp.user'
+ tags: ['auth']
+ required: false
+ description: |
+ Username for authenticating with the SMTP server.
+
+ - id: 'auth.email.smtp.pass'
+ title: 'auth.email.smtp.pass'
+ tags: ['auth']
+ required: false
+ description: |
+ Password for authenticating with the SMTP server.
+
+ - id: 'auth.email.smtp.admin_email'
+ title: 'auth.email.smtp.admin_email'
+ tags: ['auth']
+ required: false
+ default: 'admin@email.com'
+ description: |
+ Email used as the sender for emails sent from the application.
+
+ - id: 'auth.email.smtp.sender_name'
+ title: 'auth.email.smtp.sender_name'
+ tags: ['auth']
+ required: false
+ description: |
+ Display name used as the sender for emails sent from the application.
+
- id: 'auth.email.template.type.subject'
title: 'auth.email.template..subject'
tags: ['auth']
diff --git a/apps/docs/spec/client-libs-common.yml b/apps/docs/spec/client-libs-common.yml
index 6ab88bc27af..66bbdbe78da 100644
--- a/apps/docs/spec/client-libs-common.yml
+++ b/apps/docs/spec/client-libs-common.yml
@@ -40,10 +40,6 @@ commands:
title: supabase gen types
product: 'general'
- - id: supabase-gen-types-typescript
- title: supabase gen types typescript
- product: 'general'
-
- id: supabase-secrets
title: supabase secrets
product: 'secrets'
diff --git a/apps/docs/spec/common-api-sections.json b/apps/docs/spec/common-api-sections.json
index 633463e752f..91c5e9172e8 100644
--- a/apps/docs/spec/common-api-sections.json
+++ b/apps/docs/spec/common-api-sections.json
@@ -7,7 +7,7 @@
},
{
"type": "category",
- "title": "auth",
+ "title": "Auth",
"items": [
{
"id": "v1-create-a-sso-provider",
@@ -55,7 +55,7 @@
},
{
"type": "category",
- "title": "database",
+ "title": "Database",
"items": [
{
"id": "v1-disable-readonly-mode-temporarily",
@@ -169,7 +169,7 @@
},
{
"type": "category",
- "title": "domains",
+ "title": "Domains",
"items": [
{
"id": "v1-activate-custom-hostname",
@@ -223,7 +223,7 @@
},
{
"type": "category",
- "title": "edge functions",
+ "title": "Edge Functions",
"items": [
{
"id": "v1-delete-a-function",
@@ -259,7 +259,7 @@
},
{
"type": "category",
- "title": "environments",
+ "title": "Environments",
"items": [
{
"id": "v1-create-a-branch",
@@ -307,7 +307,7 @@
},
{
"type": "category",
- "title": "oauth",
+ "title": "OAuth",
"items": [
{
"id": "v1-authorize-user",
@@ -325,7 +325,7 @@
},
{
"type": "category",
- "title": "organizations",
+ "title": "Organizations",
"items": [
{
"id": "v1-create-an-organization",
@@ -355,7 +355,7 @@
},
{
"type": "category",
- "title": "projects",
+ "title": "Projects",
"items": [
{
"id": "v1-create-a-project",
@@ -363,6 +363,12 @@
"slug": "v1-create-a-project",
"type": "operation"
},
+ {
+ "id": "v1-delete-a-project",
+ "title": "Delete a project",
+ "slug": "v1-delete-a-project",
+ "type": "operation"
+ },
{
"id": "v1-delete-network-bans",
"title": "Delete network bans",
@@ -421,7 +427,7 @@
},
{
"type": "category",
- "title": "rest",
+ "title": "Rest",
"items": [
{
"id": "v1-get-postgrest-service-config",
@@ -439,7 +445,7 @@
},
{
"type": "category",
- "title": "secrets",
+ "title": "Secrets",
"items": [
{
"id": "v1-bulk-create-secrets",
@@ -481,7 +487,7 @@
},
{
"type": "category",
- "title": "storage",
+ "title": "Storage",
"items": [
{
"id": "v1-list-all-buckets",
diff --git a/apps/docs/spec/common-cli-sections.json b/apps/docs/spec/common-cli-sections.json
index 81e5cd88ca4..c11bd06c9cb 100644
--- a/apps/docs/spec/common-cli-sections.json
+++ b/apps/docs/spec/common-cli-sections.json
@@ -100,12 +100,6 @@
"title": "Generate types (Postgres schema)",
"slug": "supabase-gen-types",
"type": "cli-command"
- },
- {
- "id": "supabase-gen-types-typescript",
- "title": "Generate types (TypeScript)",
- "slug": "supabase-gen-types-typescript",
- "type": "cli-command"
}
]
},
@@ -205,6 +199,24 @@
}
]
},
+ {
+ "type": "category",
+ "title": "Seed",
+ "items": [
+ {
+ "id": "supabase-seed",
+ "title": "Seed a Supabase project",
+ "slug": "supabase-seed",
+ "type": "cli-command"
+ },
+ {
+ "id": "supabase-seed-buckets",
+ "title": "Seed storage buckets from config file",
+ "slug": "supabase-seed-buckets",
+ "type": "cli-command"
+ }
+ ]
+ },
{
"type": "category",
"title": "Inspect",
diff --git a/apps/docs/spec/common-cli.yml b/apps/docs/spec/common-cli.yml
index 1f635d28e92..7419bc6a41e 100644
--- a/apps/docs/spec/common-cli.yml
+++ b/apps/docs/spec/common-cli.yml
@@ -40,10 +40,6 @@ commands:
title: supabase gen types
product: 'general'
- - id: supabase-gen-types-typescript
- title: supabase gen types typescript
- product: 'general'
-
- id: supabase-secrets
title: supabase secrets
product: 'secrets'
diff --git a/apps/docs/spec/supabase_dart_v2.yml b/apps/docs/spec/supabase_dart_v2.yml
index 3872f76ec82..64b53f2499b 100644
--- a/apps/docs/spec/supabase_dart_v2.yml
+++ b/apps/docs/spec/supabase_dart_v2.yml
@@ -600,12 +600,9 @@ functions:
import 'package:google_sign_in/google_sign_in.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
- /// Web Client ID that you registered with Google Cloud.
- /// This will be used to perform Google sign in on Android.
- const webClientId = 'my-web.apps.googleusercontent.com';
+ const webClientId = '';
- /// iOS Client ID that you registered with Google Cloud.
- const iosClientId = 'my-ios.apps.googleusercontent.com';
+ const iosClientId = ' {
- const subscription = supabase.auth.onAuthStateChange(
+ const {data: { subscription }} = supabase.auth.onAuthStateChange(
(event, session) => {
if (event === 'SIGNED_OUT') {
setSession(null)
@@ -1823,14 +1823,12 @@ functions:
title: 'setSession()'
$ref: '@supabase/auth-js.GoTrueClient.setSession'
notes: |
- - `setSession()` takes in a refresh token and uses it to get a new session.
- - The refresh token can only be used once to obtain a new session.
- - [Refresh token rotation](/docs/reference/auth/config#refresh_token_rotation_enabled) is enabled by default on all projects to guard against replay attacks.
- - You can configure the [`REFRESH_TOKEN_REUSE_INTERVAL`](/docs/reference/auth/config#refresh_token_reuse_interval) which provides a short window in which the same refresh token can be used multiple times in the event of concurrency or offline issues.
+ - This method sets the session using an `access_token` and `refresh_token`.
+ - If successful, a `SIGNED_IN` event is emitted.
examples:
- - id: refresh-the-session
- name: Refresh the session
- description: Sets the session data from refresh_token and returns current session or an error if the refresh_token is invalid.
+ - id: set-the-session
+ name: Set the session
+ description: Sets the session data from an access_token and refresh_token, then returns an auth response or error.
isSpotlight: true
code: |
```js
@@ -7240,7 +7238,8 @@ functions:
```json
{
"data": {
- "path": "avatars/public/avatar1.png"
+ "path": "public/avatar1.png",
+ "fullPath": "avatars/public/avatar1.png"
},
"error": null
}
@@ -7286,7 +7285,8 @@ functions:
```json
{
"data": {
- "path": "avatars/public/avatar1.png"
+ "path": "public/avatar1.png",
+ "fullPath": "avatars/public/avatar1.png"
},
"error": null
}
diff --git a/apps/docs/spec/supabase_kt_v2.yml b/apps/docs/spec/supabase_kt_v2.yml
index 2637337fc05..b3f654165b0 100644
--- a/apps/docs/spec/supabase_kt_v2.yml
+++ b/apps/docs/spec/supabase_kt_v2.yml
@@ -4393,7 +4393,10 @@ functions:
isSpotlight: true
code: |
```kotlin
- supabase.functions.invoke("function_name")
+ val response = supabase.functions.invoke("function_name")
+
+ // Decode the response body to a serializable class
+ val data = response.body()
```
- id: basic-invocation-with-body
name: Basic invocation with body
@@ -4410,6 +4413,8 @@ functions:
}
)
```
+ description: |
+ The return type of the invoking methods is an `HttpResponse`. You can access the response body via `response.body()`, where `T` can be any serializable type.
- id: reuse-function
name: Reuse function by saving it to a variable
isSpotlight: true
@@ -4519,15 +4524,15 @@ functions:
data class Message(val content: String, val sender: String)
val channel = supabase.channel("channelId") {
- //optional config
+ // optional config
}
val broadcastFlow = channel.broadcastFlow(event = "message")
- //Collect the flow
- broadcastFlow.collect { //it: Message
+ // Collect the flow
+ broadcastFlow.onEach { // it: Message
println(it)
- }
+ }.launchIn(coroutineScope) // launch a new coroutine to collect the flow
channel.subscribe(blockUntilSubscribed = true)
@@ -4548,11 +4553,11 @@ functions:
val presenceFlow = channel.presenceDataFlow()
//Collect the flow
- presenceFlow.collect {
+ presenceFlow.onEach {
for (presence in it) {
println(presence.username)
}
- }
+ }.launchIn(coroutineScope) // launch a new coroutine to collect the flow
channel.subscribe(blockUntilSubscribed = true)
//send your own state
@@ -4571,14 +4576,14 @@ functions:
val changeFlow = channel.postgresChangeFlow(schema = "public")
//Collect the flow
- changeFlow.collect {
+ changeFlow.onEach {
when(it) {
is PostgresAction.Delete -> println("Deleted: ${it.oldRecord}")
is PostgresAction.Insert -> println("Inserted: ${it.record}")
is PostgresAction.Select -> println("Selected: ${it.record}")
is PostgresAction.Update -> println("Updated: ${it.oldRecord} with ${it.record}")
}
- }
+ }.launchIn(coroutineScope) // launch a new coroutine to collect the flow
channel.subscribe()
```
@@ -4600,14 +4605,14 @@ functions:
}
//Collect the flow
- changeFlow.collect {
+ changeFlow.onEach {
when(it) {
is PostgresAction.Delete -> println("Deleted: ${it.oldRecord}")
is PostgresAction.Insert -> println("Inserted: ${it.record}")
is PostgresAction.Select -> println("Selected: ${it.record}")
is PostgresAction.Update -> println("Updated: ${it.oldRecord} with ${it.record}")
}
- }
+ }.launchIn(coroutineScope) // launch a new coroutine to collect the flow
channel.subscribe()
```
@@ -4627,9 +4632,9 @@ functions:
}
//Collect the flow
- changeFlow.collect {
+ changeFlow.onEach {
println(it.record)
- }
+ }.launchIn(coroutineScope) // launch a new coroutine to collect the flow
channel.subscribe()
```
@@ -4653,10 +4658,10 @@ functions:
}
//Collect the flow
- changeFlow.collect {
+ changeFlow.onEach {
println(it.record)
println(it.oldRecord)
- }
+ }.launchIn(coroutineScope) // launch a new coroutine to collect the flow
channel.subscribe()
```
@@ -4680,9 +4685,9 @@ functions:
}
//Collect the flow
- changeFlow.collect {
+ changeFlow.onEach {
println(it.oldRecord)
- }
+ }.launchIn(coroutineScope) // launch a new coroutine to collect the flow
channel.subscribe()
```
@@ -4707,9 +4712,9 @@ functions:
}
//Collect the flow
- changeFlow.collect {
+ changeFlow.onEach {
println(it.oldRecord)
- }
+ }.launchIn(coroutineScope) // launch a new coroutine to collect the flow
channel.subscribe()
```
diff --git a/apps/docs/spec/supabase_py_v2.yml b/apps/docs/spec/supabase_py_v2.yml
index 09af232cddd..9fa3ea18a5f 100644
--- a/apps/docs/spec/supabase_py_v2.yml
+++ b/apps/docs/spec/supabase_py_v2.yml
@@ -5,7 +5,7 @@ info:
title: Supabase Python Client
description: |
- Supabase Python(Community).
+ Supabase Python
definition: spec/enrichments/tsdoc_v2/combined.json
specUrl: https://github.com/supabase/supabase/edit/master/apps/docs/spec/supabase_py_v2.yml
@@ -23,6 +23,57 @@ functions:
The Supabase client is your entrypoint to the rest of the Supabase functionality
and is the easiest way to interact with everything we offer within the Supabase ecosystem.
+ params:
+ - name: supabase_url
+ isOptional: false
+ type: string
+ description: The unique Supabase URL which is supplied when you create a new project in your project dashboard.
+ - name: supabase_key
+ isOptional: false
+ type: string
+ description: The unique Supabase Key which is supplied when you create a new project in your project dashboard.
+ - name: options
+ isOptional: true
+ type: ClientOptions
+ description: Options to change the Auth behaviors.
+ subContent:
+ - name: schema
+ isOptional: true
+ type: string
+ description: The Postgres schema which your tables belong to. Must be on the list of exposed schemas in Supabase. Defaults to 'public'.
+ - name: headers
+ isOptional: true
+ type: dictionary
+ description: Optional headers for initializing the client.
+ - name: auto_refresh_token
+ isOptional: true
+ type: bool
+ description: Whether to automatically refresh the token when it expires. Defaults to `true`.
+ - name: persist_session
+ isOptional: true
+ type: bool
+ description: Whether to persist a logged in session to storage.
+ - name: storage
+ isOptional: true
+ type: SyncSupportedStorage
+ description: A storage provider. Used to store the logged in session.
+ - name: realtime
+ isOptional: true
+ type: string
+ description: Options passed to the realtime-py instance.
+ - name: postgrest_client_timeout
+ isOptional: true
+ type: int, float, Timeout
+ description: Timeout passed to the SyncPostgrestClient instance.
+ - name: storage_client_timeout
+ isOptional: true
+ type: int, float, Timeout
+ description: Timeout passed to the SyncStorageClient instance.
+ - name: flow_type
+ isOptional: true
+ type: AuthFlowType
+ description: flow type to use for authentication.
+
examples:
- id: create-client
name: create_client()
@@ -55,6 +106,46 @@ functions:
- id: sign-up
title: 'sign_up()'
+ params:
+ - name: credentials
+ isOptional: false
+ type: SignUpWithPasswordCredentials
+ subContent:
+ - name: email
+ isOptional: true
+ type: string
+ description: One of `email` or `phone` must be provided.
+ - name: phone
+ isOptional: true
+ type: string
+ description: One of `email` or `phone` must be provided.
+ - name: password
+ type: string
+ - name: options
+ isOptional: true
+ type: object
+ subContent:
+ - name: email_redirect_to
+ isOptional: true
+ type: string
+ description: >
+ Only for email signups.
+ The redirect URL embedded in the email link.
+ Must be a configured redirect URL for your Supabase instance.
+ - name: data
+ isOptional: true
+ type: object
+ description: >
+ A custom data object to store additional user metadata.
+ - name: captcha_token
+ isOptional: true
+ type: string
+ - name: channel
+ isOptional: true
+ type: sms | whatsapp
+ description: >
+ The channel to use for sending messages.
+ Only for phone signups.
notes: |
- By default, the user needs to verify their email address before logging in. To turn this off, disable **Confirm email** in [your project](https://supabase.com/dashboard/project/_/auth/providers).
- **Confirm email** determines if users need to confirm their email address after signing up.
@@ -64,79 +155,149 @@ functions:
- If sign_up() is called for an existing confirmed user:
- 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.
- When either **Confirm email** or **Confirm phone** (even when phone provider is disabled) is disabled, the error message, `User already registered` is returned.
- - To fetch the currently logged-in user, refer to [`getUser()`](/docs/reference/python/auth-getuser).
+ - To fetch the currently logged-in user, refer to [`get_user()`](/docs/reference/python/auth-getuser).
examples:
- id: signup
- name: Sign up
+ name: Sign up with an email and password
code: |
- ```
- credentials = {
- "email": "users_email@email.com",
- "password": "users_password"
- }
- user = supabase.auth.sign_up(credentials)
+ ```python
+ response = supabase.auth.sign_up(
+ credentials={"email": "hello@example.com", "password": "password"}
+ )
```
response: |
- ```
- User(
- id='11111111-1111-1111-1111-111111111111',
- app_metadata={
- 'provider': 'email',
- 'providers': ['email']
- },
- user_metadata={
- 'email': 'users_email@email.com',
- 'email_verified': False,
- 'phone_verified': False,
- 'sub': '11111111-1111-1111-1111-111111111111'
+ ```json
+ {
+ "user": {
+ "id": "11111111-1111-1111-1111-111111111111",
+ "app_metadata": {
+ "provider": "email",
+ "providers": [
+ "email"
+ ]
+ },
+ "user_metadata": {},
+ "aud": "authenticated",
+ "confirmation_sent_at": null,
+ "recovery_sent_at": null,
+ "email_change_sent_at": null,
+ "new_email": null,
+ "invited_at": null,
+ "action_link": null,
+ "email": "hello@example.com",
+ "phone": "",
+ "created_at": "2024-06-17T00:19:25.760110Z",
+ "confirmed_at": null,
+ "email_confirmed_at": "2024-06-17T00:19:25.779181Z",
+ "phone_confirmed_at": null,
+ "last_sign_in_at": "2024-06-17T00:19:25.785489Z",
+ "role": "authenticated",
+ "updated_at": "2024-06-17T00:19:25.794650Z",
+ "identities": [
+ {
+ "id": "11111111-1111-1111-1111-111111111111",
+ "user_id": "11111111-1111-1111-1111-111111111111",
+ "identity_data": {
+ "email": "hello@example.com",
+ "sub": "11111111-1111-1111-1111-111111111111"
+ },
+ "provider": "email",
+ "created_at": "2024-06-17T00:19:25.774522Z",
+ "last_sign_in_at": "2024-06-17T00:19:25.774498Z",
+ "updated_at": "2024-06-17T00:19:25.774522Z"
+ }
+ ],
+ "factors": null
},
- aud='authenticated',
- confirmation_sent_at=datetime.datetime(2024, 1, 1, 1, 0, 0, 0, tzinfo=TzInfo(UTC)),
- recovery_sent_at=None,
- email_change_sent_at=None,
- new_email=None,
- invited_at=None,
- action_link=None,
- email='users_email@email.com',
- phone='',
- created_at=datetime.datetime(2024, 1, 1, 1, 0, 0, 0, tzinfo=TzInfo(UTC)),
- confirmed_at=None,
- email_confirmed_at=None,
- phone_confirmed_at=None,
- last_sign_in_at=None,
- role='authenticated',
- updated_at=datetime.datetime(2024, 1, 1, 1, 0, 0, 0, tzinfo=TzInfo(UTC)),
- identities=[
- UserIdentity(
- id='22222222-2222-2222-2222-222222222222',
- user_id='11111111-1111-1111-1111-111111111111',
- identity_data={
- 'email': 'users_email@email.com',
- 'email_verified': False,
- 'phone_verified': False,
- 'sub': '11111111-1111-1111-1111-111111111111'
+ "session": {
+ "provider_token": null,
+ "provider_refresh_token": null,
+ "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZXhwIjoxNzE4NTg3MTY1LCJpYXQiOjE3MTg1ODM1NjUsImlzcyI6Imh0dHA6Ly8xMjcuMC4wLjE6NTQzMjEvYXV0aC92MSIsInN1YiI6ImU0MTBkMTBmLTZlNTktNDBlNS1hMmRlLTY5NGE5MzVlNzJlZCIsImVtYWlsIjoiaGVsbG9AZXhhbXBsZS5jb20iLCJwaG9uZSI6IiIsImFwcF9tZXRhZGF0YSI6eyJwcm92aWRlciI6ImVtYWlsIiwicHJvdmlkZXJzIjpbImVtYWlsIl19LCJ1c2VyX21ldGFkYXRhIjp7fSwicm9sZSI6ImF1dGhlbnRpY2F0ZWQiLCJhYWwiOiJhYWwxIiwiYW1yIjpbeyJtZXRob2QiOiJwYXNzd29yZCIsInRpbWVzdGFtcCI6MTcxODU4MzU2NX1dLCJzZXNzaW9uX2lkIjoiMjRmOGFlMmMtYWM4Mi00NzdhLWIxMTMtZTkwNmRlNzFiMDIxIn0.5KrE1AL4koBJs5dvNQfThMV1HxV8nPP-GPU24aRL9xI",
+ "refresh_token": "mNUp4-LDuYq-kNG61t-2Xw",
+ "expires_in": 3600,
+ "expires_at": 1718587165,
+ "token_type": "bearer",
+ "user": {
+ "id": "11111111-1111-1111-1111-111111111111",
+ "app_metadata": {
+ "provider": "email",
+ "providers": [
+ "email"
+ ]
},
- provider='email',
- created_at=datetime.datetime(2024, 1, 1, 1, 0, 0, 0, tzinfo=TzInfo(UTC)),
- last_sign_in_at=datetime.datetime(2024, 1, 1, 1, 0, 0, 0, tzinfo=TzInfo(UTC)),
- updated_at=datetime.datetime(2024, 1, 1, 1, 0, 0, 0, tzinfo=TzInfo(UTC))
- )
- ],
- factors=None
- )
- session=None
+ "user_metadata": {},
+ "aud": "authenticated",
+ "confirmation_sent_at": null,
+ "recovery_sent_at": null,
+ "email_change_sent_at": null,
+ "new_email": null,
+ "invited_at": null,
+ "action_link": null,
+ "email": "hello@example.com",
+ "phone": "",
+ "created_at": "2024-06-17T00:19:25.760110Z",
+ "confirmed_at": null,
+ "email_confirmed_at": "2024-06-17T00:19:25.779181Z",
+ "phone_confirmed_at": null,
+ "last_sign_in_at": "2024-06-17T00:19:25.785489Z",
+ "role": "authenticated",
+ "updated_at": "2024-06-17T00:19:25.794650Z",
+ "identities": [
+ {
+ "id": "11111111-1111-1111-1111-111111111111",
+ "user_id": "11111111-1111-1111-1111-111111111111",
+ "identity_data": {
+ "email": "hello@example.com",
+ "sub": "11111111-1111-1111-1111-111111111111"
+ },
+ "provider": "email",
+ "created_at": "2024-06-17T00:19:25.774522Z",
+ "last_sign_in_at": "2024-06-17T00:19:25.774498Z",
+ "updated_at": "2024-06-17T00:19:25.774522Z"
+ }
+ ],
+ "factors": null
+ }
+ }
+ }
+ ```
+ - id: sign-up-phone
+ name: Sign up with a phone number and password (SMS)
+ isSpotlight: true
+ code: |
+ ```python
+ response = supabase.auth.sign_up(
+ credentials={
+ "phone": "123456789",
+ "password": "password",
+ }
+ )
+ ```
+ - id: sign-up-phone-whatsapp
+ name: Sign up with a phone number and password (whatsapp)
+ isSpotlight: true
+ 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.
+ code: |
+ ```python
+ response = supabase.auth.sign_up(
+ credentials={
+ "phone": "123456789",
+ "password": "password",
+ "options": {"channel": "whatsapp"},
+ }
+ )
```
- id: sign-up-with-additional-user-metadata
name: Sign up with additional user metadata
code: |
- ```
- res = supabase.auth.sign_up(
- email= 'example@email.com',
- password= 'example-password',
- data= {
- first_name= 'John',
- age= 27,
- }
+ ```python
+ response = supabase.auth.sign_up(
+ credentials={
+ "email": "hello@example.com",
+ "password": "password",
+ "options": {"data": {"first_name": "John", "age": 27}},
+ }
)
```
- id: sign-up-with-redirect
@@ -144,11 +305,117 @@ functions:
description: |
- See [redirect URLs and wildcards](/docs/guides/auth/redirect-urls) to add additional redirect URLs to your project.
code: |
+ ```python
+ response = supabase.auth.sign_up(
+ credentials={
+ "email": "hello1@example.com",
+ "password": "password",
+ "options": {
+ "email_redirect_to": "https://example.com/welcome",
+ },
+ }
+ )
```
- res = supabase.auth.sign_up(
- email= 'example@email.com',
- password= 'example-password',
- redirect_to= 'https://example.com/welcome'
+ - id: sign-in-anonymously
+ title: 'sign_in_anonymously()'
+ params:
+ - name: credentials
+ isOptional: false
+ type: SignInAnonymouslyCredentials
+ subContent:
+ - name: options
+ isOptional: true
+ type: object
+ subContent:
+ - name: data
+ isOptional: true
+ type: object
+ description: A custom data object to store the user's metadata. This maps to the `auth.users.raw_user_meta_data` column. The `data` should be a JSON object that includes user-specific info, such as their first and last name.
+ - name: captcha_token
+ isOptional: true
+ type: string
+ description: Verification token received when the user completes the captcha on the site.
+
+ notes: |
+ - Returns an anonymous user
+ - 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: sign-in-anonymously
+ name: Create an anonymous user
+ isSpotlight: true
+ code: |
+ ```python
+ response = supabase.auth.sign_in_anonymously(
+ credentials={"options": {"captcha_token": ""}}
+ )
+ ```
+ response: |
+ ```json
+ {
+ "user": {
+ "id": "11111111-1111-1111-1111-111111111111",
+ "app_metadata": {},
+ "user_metadata": {},
+ "aud": "authenticated",
+ "confirmation_sent_at": null,
+ "recovery_sent_at": null,
+ "email_change_sent_at": null,
+ "new_email": null,
+ "invited_at": null,
+ "action_link": null,
+ "email": "",
+ "phone": "",
+ "created_at": "2024-06-23T22:35:47.518626Z",
+ "confirmed_at": null,
+ "email_confirmed_at": null,
+ "phone_confirmed_at": null,
+ "last_sign_in_at": "2024-06-23T22:35:47.520855Z",
+ "role": "authenticated",
+ "updated_at": "2024-06-23T22:35:47.522241Z",
+ "identities": [],
+ "factors": null
+ },
+ "session": {
+ "provider_token": null,
+ "provider_refresh_token": null,
+ "access_token": "",
+ "refresh_token": "",
+ "expires_in": 3600,
+ "expires_at": 1719185747,
+ "token_type": "bearer",
+ "user": {
+ "id": "11111111-1111-1111-1111-111111111111",
+ "app_metadata": {},
+ "user_metadata": {},
+ "aud": "authenticated",
+ "confirmation_sent_at": null,
+ "recovery_sent_at": null,
+ "email_change_sent_at": null,
+ "new_email": null,
+ "invited_at": null,
+ "action_link": null,
+ "email": "",
+ "phone": "",
+ "created_at": "2024-06-23T22:35:47.518626Z",
+ "confirmed_at": null,
+ "email_confirmed_at": null,
+ "phone_confirmed_at": null,
+ "last_sign_in_at": "2024-06-23T22:35:47.520855Z",
+ "role": "authenticated",
+ "updated_at": "2024-06-23T22:35:47.522241Z",
+ "identities": [],
+ "factors": null
+ }
+ }
+ }
+ ```
+ - id: sign-in-anonymously-with-user-metadata
+ name: Create an anonymous user with custom user metadata
+ isSpotlight: false
+ code: |
+ ```python
+ response = supabase.auth.sign_in_anonymously(
+ credentials={"options": {"data": {}}}
)
```
- id: sign-in-with-password
@@ -300,7 +567,7 @@ functions:
isSpotlight: true
code: |
```
- res = await supabase.auth.mfa.enroll({
+ res = supabase.auth.mfa.enroll({
"factor_type": "totp",
"friendly_name": "your_friendly_name"
})
@@ -316,7 +583,7 @@ functions:
isSpotlight: true
code: |
```
- res = await supabase.auth.mfa.challenge({
+ res = supabase.auth.mfa.challenge({
"factor_id": '34e770dd-9ff9-416c-87fa-43b31d7ef225'
})
```
@@ -330,7 +597,7 @@ functions:
isSpotlight: true
code: |
```
- res = await supabase.auth.mfa.verify({
+ res = supabase.auth.mfa.verify({
"factor_id": '34e770dd-9ff9-416c-87fa-43b31d7ef225',
"challenge_id": '4034ae6f-a8ce-4fb5-8ee5-69a5863a7c15',
"code": '123456'
@@ -347,7 +614,7 @@ functions:
isSpotlight: true
code: |
```
- res = await supabase.auth.mfa.challenge_and_verify({
+ res = supabase.auth.mfa.challenge_and_verify({
"factor_id": '34e770dd-9ff9-416c-87fa-43b31d7ef225',
"code": '123456'
})
@@ -360,7 +627,7 @@ functions:
isSpotlight: true
code: |
```
- res = await supabase.auth.mfa.unenroll({
+ res = supabase.auth.mfa.unenroll({
"factor_id": '34e770dd-9ff9-416c-87fa-43b31d7ef225',
})
```
@@ -376,7 +643,7 @@ functions:
isSpotlight: true
code: |
```
- res = await supabase.auth.mfa.get_authenticator_assurance_level()
+ res = supabase.auth.mfa.get_authenticator_assurance_level()
```
- id: get-user
title: 'get_user'
@@ -415,8 +682,7 @@ functions:
- `setSession()` takes in a refresh token and uses it to get a new session.
- The refresh token can only be used once to obtain a new session.
- [Refresh token rotation](/docs/reference/auth/config#refresh_token_rotation_enabled) is enabled by default on all projects to guard against replay attacks.
- - You can configure the [`REFRESH_TOKEN_REUSE_INTERVAL`](https://supabase.com/docs/reference/auth/config#refresh_token_reuse_interval) which provides a short window in which the same refresh token can be used multiple times in the event of concurrency or offline issues.
- - If you are using React Native, you will need to install a Buffer polyfill via a library such as [rn-nodeify](https://github.com/tradle/rn-nodeify) to properly use the library.
+ - You can configure the [`REFRESH_TOKEN_REUSE_INTERVAL`](/docs/reference/auth/config#refresh_token_reuse_interval) which provides a short window in which the same refresh token can be used multiple times in the event of concurrency or offline issues.
examples:
- id: set-session
name: Refresh the session
@@ -429,7 +695,6 @@ functions:
title: 'refresh_session()'
notes: |
- This method will refresh the session whether the current one is expired or not.
- - Both examples destructure `user` and `session` from `data`. This is not required; so `const { data, error } =` is also valid.
examples:
- id: refresh-session
name: Refresh session using the current session
@@ -440,14 +705,25 @@ functions:
- id: select
title: 'Fetch data: select()'
notes: |
- - By default, Supabase projects return a maximum of 1,000 rows. This setting can be changed in your project's [API settings](https://supabase.com/dashboard/project/_/settings/api). It's recommended that you keep it low to limit the payload size of accidental or malicious requests.
+ - 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.
+ - `select()` can be combined with [Filters](/docs/reference/python/using-filters)
+ - `select()` can be combined with [Modifiers](/docs/reference/python/using-modifiers)
- `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).
+ params:
+ - name: columns
+ isOptional: true
+ type: string
+ description: The columns to retrieve, defaults to `*`.
+ - name: count
+ isOptional: true
+ type: CountMethod
+ description: The property to use to get the count of rows returned.
examples:
- id: getting-your-data
name: Getting your data
code: |
```python
- response = supabase.table('countries').select("*").execute()
+ response = supabase.table("countries").select("*").execute()
```
data:
sql: |
@@ -463,17 +739,30 @@ functions:
(3, 'Algeria');
```
response: |
- ```
- APIResponse(data=[{'id': 1, 'name': 'Afghanistan'},
- {'id': 2, 'name': 'Albania'},
- {'id': 3, 'name': 'Algeria'}],
- count=None)
+ ```json
+ {
+ "data": [
+ {
+ "id": 1,
+ "name": "Afghanistan"
+ },
+ {
+ "id": 2,
+ "name": "Albania"
+ },
+ {
+ "id": 3,
+ "name": "Algeria"
+ }
+ ],
+ "count": null
+ }
```
- id: selecting-specific-columns
name: Selecting specific columns
code: |
```
- response = supabase.table('countries').select('name').execute()
+ response = supabase.table("countries").select("name").execute()
```
data:
sql: |
@@ -489,21 +778,29 @@ functions:
(3, 'Algeria');
```
response: |
+ ```json
+ {
+ "data": [
+ {
+ "name": "Afghanistan"
+ },
+ {
+ "name": "Albania"
+ },
+ {
+ "name": "Algeria"
+ }
+ ],
+ "count": null
+ }
```
- APIResponse(data=[{'name': 'Afghanistan'},
- {'name': 'Albania'},
- {'name': 'Algeria'}],
- count=None)
- ```
- - id: query-foreign-tables
- name: Query foreign tables
+ - id: query-referenced-tables
+ name: Query referenced tables
description: |
If your database has foreign key relationships, you can query related tables too.
code: |
- ```
- response = supabase.table('countries')
- .select('name, cities(name)')
- .execute()
+ ```python
+ response = supabase.table("countries").select("name, cities(name)").execute()
```
data:
sql: |
@@ -529,18 +826,34 @@ functions:
(2, 1, 'Munich');
```
response: |
+ ```json
+ {
+ "data": [
+ {
+ "name": "Germany",
+ "cities": [
+ {
+ "name": "Munich"
+ }
+ ]
+ },
+ {
+ "name": "Indonesia",
+ "cities": [
+ {
+ "name": "Bali"
+ }
+ ]
+ }
+ ],
+ "count": null
+ }
```
- APIResponse(data=[{'name': 'Germany', 'cities': [{'name': 'Munich'}]},
- {'name': 'Indonesia', 'cities': [{'name': 'Bali'}]}],
- count=None)
- ```
- - id: query-foreign-tables-through-a-join-table
- name: Query foreign tables through a join table
+ - id: query-referenced-tables-through-a-join-table
+ name: Query referenced tables through a join table
code: |
- ```
- response = supabase.table('users')
- .select('name, teams(name)')
- .execute()
+ ```python
+ response = supabase.table("users").select("name, teams(name)").execute()
```
data:
sql: |
@@ -582,12 +895,31 @@ functions:
(2, 2);
```
response: |
- ```
- APIResponse(data=[
- {'name': 'Kiran', 'teams': [{'name': 'Green'}, {'name': 'Blue'}]},
- {'name': 'Evan', 'teams': [{'name': 'Blue'}]}
- ],
- count=None)
+ ```json
+ {
+ "data": [
+ {
+ "name": "Kiran",
+ "teams": [
+ {
+ "name": "Green"
+ },
+ {
+ "name": "Blue"
+ }
+ ]
+ },
+ {
+ "name": "Evan",
+ "teams": [
+ {
+ "name": "Blue"
+ }
+ ]
+ }
+ ],
+ "count": null
+ }
```
description: |
If you're in a situation where your tables are **NOT** directly
@@ -595,13 +927,15 @@ functions:
the `select()` method to query the related data. The join table needs
to have the foreign keys as part of its composite primary key.
hideCodeBlock: true
- - id: query-the-same-foreign-table-multiple-times
- name: Query the same foreign table multiple times
+ - id: query-the-same-referenced-table-multiple-times
+ name: Query the same referenced table multiple times
code: |
- ```
- response = supabase.table('messages')
- .select('content,from:sender_id(name),to:receiver_id(name)')
- .execute()
+ ```python
+ response = (
+ supabase.table("messages")
+ .select("content,from:sender_id(name),to:receiver_id(name)")
+ .execute()
+ )
```
data:
sql: |
@@ -628,26 +962,37 @@ functions:
(1, 2, '👋');
```
response: |
- ```
- APIResponse(data=[{'content': '👋',
- 'from': {'name': 'Kiran'},
- 'to': {'name': 'Evan'}}
- ],
- count=None)
+ ```json
+ {
+ "data": [
+ {
+ "content": "👋",
+ "from": {
+ "name": "Kiran"
+ },
+ "to": {
+ "name": "Evan"
+ }
+ }
+ ],
+ "count": null
+ }
```
description: |
- If you need to query the same foreign table twice, use the name of the
+ If you need to query the same referenced table twice, use the name of the
joined column to identify which join to use. You can also give each
column an alias.
hideCodeBlock: true
- - id: filtering-through-foreign-tables
- name: Filtering through foreign tables
+ - id: filtering-through-referenced-tables
+ name: Filtering through referenced tables
code: |
- ```
- response = supabase.table('cities')
- .select('name, countries(*)')
- .eq('countries.name', 'Estonia')
- .execute()
+ ```python
+ response = (
+ supabase.table("cities")
+ .select("name, countries(*)")
+ .eq("countries.name", "Estonia")
+ .execute()
+ )
```
data:
sql: |
@@ -673,24 +1018,31 @@ functions:
(2, 1, 'Munich');
```
response: |
- ```
- APIResponse(data=[{'name': 'Bali', 'countries': None},
- {'name': 'Munich', 'countries': None}],
- count=None)
+ ```json
+ {
+ "data": [
+ {
+ "name": "Bali",
+ "countries": null
+ },
+ {
+ "name": "Munich",
+ "countries": null
+ }
+ ],
+ "count": null
+ }
```
description: |
- NOT WORKING CURRENTLY
- If the filter on a foreign table's column is not satisfied, the foreign
+ If the filter on a referenced table's column is not satisfied, the referenced
table returns `[]` or `null` but the parent table is not filtered out.
If you want to filter out the parent table rows, use the `!inner` hint
hideCodeBlock: true
- - id: querying-foreign-table-with-count
- name: Querying foreign table with count
+ - id: querying-referenced-table-with-count
+ name: Querying referenced table with count
code: |
- ```
- response = supabase.table('countries')
- .select('*, cities(count)')
- .execute()
+ ```python
+ response = supabase.table("countries").select("*, cities(count)").execute()
```
data:
sql: |
@@ -717,10 +1069,21 @@ functions:
('Bristol', (select id from country));
```
response: |
- ```
- APIResponse(data=[{'id': 1, 'name': 'Germany', 'cities': [{'count': 1}]},
- {'id': 2, 'name': 'Indonesia', 'cities': [{'count': 1}]}],
- count=None)
+ ```json
+ {
+ "data": [
+ {
+ "id": "c31e7151-5a6f-453c-915b-caf31ec9a0a0",
+ "name": "united kingdom",
+ "cities": [
+ {
+ "count": 4
+ }
+ ]
+ }
+ ],
+ "count": null
+ }
```
description: |
You can get the number of rows in a related table by using the
@@ -729,10 +1092,8 @@ functions:
- id: querying-with-count-option
name: Querying with count option
code: |
- ```
- response = supabase.table('countries')
- .select('*', count='exact')
- .execute()
+ ```python
+ response = supabase.table("countries").select("*", count="exact").execute()
```
data:
sql: |
@@ -748,10 +1109,24 @@ functions:
(3, 'Algeria');
```
response: |
- ```
- APIResponse(data=[{'id': 1, 'name': 'Germany'},
- {'id': 2, 'name': 'Indonesia'}],
- count=2)
+ ```json
+ {
+ "data": [
+ {
+ "id": 1,
+ "name": "Afghanistan"
+ },
+ {
+ "id": 2,
+ "name": "Albania"
+ },
+ {
+ "id": 3,
+ "name": "Algeria"
+ }
+ ],
+ "count": 3
+ }
```
description: |
You can get the number of rows by using the
@@ -760,10 +1135,8 @@ functions:
- id: querying-json-data
name: Querying JSON data
code: |
- ```
- response = supabase.table('users')
- .select('id, name, address->city')
- .execute()
+ ```python
+ response = supabase.table("users").select("id, name, address->city").execute()
```
data:
sql: |
@@ -781,8 +1154,17 @@ functions:
(1, 'Avdotya', '{"city":"Saint Petersburg"}');
```
response: |
- ```
- APIResponse(data=[{'id': 1, 'name': 'Avdotya', 'city': 'Saint Petersburg'}], count=None)
+ ```json
+ {
+ "data": [
+ {
+ "id": 1,
+ "name": "Avdotya",
+ "city": "Saint Petersburg"
+ }
+ ],
+ "count": null
+ }
```
description: |
You can select and filter data inside of
@@ -790,17 +1172,122 @@ functions:
[operators](/docs/guides/database/json#query-the-jsonb-data) for
querying JSON data.
hideCodeBlock: true
+ - id: querying-referenced-table-with-inner-join
+ name: Querying referenced table with inner join
+ code: |
+ ```python
+ response = (
+ supabase.table("cities")
+ .select("name, countries!inner(name)")
+ .eq("countries.name", "Indonesia")
+ .execute()
+ )
+ ```
+ data:
+ sql: |
+ ```sql
+ create table
+ countries (id int8 primary key, name text);
+ create table
+ cities (
+ id int8 primary key,
+ country_id int8 not null references countries,
+ name text
+ );
+
+ insert into
+ countries (id, name)
+ values
+ (1, 'Germany'),
+ (2, 'Indonesia');
+ insert into
+ cities (id, country_id, name)
+ values
+ (1, 2, 'Bali'),
+ (2, 1, 'Munich');
+ ```
+ response: |
+ ```json
+ {
+ "data": [
+ {
+ "name": "Bali",
+ "countries": {
+ "name": "Indonesia"
+ }
+ }
+ ],
+ "count": null
+ }
+ ```
+ description: |
+ If you don't want to return the referenced table contents, you can leave the parenthesis empty.
+ Like `.select('name, countries!inner()')`.
+ hideCodeBlock: true
+ - id: switching-schemas-per-query
+ name: Switching schemas per query
+ code: |
+ ```python
+ response = supabase.schema("myschema").table("mytable").select("*").execute()
+ ```
+ data:
+ sql: |
+ ```sql
+ create schema myschema;
+
+ create table myschema.mytable (
+ id uuid primary key default gen_random_uuid(),
+ data text
+ );
+
+ insert into myschema.mytable (data) values ('mydata');
+ ```
+ response: |
+ ```json
+ {
+ "data": [
+ {
+ "id": "b1a8c0b5-bdf0-46f1-95a5-f0fb9cb2f410",
+ "data": "mydata"
+ }
+ ],
+ "count": null
+ }
+ ```
+ description: |
+ In addition to setting the schema during initialization, you can also switch schemas on a per-query basis.
+ Make sure you've set up your [database privileges and API settings](/docs/guides/api/using-custom-schemas).
+ hideCodeBlock: true
- id: insert
title: 'Create data: insert()'
+ params:
+ - name: json
+ isOptional: false
+ type: dict, list
+ description: The values to insert. Pass an dict to insert a single row or an list to insert multiple rows.
+ - name: count
+ isOptional: true
+ type: CountMethod
+ description: The property to use to get the count of rows returned.
+ - name: returning
+ isOptional: true
+ type: ReturnMethod
+ description: Either 'minimal' or 'representation'. Defaults to 'representation'.
+ - name: default_to_null
+ isOptional: true
+ type: bool
+ description: Make missing fields default to `null`. Otherwise, use the default value for the column. Only applies for bulk inserts.
examples:
- id: create-a-record
name: Create a record
code: |
```python
- data, count = supabase.table('countries')
- .insert({"id": 1, "name": "Denmark"})
- .execute()
+ response = (
+ supabase.table("countries")
+ .insert({"id": 1, "name": "Denmark"})
+ .execute()
+ )
```
data:
sql: |
@@ -809,24 +1296,100 @@ functions:
countries (id int8 primary key, name text);
```
response: |
- ```
- APIResponse(data=[{'id': 1, 'name': 'Denmark'}], count=None)
+ ```json
+ {
+ "data": [
+ {
+ "id": 1,
+ "name": "Denmark"
+ }
+ ],
+ "count": null
+ }
```
hideCodeBlock: true
isSpotlight: true
+ - id: bulk-create
+ name: Bulk create
+ code: |
+ ```python
+ try:
+ response = supabase.table("countries")
+ .insert([
+ { "id": 1, "name": "Nepal" },
+ { "id": 1, "name": "Vietnam" },
+ ])
+ .execute()
+ return response
+ except Exception as exception:
+ return exception
+ ```
+ data:
+ sql: |
+ ```sql
+ create table
+ countries (id int8 primary key, name text);
+ ```
+ response: |
+ ```json
+ {
+ "_raw_error": {
+ "code": "23505",
+ "details": "Key (id)=(1) already exists.",
+ "hint": null,
+ "message": "duplicate key value violates unique constraint \"countries_pkey\""
+ },
+ "message": "duplicate key value violates unique constraint \"countries_pkey\"",
+ "code": "23505",
+ "hint": null,
+ "details": "Key (id)=(1) already exists."
+ }
+ ```
+ description: |
+ A bulk create operation is handled in a single transaction.
+ If any of the inserts fail, none of the rows are inserted.
+ hideCodeBlock: true
- id: update
title: 'Modify data: update()'
notes: |
- `update()` should always be combined with [Filters](/docs/reference/python/using-filters) to target the item(s) you wish to update.
+ params:
+ - name: json
+ isOptional: false
+ type: dict, list
+ description: The values to insert. Pass an dict to insert a single row or an list to insert multiple rows.
+ - name: count
+ isOptional: true
+ type: CountMethod
+ description: The property to use to get the count of rows returned.
+ - name: returning
+ isOptional: true
+ type: ReturnMethod
+ description: Either 'minimal' or 'representation'. Defaults to 'representation'.
+ - name: ignore_duplicates
+ isOptional: true
+ type: bool
+ description: Whether duplicate rows should be ignored.
+ - name: on_conflict
+ isOptional: true
+ type: bool
+ description: Specified columns to be made to work with UNIQUE constraint.
+ - name: default_to_null
+ isOptional: true
+ type: bool
+ description: |
+ Make missing fields default to `null`. Otherwise, use the default value for the column. This only applies when inserting new rows, not when merging with existing rows under `ignore_duplicates: false`. This also only applies when doing bulk upserts.
examples:
- id: updating-your-data
name: Updating your data
code: |
```python
- data, count = supabase.table('countries')
- .update({'name': 'Australia'})
- .eq('id', 1)
- .execute()
+ response = (
+ supabase.table("countries")
+ .update({"name": "Australia"})
+ .eq("id", 1)
+ .execute()
+ )
```
data:
sql: |
@@ -840,23 +1403,103 @@ functions:
(1, 'Denmark');
```
response: |
- ```
- APIResponse(data=[{'id': 1, 'name': 'Australia'}], count=None)
+ ```json
+ {
+ "data": [
+ {
+ "id": 1,
+ "name": "Australia"
+ }
+ ],
+ "count": null
+ }
```
hideCodeBlock: true
isSpotlight: true
+ - id: updating-json-data
+ name: Updating JSON data
+ code: |
+ ```python
+ response = (
+ supabase.table("users")
+ .update({"address": {"street": "Melrose Place", "postcode": 90210}})
+ .eq("address->postcode", 90210)
+ .execute()
+ )
+ ```
+ 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 }');
+ ```
+ response: |
+ ```json
+ {
+ "data": [
+ {
+ "id": 1,
+ "name": "Michael",
+ "address": {
+ "street": "Melrose Place",
+ "postcode": 90210
+ }
+ }
+ ],
+ "count": null
+ }
+ ```
+ description: |
+ Postgres offers some [operators](/docs/guides/database/json#query-the-jsonb-data) for working with JSON data. Currently, it is only possible to update the entire JSON document.
+ hideCodeBlock: true
- id: upsert
title: 'Upsert data: upsert()'
notes: |
- Primary keys must be included in the `values` dict to use upsert.
+ params:
+ - name: json
+ isOptional: false
+ type: dict, list
+ description: The values to insert. Pass an dict to insert a single row or an list to insert multiple rows.
+ - name: count
+ isOptional: true
+ type: CountMethod
+ description: The property to use to get the count of rows returned.
+ - name: returning
+ isOptional: true
+ type: ReturnMethod
+ description: Either 'minimal' or 'representation'. Defaults to 'representation'.
+ - name: ignore_duplicates
+ isOptional: true
+ type: bool
+ description: Whether duplicate rows should be ignored.
+ - name: on_conflict
+ isOptional: true
+ type: bool
+ description: Specified columns to be made to work with UNIQUE constraint.
+ - name: default_to_null
+ isOptional: true
+ type: bool
+ description: Make missing fields default to `null`. Otherwise, use the default value for the column. Only applies for bulk inserts.
examples:
- id: upsert-your-data
name: Upsert your data
code: |
```python
- data, count = supabase.table('countries')
- .upsert({'id': 1, 'name': 'Australia'})
- .execute()
+ response = (
+ supabase.table("countries")
+ .upsert({"id": 1, "name": "Australia"})
+ .execute()
+ )
```
data:
sql: |
@@ -870,8 +1513,16 @@ functions:
(1, 'Afghanistan');
```
response: |
- ```
- APIResponse(data=[{'id': 1, 'name': 'Australia'}], count=None)
+ ```json
+ {
+ "data": [
+ {
+ "id": 1,
+ "name": "Australia"
+ }
+ ],
+ "count": null
+ }
```
hideCodeBlock: true
isSpotlight: true
@@ -879,9 +1530,11 @@ functions:
name: Bulk Upsert your data
code: |
```python
- data, count = supabase.table('countries')
- .upsert([{'id': 1, 'name': 'Albania'}, {'id': 2, 'name': 'Algeria'}])
- .execute()
+ response = (
+ supabase.table("countries")
+ .upsert([{"id": 1, "name": "Albania"}, {"id": 2, "name": "Algeria"}])
+ .execute()
+ )
```
data:
sql: |
@@ -895,9 +1548,68 @@ functions:
(1, 'Afghanistan');
```
response: |
+ ```json
+ {
+ "data": [
+ {
+ "id": 1,
+ "name": "Albania"
+ },
+ {
+ "id": 2,
+ "name": "Algeria"
+ }
+ ],
+ "count": null
+ }
```
- APIResponse(data=[{'id': 1, 'name': 'Albania'}, {'id': 2, 'name': 'Algeria'}], count=None)
+ hideCodeBlock: true
+ - id: upserting-into-tables-with-constraints
+ name: Upserting into tables with constraints
+ code: |
+ ```python
+ response = (
+ supabase.table("users")
+ .upsert(
+ {"id": 42, "handle": "saoirse", "display_name": "Saoirse"},
+ on_conflict="handle",
+ )
+ .execute()
+ )
```
+ data:
+ sql: |
+ ```sql
+ create table
+ users (
+ id int8 generated by default as identity primary key,
+ handle text not null unique,
+ display_name text
+ );
+
+ insert into
+ users (id, handle, display_name)
+ values
+ (1, 'saoirse', null);
+ ```
+ response: |
+ ```json
+ {
+ "_raw_error": {
+ "code": "23505",
+ "details": "Key (handle)=(saoirse) already exists.",
+ "hint": null,
+ "message": "duplicate key value violates unique constraint \"users_handle_key\""
+ },
+ "message": "duplicate key value violates unique constraint \"users_handle_key\"",
+ "code": "23505",
+ "hint": null,
+ "details": "Key (handle)=(saoirse) already exists."
+ }
+ ```
+ description: |
+ In the following query, `upsert()` implicitly uses the `id`(primary key) column to determine conflicts. If there is no existing row with the same `id`, `upsert()` inserts a new row, which will fail in this case as there is already a row with `handle` `"saoirse"`.
+ Using the `on_conflict` option, you can instruct `upsert()` to use another column with a unique constraint to determine conflicts.
hideCodeBlock: true
- id: delete
@@ -909,15 +1621,22 @@ functions:
rows visible through `SELECT` policies are deleted. Note that by default
no rows are visible, so you need at least one `SELECT`/`ALL` policy that
makes the rows visible.
+ - 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.
+ params:
+ - name: count
+ isOptional: true
+ type: CountMethod
+ description: The property to use to get the count of rows returned.
+ - name: returning
+ isOptional: true
+ type: ReturnMethod
+ description: Either 'minimal' or 'representation'. Defaults to 'representation'.
examples:
- id: delete-records
name: Delete records
code: |
```python
- data, count = supabase.table('countries')
- .delete()
- .eq('id', 1)
- .execute()
+ response = supabase.table('countries').delete().eq('id', 1).execute()
```
data:
sql: |
@@ -930,12 +1649,221 @@ functions:
values
(1, 'Spain');
```
- response: |
+ response: |
+ ```
+ {
+ "data": [
+ {
+ "id": 1,
+ "name": "Spain"
+ }
+ ],
+ "count": null
+ }
+ ```
+ hideCodeBlock: true
+ isSpotlight: true
+ - id: delete-multiple-records
+ name: Delete multiple records
+ code: |
+ ```python
+ response = supabase.table("countries").delete().in_("id", [1, 2, 3]).execute()
+ ```
+ data:
+ sql: |
+ ```sql
+ create table
+ countries (id int8 primary key, name text);
+
+ insert into
+ countries (id, name)
+ values
+ (1, 'Spain'), (2, 'France'), (3, 'Germany');
```
- APIResponse(data=[{'id': 1, 'name': 'United States'], count=None)
+ response: |
+ ```json
+ {
+ "data": [
+ {
+ "id": 1,
+ "name": "Spain"
+ },
+ {
+ "id": 2,
+ "name": "France"
+ },
+ {
+ "id": 3,
+ "name": "Germany"
+ }
+ ],
+ "count": null
+ }
+ ```
+ hideCodeBlock: false
+ isSpotlight: false
+
+ - id: rpc
+ title: 'Postgres functions: rpc()'
+ description: |
+ You can call Postgres functions as _Remote Procedure Calls_, logic in your database that you can execute from anywhere.
+ Functions are useful when the logic rarely changes—like for password resets and updates.
+
+ ```sql
+ create or replace function hello_world() returns text as $$
+ select 'Hello world';
+ $$ language sql;
+ ```
+ params:
+ - name: fn
+ isOptional: false
+ type: callable
+ description: The stored procedure call to be executed.
+ - name: params
+ isOptional: true
+ type: dict of any
+ description: Parameters passed into the stored procedure call.
+ - name: get
+ isOptional: true
+ type: dict of any
+ description: When set to `true`, `data` will not be returned. Useful if you only need the count.
+ - name: head
+ isOptional: true
+ type: dict of any
+ description: When set to `true`, the function will be called with read-only access mode.
+ - name: count
+ isOptional: true
+ type: CountMethod
+ description: |
+ Count algorithm to use to count rows returned by the function. Only applicable for [set-returning functions](https://www.postgresql.org/docs/current/functions-srf.html). `"exact"`: Exact but slow count algorithm. Performs a `COUNT(*)` under the hood. `"planned"`: Approximated but fast count algorithm. Uses the Postgres statistics under the hood. `"estimated"`: Uses exact count for low numbers and planned count for high numbers.
+ examples:
+ - id: call-a-postgres-function-without-arguments
+ name: Call a Postgres function without arguments
+ code: |
+ ```python
+ response = supabase.rpc("hello_world").execute()
+ ```
+ data:
+ sql: |
+ ```sql
+ create function hello_world() returns text as $$
+ select 'Hello world';
+ $$ language sql;
```
- hideCodeBlock: true
- isSpotlight: true
+ response: |
+ ```json
+ {
+ "data": "Hello world",
+ "count": null
+ }
+ ```
+ hideCodeBlock: true
+ isSpotlight: true
+ - id: call-a-postgres-function-with-arguments
+ name: Call a Postgres function with arguments
+ code: |
+ ```python
+ response = supabase.rpc("echo", { "say": "👋" }).execute()
+ ```
+ data:
+ sql: |
+ ```sql
+ create function echo(say text) returns text as $$
+ select say;
+ $$ language sql;
+ ```
+ response: |
+ ```json
+ {
+ "data": "👋",
+ "count": null
+ }
+ ```
+ hideCodeBlock: true
+ - id: bulk-processing
+ name: Bulk processing
+ code: |
+ ```python
+ response = supabase.rpc("add_one_each", {"arr": [1, 2, 3]}).execute()
+ ```
+ data:
+ sql: |
+ ```sql
+ create function add_one_each(arr int[]) returns int[] as $$
+ select array_agg(n + 1) from unnest(arr) as n;
+ $$ language sql;
+ ```
+ response: |
+ ```json
+ {
+ "data": [
+ 2,
+ 3,
+ 4
+ ],
+ "count": null
+ }
+ ```
+ description: |
+ You can process large payloads by passing in an array as an argument.
+ hideCodeBlock: true
+ - id: call-a-postgres-function-with-filters
+ name: Call a Postgres function with filters
+ code: |
+ ```python
+ response = supabase.rpc("list_stored_countries").eq("id", 1).single().execute()
+ ```
+ data:
+ sql: |
+ ```sql
+ create table
+ countries (id int8 primary key, name text);
+
+ insert into
+ countries (id, name)
+ values
+ (1, 'France'),
+ (2, 'United Kingdom');
+
+ create function list_stored_countries() returns setof countries as $$
+ select * from countries;
+ $$ language sql;
+ ```
+ response: |
+ ```json
+ {
+ "data": {
+ "id": 1,
+ "name": "France"
+ },
+ "count": null
+ }
+ ```
+ description: |
+ Postgres functions that return tables can also be combined with [Filters](/docs/reference/javascript/using-filters) and [Modifiers](/docs/reference/javascript/using-modifiers).
+ hideCodeBlock: true
+ - id: call-a-read-only-postgres-function
+ name: Call a read-only Postgres function
+ code: |
+ ```python
+ response = supabase.rpc('hello_world', get=True).execute()
+ ```
+ data:
+ sql: |
+ ```sql
+ create function hello_world() returns text as $$
+ select 'Hello world';
+ $$ language sql;
+ ```
+ response: |
+ ```json
+ {
+ "data": "Hello world",
+ "count": null
+ }
+ ```
+ hideCodeBlock: true
+
- id: using-filters
title: Using Filters
@@ -955,17 +1883,44 @@ functions:
code: |
```python
# Correct
- data, count = supabase.from('cities')
- .select('name, country_id')
- .eq('name', 'The Shire')
- .execute()
+ response = (
+ supabase.table("cities")
+ .select("name, country_id")
+ .eq("name", "Bali")
+ .execute()
+ )
# Incorrect
- data, count = supabase.table('cities')
- .eq('name', 'The Shire')
- .select('name, country_id')
- .execute()
+ response = (
+ supabase.table("cities")
+ .eq("name", "Bali")
+ .select("name, country_id")
+ .execute()
+ )
```
+ data:
+ sql: |
+ ```sql
+ create table
+ countries (id int8 primary key, name text);
+ create table
+ cities (
+ id int8 primary key,
+ country_id int8 not null references countries,
+ name text
+ );
+
+ insert into
+ countries (id, name)
+ values
+ (1, 'Germany'),
+ (2, 'Indonesia');
+ insert into
+ cities (id, country_id, name)
+ values
+ (1, 2, 'Bali'),
+ (2, 1, 'Munich');
+ ```
- id: chaining-filters
name: Chaining
description: |
@@ -973,11 +1928,49 @@ functions:
to query cities with population between 1,000 and 10,000.
code: |
```python
- data, count = supabase.table('cities')
- .select('name, country_id')
- .gte('population', 1000)
- .lt('population', 10000)
- .execute()
+ response = (
+ supabase.table("cities")
+ .select("name, country_id")
+ .gte("population", 1000)
+ .lt("population", 10000)
+ .execute()
+ )
+ ```
+ data:
+ sql: |
+ ```sql
+ create table
+ countries (id int8 primary key, name text);
+ create table
+ cities (
+ id int8 primary key,
+ country_id int8 not null references countries,
+ name text,
+ population int8
+ );
+
+ insert into
+ countries (id, name)
+ values
+ (1, 'Germany'),
+ (2, 'Indonesia');
+ insert into
+ cities (id, country_id, name, population)
+ values
+ (1, 2, 'Bali', 9980),
+ (2, 1, 'Munich', 250000);
+ ```
+ response: |
+ ```json
+ {
+ "data": [
+ {
+ "name": "Bali",
+ "country_id": 2
+ }
+ ],
+ "count": null
+ }
```
- id: conditional-chaining
name: Conditional chaining
@@ -989,27 +1982,65 @@ functions:
filterPopLow = 1000
filterPopHigh = 10000
- query = supabase.from('cities').select('name, country_id')
+ query = supabase.table("cities").select("name, country_id")
if filterByName:
- query = query.eq('name', filterByName)
+ query = query.eq("name", filterByName)
if filterPopLow:
- query = query.gte('population', filterPopLow)
+ query = query.gte("population", filterPopLow)
if filterPopHigh:
- query = query.lt('population', filterPopHigh)
+ query = query.lt("population", filterPopHigh)
response = query.execute()
```
+ data:
+ sql: |
+ ```sql
+ create table
+ countries (id int8 primary key, name text);
+ create table
+ cities (
+ id int8 primary key,
+ country_id int8 not null references countries,
+ name text,
+ population int8
+ );
+
+ insert into
+ countries (id, name)
+ values
+ (1, 'Germany'),
+ (2, 'Indonesia');
+ insert into
+ cities (id, country_id, name, population)
+ values
+ (1, 2, 'Bali', 9980),
+ (2, 1, 'Munich', 250000);
+ ```
+ response: |
+ ```json
+ {
+ "data": [
+ {
+ "name": "Bali",
+ "country_id": 2
+ }
+ ],
+ "count": null
+ }
+ ```
- id: filter-by-value-within-json-column
name: Filter by values within JSON column
code: |
```python
- data, count = supabase.table('users')
- .select('*')
- .eq('address->postcode', 90210)
- .execute()
+ response = (
+ supabase.table("users")
+ .select("*")
+ .eq("address->postcode", 90210)
+ .execute()
+ )
```
data:
sql: |
@@ -1028,17 +2059,30 @@ functions:
(2, 'Jane', null);
```
response: |
- ```
- APIResponse(data=[{'id': 1, 'name': 'Michael', 'address': {'postcode': 90210}}], count=None)
+ ```json
+ {
+ "data": [
+ {
+ "id": 1,
+ "name": "Michael",
+ "address": {
+ "postcode": 90210
+ }
+ }
+ ],
+ "count": null
+ }
```
- id: filter-foreign-tables
name: Filter Foreign Tables
code: |
```python
- data, count = supabase.table('countries')
- .select('name, cities!inner(name)')
- .eq('cities.name', 'Bali')
- .execute()
+ response = (
+ supabase.table("countries")
+ .select("name, cities!inner(name)")
+ .eq("cities.name", "Bali")
+ .execute()
+ )
```
data:
sql: |
@@ -1064,8 +2108,20 @@ functions:
(2, 1, 'Munich');
```
response: |
- ```
- APIResponse(data=[{'name': 'Indonesia', 'cities': [{'name': 'Bali'}]}], count=None)
+ ```json
+ {
+ "data": [
+ {
+ "name": "Indonesia",
+ "cities": [
+ {
+ "name": "Bali"
+ }
+ ]
+ }
+ ],
+ "count": null
+ }
```
description: |
You can filter on foreign tables in your `select()` query using dot
@@ -1073,46 +2129,23 @@ functions:
- id: eq
title: eq()
+ description: |
+ Match only rows where `column` is equal to `value`.
+ params:
+ - name: column
+ isOptional: false
+ type: string
+ description: The column to filter on
+ - name: value
+ isOptional: false
+ type: any
+ description: The value to filter by
examples:
- id: with-select
name: With `select()`
code: |
```python
- data, count = supabase.table('countries')
- .select('*')
- .eq('name', 'Albania')
- .execute()
- ```
- data:
- sql: |
- ```sql
- create table
- countries (id int8 primary key, name text);
-
- insert into
- countries (id, name)
- values
- (1, 'Afghanistan'),
- (2, 'Albania'),
- (3, 'Algeria');
- ```
- response: |
- ```
- APIResponse(data=[{'id': 2, 'name': 'Albania'}], count=None)
- ```
- hideCodeBlock: true
- isSpotlight: true
- - id: neq
- title: neq()
- examples:
- - id: with-select
- name: With `select()`
- code: |
- ```python
- data, count = supabase.table('countries')
- .select('*')
- .neq('name', 'Albania')
- .execute()
+ response = supabase.table("countries").select("*").eq("name", "Albania").execute()
```
data:
sql: |
@@ -1128,24 +2161,89 @@ functions:
(3, 'Algeria');
```
response: |
+ ```json
+ {
+ "data": [
+ {
+ "id": 2,
+ "name": "Albania"
+ }
+ ],
+ "count": null
+ }
```
- APIResponse(data=[{'id': 1, 'name': 'Afghanistan'},
- {'id': 3, 'name': 'Algeria'}],
- count=None)
+ hideCodeBlock: true
+ isSpotlight: true
+ - id: neq
+ title: neq()
+ description: |
+ Match only rows where `column` is not equal to `value`.
+ params:
+ - name: column
+ isOptional: false
+ type: string
+ description: The column to filter on
+ - name: value
+ isOptional: false
+ type: any
+ description: The value to filter by
+ examples:
+ - id: with-select
+ name: With `select()`
+ code: |
+ ```python
+ response = supabase.table("countries").select("*").neq("name", "Albania").execute()
+ ```
+ data:
+ sql: |
+ ```sql
+ create table
+ countries (id int8 primary key, name text);
+
+ insert into
+ countries (id, name)
+ values
+ (1, 'Afghanistan'),
+ (2, 'Albania'),
+ (3, 'Algeria');
+ ```
+ response: |
+ ```json
+ {
+ "data": [
+ {
+ "id": 1,
+ "name": "Afghanistan"
+ },
+ {
+ "id": 3,
+ "name": "Algeria"
+ }
+ ],
+ "count": null
+ }
```
hideCodeBlock: true
isSpotlight: true
- id: gt
title: gt()
+ description: |
+ Match only rows where `column` is greather than `value`.
+ params:
+ - name: column
+ isOptional: false
+ type: string
+ description: The column to filter on
+ - name: value
+ isOptional: false
+ type: any
+ description: The value to filter by
examples:
- id: with-select
name: With `select()`
code: |
```python
- data, count = supabase.table('countries')
- .select('*')
- .gt('id', 2)
- .execute()
+ response = supabase.table("countries").select("*").gt("id", 2).execute()
```
data:
sql: |
@@ -1161,8 +2259,16 @@ functions:
(3, 'Algeria');
```
response: |
- ```
- APIResponse(data=[{'id': 3, 'name': 'Algeria'}], count=None)
+ ```json
+ {
+ "data": [
+ {
+ "id": 3,
+ "name": "Algeria"
+ }
+ ],
+ "count": null
+ }
```
hideCodeBlock: true
isSpotlight: true
@@ -1171,15 +2277,23 @@ functions:
to add double quotes e.g. `.gt('"order"', 2)`
- id: gte
title: gte()
+ description: |
+ Match only rows where `column` is greater than or equal to `value`.
+ params:
+ - name: column
+ isOptional: false
+ type: string
+ description: The column to filter on
+ - name: value
+ isOptional: false
+ type: any
+ description: The value to filter by
examples:
- id: with-select
name: With `select()`
code: |
```python
- data, count = supabase.table('countries')
- .select('*')
- .gte('id', 2)
- .execute()
+ response = supabase.table("countries").select("*").gte("id", 2).execute()
```
data:
sql: |
@@ -1195,24 +2309,42 @@ functions:
(3, 'Algeria');
```
response: |
- ```
- APIResponse(data=[{'id': 2, 'name': 'Albania'},
- {'id': 3, 'name': 'Algeria'}],
- count=None)
+ ```json
+ {
+ "data": [
+ {
+ "id": 2,
+ "name": "Albania"
+ },
+ {
+ "id": 3,
+ "name": "Algeria"
+ }
+ ],
+ "count": null
+ }
```
hideCodeBlock: true
isSpotlight: true
- id: lt
title: lt()
+ description: |
+ Match only rows where `column` is less than `value`.
+ params:
+ - name: column
+ isOptional: false
+ type: string
+ description: The column to filter on
+ - name: value
+ isOptional: false
+ type: any
+ description: The value to filter by
examples:
- id: with-select
name: With `select()`
code: |
```python
- data, count = supabase.table('countries')
- .select('*')
- .lt('id', 2)
- .execute()
+ response = supabase.table("countries").select("*").lt("id", 2).execute()
```
data:
sql: |
@@ -1228,22 +2360,38 @@ functions:
(3, 'Algeria');
```
response: |
- ```
- APIResponse(data=[{'id': 1, 'name': 'Afghanistan'}], count=None)
+ ```json
+ {
+ "data": [
+ {
+ "id": 1,
+ "name": "Afghanistan"
+ }
+ ],
+ "count": null
+ }
```
hideCodeBlock: true
isSpotlight: true
- id: lte
title: lte()
+ description: |
+ Match only rows where `column` is less than or equal to `value`.
+ params:
+ - name: column
+ isOptional: false
+ type: string
+ description: The column to filter on
+ - name: value
+ isOptional: false
+ type: any
+ description: The value to filter by
examples:
- id: with-select
name: With `select()`
code: |
```python
- data, count = supabase.table('countries')
- .select('*')
- .lte('id', 2)
- .execute()
+ response = supabase.table("countries").select("*").lte("id", 2).execute()
```
data:
sql: |
@@ -1259,24 +2407,42 @@ functions:
(3, 'Algeria');
```
response: |
- ```
- APIResponse(data=[{'id': 1, 'name': 'Afghanistan'},
- {'id': 2, 'name': 'Albania'}],
- count=None)
+ ```json
+ {
+ "data": [
+ {
+ "id": 1,
+ "name": "Afghanistan"
+ },
+ {
+ "id": 2,
+ "name": "Albania"
+ }
+ ],
+ "count": null
+ }
```
hideCodeBlock: true
isSpotlight: true
- id: like
title: like()
+ description: |
+ Match only rows where `column` matches `pattern` case-sensitively.
+ params:
+ - name: column
+ isOptional: false
+ type: string
+ description: The name of the column to apply a filter on
+ - name: pattern
+ isOptional: false
+ type: string
+ description: The pattern to match by
examples:
- id: with-select
name: With `select()`
code: |
```python
- data, count = supabase.table('countries')
- .select('*')
- .like('name', '%Alba%')
- .execute()
+ response = supabase.table("countries").select("*").like("name", "%Alba%").execute()
```
data:
sql: |
@@ -1292,22 +2458,38 @@ functions:
(3, 'Algeria');
```
response: |
- ```
- APIResponse(data=[{'id': 2, 'name': 'Albania'}], count=None)
+ ```json
+ {
+ "data": [
+ {
+ "id": 2,
+ "name": "Albania"
+ }
+ ],
+ "count": null
+ }
```
hideCodeBlock: true
isSpotlight: true
- id: ilike
title: ilike()
+ description: |
+ Match only rows where `column` matches `pattern` case-insensitively.
+ params:
+ - name: column
+ isOptional: false
+ type: string
+ description: The name of the column to apply a filter on
+ - name: pattern
+ isOptional: false
+ type: string
+ description: The pattern to match by
examples:
- id: with-select
name: With `select()`
code: |
```python
- data, count = supabase.table('countries')
- .select('*')
- .ilike('name', '%alba%')
- .execute()
+ response = supabase.table("countries").select("*").ilike("name", "%alba%").execute()
```
data:
sql: |
@@ -1323,22 +2505,38 @@ functions:
(3, 'Algeria');
```
response: |
- ```
- APIResponse(data=[{'id': 2, 'name': 'Albania'}], count=None)
+ ```json
+ {
+ "data": [
+ {
+ "id": 2,
+ "name": "Albania"
+ }
+ ],
+ "count": null
+ }
```
hideCodeBlock: true
isSpotlight: true
- id: is
title: is_()
+ description: |
+ Match only rows where `column` IS `value`.
+ params:
+ - name: column
+ isOptional: false
+ type: string
+ description: The name of the column to apply a filter on
+ - name: value
+ isOptional: false
+ type: null | boolean
+ description: The value to match by
examples:
- id: checking-nullness
name: Checking for nullness, True or False
code: |
```python
- data, count = supabase.table('countries')
- .select('*')
- .is_('name', 'null')
- .execute()
+ response = supabase.table("countries").select("*").is_("name", "null").execute()
```
data:
sql: |
@@ -1353,8 +2551,16 @@ functions:
(2, null);
```
response: |
- ```
- APIResponse(data=[{'id': 2, 'name': None}], count=None)
+ ```json
+ {
+ "data": [
+ {
+ "id": 2,
+ "name": null
+ }
+ ],
+ "count": null
+ }
```
description: |
Using the `eq()` filter doesn't work when filtering for `null`. Instead, you need to use `is_()`.
@@ -1366,15 +2572,28 @@ functions:
isSpotlight: true
- id: in
title: in_()
+ description: |
+ Match only rows where `column` is included in the `values` array.
+ params:
+ - name: column
+ isOptional: false
+ type: string
+ description: The column to filter on
+ - name: values
+ isOptional: false
+ type: array
+ description: The values to filter by
examples:
- id: with-select
name: With `select()`
code: |
```python
- data, count = supabase.table('countries')
- .select('*')
- .in_('name', ['Albania', 'Algeria'])
+ response = (
+ supabase.table("countries")
+ .select("*")
+ .in_("name", ["Albania", "Algeria"])
.execute()
+ )
```
data:
sql: |
@@ -1390,24 +2609,47 @@ functions:
(3, 'Algeria');
```
response: |
- ```
- APIResponse(data=[{'id': 2, 'name': 'Albania'},
- {'id': 3, 'name': 'Algeria'}],
- count=None)
+ ```json
+ {
+ "data": [
+ {
+ "id": 2,
+ "name": "Albania"
+ },
+ {
+ "id": 3,
+ "name": "Algeria"
+ }
+ ],
+ "count": null
+ }
```
hideCodeBlock: true
isSpotlight: true
- id: contains
title: contains()
+ description: |
+ Only relevant for jsonb, array, and range columns. Match only rows where `column` contains every element appearing in `value`.
+ params:
+ - name: column
+ isOptional: false
+ type: string
+ description: The column to filter on
+ - name: values
+ isOptional: false
+ type: object
+ description: The jsonb, array, or range value to filter with
examples:
- id: on-array-columns
name: On array columns
code: |
```python
- data, count = supabase.table('issues')
- .select('*')
- .contains('tags', ['is:open', 'priority:low'])
+ response = (
+ supabase.table("issues")
+ .select("*")
+ .contains("tags", ["is:open", "priority:low"])
.execute()
+ )
```
data:
sql: |
@@ -1425,8 +2667,21 @@ functions:
(2, 'Use better names', array['is:open', 'severity:low', 'priority:medium']);
```
response: |
- ```
- APIResponse(data=[{'id': 1, 'title': 'Cache invalidation is not working', 'tags': ['is:open', 'severity:high', 'priority:low']}], count=None)
+ ```json
+ {
+ "data": [
+ {
+ "id": 1,
+ "title": "Cache invalidation is not working",
+ "tags": [
+ "is:open",
+ "severity:high",
+ "priority:low"
+ ]
+ }
+ ],
+ "count": null
+ }
```
hideCodeBlock: true
isSpotlight: true
@@ -1434,10 +2689,12 @@ functions:
name: On range columns
code: |
```python
- data, count = supabase.table('reservations')
- .select('*')
- .contains('during', '[2000-01-01 13:00, 2000-01-01 13:30)')
+ response = (
+ supabase.table("reservations")
+ .select("*")
+ .contains("during", "[2000-01-01 13:00, 2000-01-01 13:30)")
.execute()
+ )
```
data:
sql: |
@@ -1456,8 +2713,17 @@ functions:
(2, 'Topaz', '[2000-01-02 09:00, 2000-01-02 10:00)');
```
response: |
- ```
- APIResponse(data=[{'id': 1, 'room_name': 'Emerald', 'during': '["2000-01-01 13:00:00","2000-01-01 15:00:00")'}], count=None)
+ ```json
+ {
+ "data": [
+ {
+ "id": 1,
+ "room_name": "Emerald",
+ "during": "[\"2000-01-01 13:00:00\",\"2000-01-01 15:00:00\")"
+ }
+ ],
+ "count": null
+ }
```
description: |
Postgres supports a number of [range
@@ -1469,10 +2735,12 @@ functions:
name: On `jsonb` columns
code: |
```python
- data, count = supabase.table('users')
- .select('*')
- .contains('address', {'postcode': 90210})
+ response = (
+ supabase.table("users")
+ .select("*")
+ .contains("address", {"postcode": 90210})
.execute()
+ )
```
data:
sql: |
@@ -1491,21 +2759,46 @@ functions:
(2, 'Jane', '{}');
```
response: |
- ```
- APIResponse(data=[{'id': 1, 'name': 'Michael', 'address': {'postcode': 90210}}], count=None)
+ ```json
+ {
+ "data": [
+ {
+ "id": 1,
+ "name": "Michael",
+ "address": {
+ "street": "Melrose Place",
+ "postcode": 90210
+ }
+ }
+ ],
+ "count": null
+ }
```
hideCodeBlock: true
- id: contained-by
title: contained_by()
+ description: |
+ Only relevant for jsonb, array, and range columns. Match only rows where every element appearing in `column` is contained by `value`.
+ params:
+ - name: column
+ isOptional: false
+ type: string
+ description: The jsonb, array, or range column to filter on
+ - name: value
+ isOptional: false
+ type: object
+ description: The jsonb, array, or range value to filter with
examples:
- id: on-array-columns
name: On array columns
code: |
```python
- data, count = supabase.table('classes')
- .select('name')
- .contained_by('days', ['monday', 'tuesday', 'wednesday', 'friday'])
- .execute()
+ response = (
+ supabase.table("classes")
+ .select("name")
+ .contained_by("days", ["monday", "tuesday", "wednesday", "friday"])
+ .execute()
+ )
```
data:
sql: |
@@ -1524,8 +2817,15 @@ functions:
(2, 'History', array['monday', 'wednesday', 'thursday']);
```
response: |
- ```
- APIResponse(data=[{'name': 'Chemistry'}], count=None)
+ ```json
+ {
+ "data": [
+ {
+ "name": "Chemistry"
+ }
+ ],
+ "count": null
+ }
```
hideCodeBlock: true
isSpotlight: true
@@ -1533,10 +2833,12 @@ functions:
name: On range columns
code: |
```python
- data, count = supabase.table('reservations')
- .select('*')
- .contained_by('during', '[2000-01-01 00:00, 2000-01-01 23:59)')
- .execute()
+ response = (
+ supabase.table("reservations")
+ .select("*")
+ .contained_by("during", "[2000-01-01 00:00, 2000-01-01 23:59)")
+ .execute()
+ )
```
data:
sql: |
@@ -1555,8 +2857,17 @@ functions:
(2, 'Topaz', '[2000-01-02 09:00, 2000-01-02 10:00)');
```
response: |
- ```
- APIResponse(data=[{'id': 1, 'room_name': 'Emerald', 'during': '["2000-01-01 13:00:00","2000-01-01 15:00:00")'}], count=None)
+ ```json
+ {
+ "data": [
+ {
+ "id": 1,
+ "room_name": "Emerald",
+ "during": "[\"2000-01-01 13:00:00\",\"2000-01-01 15:00:00\")"
+ }
+ ],
+ "count": null
+ }
```
description: |
Postgres supports a number of [range
@@ -1568,10 +2879,12 @@ functions:
name: On `jsonb` columns
code: |
```python
- data, count = supabase.table('users')
- .select('name')
- .contained_by('address', {})
+ response = (
+ supabase.table("users")
+ .select("name")
+ .contained_by("address", {})
.execute()
+ )
```
data:
sql: |
@@ -1590,21 +2903,554 @@ functions:
(2, 'Jane', '{}');
```
response: |
- ```
- APIResponse(data=[{'name': 'Jane'}], count=None)
+ ```json
+ {
+ "data": [
+ {
+ "name": "Jane"
+ }
+ ],
+ "count": null
+ }
```
hideCodeBlock: true
- - id: match
- title: match()
+ - id: range-gt
+ title: range_gt()
+ description: |
+ Only relevant for range columns. Match only rows where every element in `column` is greater than any element in `range`.
+ params:
+ - name: column
+ isOptional: false
+ type: string
+ description: The range column to filter on
+ - name: range
+ isOptional: false
+ type: array
+ description: The range to filter with
examples:
- id: with-select
name: With `select()`
code: |
```python
- data, count = supabase.table('countries')
- .select('*')
- .match({'id': 2, 'name': 'Albania'})
+ response = (
+ supabase.table("reservations")
+ .select("*")
+ .range_gt("during", ["2000-01-02 08:00", "2000-01-02 09:00"])
.execute()
+ )
+ ```
+ data:
+ sql: |
+ ```sql
+ create table
+ reservations (
+ id int8 primary key,
+ room_name text,
+ during tsrange
+ );
+
+ insert into
+ reservations (id, room_name, during)
+ values
+ (1, 'Emerald', '[2000-01-01 13:00, 2000-01-01 15:00)'),
+ (2, 'Topaz', '[2000-01-02 09:00, 2000-01-02 10:00)');
+ ```
+ response: |
+ ```json
+ {
+ "data": [
+ {
+ "id": 2,
+ "room_name": "Topaz",
+ "during": "[\"2000-01-02 09:00:00\",\"2000-01-02 10:00:00\")"
+ }
+ ],
+ "count": null
+ }
+ ```
+ description: |
+ Postgres supports a number of [range types](https://www.postgresql.org/docs/current/rangetypes.html). You can filter on range columns using the string representation of range values.
+ hideCodeBlock: true
+ isSpotlight: true
+ - id: range-gte
+ title: range_gte()
+ description: |
+ Only relevant for range columns. Match only rows where every element in `column` is either contained in `range` or greater than any element in `range`.
+ params:
+ - name: column
+ isOptional: false
+ type: string
+ description: The range column to filter on
+ - name: range
+ isOptional: false
+ type: string
+ description: The range to filter with
+ examples:
+ - id: with-select
+ name: With `select()`
+ code: |
+ ```python
+ response = (
+ supabase.table("reservations")
+ .select("*")
+ .range_gte("during", ["2000-01-02 08:30", "2000-01-02 09:30"])
+ .execute()
+ )
+ ```
+ data:
+ sql: |
+ ```sql
+ create table
+ reservations (
+ id int8 primary key,
+ room_name text,
+ during tsrange
+ );
+
+ insert into
+ reservations (id, room_name, during)
+ values
+ (1, 'Emerald', '[2000-01-01 13:00, 2000-01-01 15:00)'),
+ (2, 'Topaz', '[2000-01-02 09:00, 2000-01-02 10:00)');
+ ```
+ response: |
+ ```json
+ {
+ "data": [
+ {
+ "id": 2,
+ "room_name": "Topaz",
+ "during": "[\"2000-01-02 09:00:00\",\"2000-01-02 10:00:00\")"
+ }
+ ],
+ "count": null
+ }
+ ```
+ description: |
+ Postgres supports a number of [range types](https://www.postgresql.org/docs/current/rangetypes.html). You can filter on range columns using the string representation of range values.
+ hideCodeBlock: true
+ isSpotlight: true
+ - id: range-lt
+ title: range_lt()
+ description: |
+ Only relevant for range columns. Match only rows where every element in `column` is less than any element in `range`.
+ params:
+ - name: column
+ isOptional: false
+ type: string
+ description: The range column to filter on
+ - name: range
+ isOptional: false
+ type: array
+ description: The range to filter with
+ examples:
+ - id: with-select
+ name: With `select()`
+ code: |
+ ```python
+ response = (
+ supabase.table("reservations")
+ .select("*")
+ .range_lt("during", ["2000-01-01 15:00", "2000-01-01 16:00"])
+ .execute()
+ )
+ ```
+ data:
+ sql: |
+ ```sql
+ create table
+ reservations (
+ id int8 primary key,
+ room_name text,
+ during tsrange
+ );
+
+ insert into
+ reservations (id, room_name, during)
+ values
+ (1, 'Emerald', '[2000-01-01 13:00, 2000-01-01 15:00)'),
+ (2, 'Topaz', '[2000-01-02 09:00, 2000-01-02 10:00)');
+ ```
+ response: |
+ ```json
+ {
+ "data": [
+ {
+ "id": 1,
+ "room_name": "Emerald",
+ "during": "[\"2000-01-01 13:00:00\",\"2000-01-01 15:00:00\")"
+ }
+ ],
+ "count": null
+ }
+ ```
+ description: |
+ Postgres supports a number of [range types](https://www.postgresql.org/docs/current/rangetypes.html). You can filter on range columns using the string representation of range values.
+ hideCodeBlock: true
+ isSpotlight: true
+ - id: range-lte
+ title: range_lte()
+ description: |
+ Only relevant for range columns. Match only rows where every element in `column` is less than any element in `range`.
+ params:
+ - name: column
+ isOptional: false
+ type: string
+ description: The range column to filter on
+ - name: range
+ isOptional: false
+ type: array
+ description: The range to filter with
+ examples:
+ - id: with-select
+ name: With `select()`
+ code: |
+ ```python
+ response = (
+ supabase.table("reservations")
+ .select("*")
+ .range_lte("during", ["2000-01-01 14:00", "2000-01-01 16:00"])
+ .execute()
+ )
+ ```
+ data:
+ sql: |
+ ```sql
+ create table
+ reservations (
+ id int8 primary key,
+ room_name text,
+ during tsrange
+ );
+
+ insert into
+ reservations (id, room_name, during)
+ values
+ (1, 'Emerald', '[2000-01-01 13:00, 2000-01-01 15:00)'),
+ (2, 'Topaz', '[2000-01-02 09:00, 2000-01-02 10:00)');
+ ```
+ response: |
+ ```json
+ {
+ "data": [
+ {
+ "id": 1,
+ "room_name": "Emerald",
+ "during": "[\"2000-01-01 13:00:00\",\"2000-01-01 15:00:00\")"
+ }
+ ],
+ "count": null
+ }
+ ```
+ description: |
+ Postgres supports a number of [range types](https://www.postgresql.org/docs/current/rangetypes.html). You can filter on range columns using the string representation of range values.
+ hideCodeBlock: true
+ isSpotlight: true
+
+ - id: range-adjacent
+ title: range_adjacent()
+ description: |
+ Only relevant for range columns. Match only rows where `column` is mutually exclusive to `range` and there can be no element between the two ranges.
+ params:
+ - name: column
+ isOptional: false
+ type: string
+ description: The range column to filter on
+ - name: range
+ isOptional: false
+ type: array
+ description: The range to filter with
+ examples:
+ - id: with-select
+ name: With `select()`
+ code: |
+ ```python
+ response = (
+ supabase.table("reservations")
+ .select("*")
+ .range_adjacent("during", ["2000-01-01 12:00", "2000-01-01 13:00"])
+ .execute()
+ )
+ ```
+ data:
+ sql: |
+ ```sql
+ create table
+ reservations (
+ id int8 primary key,
+ room_name text,
+ during tsrange
+ );
+
+ insert into
+ reservations (id, room_name, during)
+ values
+ (1, 'Emerald', '[2000-01-01 13:00, 2000-01-01 15:00)'),
+ (2, 'Topaz', '[2000-01-02 09:00, 2000-01-02 10:00)');
+ ```
+ response: |
+ ```json
+ {
+ "data": [
+ {
+ "id": 1,
+ "room_name": "Emerald",
+ "during": "[\"2000-01-01 13:00:00\",\"2000-01-01 15:00:00\")"
+ }
+ ],
+ "count": null
+ }
+ ```
+ description: |
+ Postgres supports a number of [range types](https://www.postgresql.org/docs/current/rangetypes.html). You can filter on range columns using the string representation of range values.
+ hideCodeBlock: true
+ isSpotlight: true
+
+ - id: overlaps
+ title: overlaps()
+ description: |
+ Only relevant for array and range columns. Match only rows where `column` and `value` have an element in common.
+ params:
+ - name: column
+ isOptional: false
+ type: string
+ description: The array or range column to filter on
+ - name: value
+ isOptional: false
+ type: Iterable[Any]
+ description: The array or range value to filter with
+ examples:
+ - id: on-array-columns
+ name: On array columns
+ code: |
+ ```python
+ response = (
+ supabase.table("issues")
+ .select("title")
+ .overlaps("tags", ["is:closed", "severity:high"])
+ .execute()
+ )
+ ```
+ data:
+ sql: |
+ ```sql
+ create table
+ issues (
+ id int8 primary key,
+ title text,
+ tags text[]
+ );
+
+ insert into
+ issues (id, title, tags)
+ values
+ (1, 'Cache invalidation is not working', array['is:open', 'severity:high', 'priority:low']),
+ (2, 'Use better names', array['is:open', 'severity:low', 'priority:medium']);
+ ```
+ response: |
+ ```json
+ {
+ "data": [
+ {
+ "title": "Cache invalidation is not working"
+ }
+ ],
+ "count": null
+ }
+ ```
+ hideCodeBlock: true
+ isSpotlight: true
+ - id: on-range-columns
+ name: On range columns
+ code: |
+ ```python
+ response = (
+ supabase.table("reservations")
+ .select("*")
+ .overlaps("during", "[2000-01-01 12:45, 2000-01-01 13:15)")
+ .execute()
+ )
+ ```
+ data:
+ sql: |
+ ```sql
+ create table
+ reservations (
+ id int8 primary key,
+ room_name text,
+ during tsrange
+ );
+
+ insert into
+ reservations (id, room_name, during)
+ values
+ (1, 'Emerald', '[2000-01-01 13:00, 2000-01-01 15:00)'),
+ (2, 'Topaz', '[2000-01-02 09:00, 2000-01-02 10:00)');
+ ```
+ response: |
+ ```json
+ {
+ "data": [
+ {
+ "id": 1,
+ "room_name": "Emerald",
+ "during": "[\"2000-01-01 13:00:00\",\"2000-01-01 15:00:00\")"
+ }
+ ],
+ "status": 200,
+ "statusText": "OK"
+ }
+ ```
+ description: |
+ Postgres supports a number of [range types](https://www.postgresql.org/docs/current/rangetypes.html). You can filter on range columns using the string representation of range values.
+ hideCodeBlock: true
+
+ - id: text-search
+ title: text_search()
+ description: |
+ Only relevant for text and tsvector columns. Match only rows where `column` matches the query string in `query`.
+
+ params:
+ - name: column
+ isOptional: false
+ type: string
+ description: The text or tsvector column to filter on
+ - name: query
+ isOptional: false
+ type: string
+ description: The query text to match with
+ - name: options
+ isOptional: true
+ type: object
+ description: Named parameters
+ subContent:
+ - name: type
+ isOptional: true
+ type: '"plain" | "phrase" | "websearch"'
+ description: Change how the `query` text is interpreted
+ - name: config
+ isOptional: true
+ type: string
+ description: The text search configuration to use
+ notes: |
+ - For more information, see [Postgres full text search](/docs/guides/database/full-text-search).
+ examples:
+ - id: text-search
+ name: Text search
+ code: |
+ ```python
+ response = (
+ supabase.table("texts")
+ .select("content")
+ .text_search("content", "'eggs' & 'ham'", options={"config": "english"})
+ .execute()
+ )
+ ```
+ data:
+ sql: |
+ ```sql
+ create table texts (
+ id bigint
+ primary key
+ generated always as identity,
+ content text
+ );
+
+ insert into texts (content) values
+ ('Four score and seven years ago'),
+ ('The road goes ever on and on'),
+ ('Green eggs and ham')
+ ;
+ ```
+ response: |
+ ```json
+ {
+ "data": [
+ {
+ "content": "Green eggs and ham"
+ }
+ ],
+ "count": null
+ }
+ ```
+ - id: basic-normalization
+ name: Basic normalization
+ description: Uses PostgreSQL's `plainto_tsquery` function.
+ code: |
+ ```python
+ response = (
+ supabase.table("quotes")
+ .select("catchphrase")
+ .text_search(
+ "catchphrase",
+ "'fat' & 'cat'",
+ options={"type": "plain", "config": "english"},
+ )
+ .execute()
+ )
+ ```
+ - id: full-normalization
+ name: Full normalization
+ description: Uses PostgreSQL's `phraseto_tsquery` function.
+ code: |
+ ```python
+ response = (
+ supabase.table("quotes")
+ .select("catchphrase")
+ .text_search(
+ "catchphrase",
+ "'fat' & 'cat'",
+ options={"type": "phrase", "config": "english"},
+ )
+ .execute()
+ )
+ ```
+ - id: web-search
+ name: Websearch
+ description: |
+ Uses PostgreSQL's `websearch_to_tsquery` function.
+ This function will never raise syntax errors, which makes it possible to use raw user-supplied input for search, and can be used
+ with advanced operators.
+
+ - `unquoted text`: text not inside quote marks will be converted to terms separated by & operators, as if processed by plainto_tsquery.
+ - `"quoted text"`: text inside quote marks will be converted to terms separated by <-> operators, as if processed by phraseto_tsquery.
+ - `OR`: the word “or” will be converted to the | operator.
+ - `-`: a dash will be converted to the ! operator.
+
+ code: |
+ ```python
+ response = (
+ supabase.table("quotes")
+ .select("catchphrase")
+ .text_search(
+ "catchphrase",
+ "'fat or cat'",
+ options={"type": "websearch", "config": "english"},
+ )
+ .execute()
+ )
+ ```
+
+ - id: match
+ title: match()
+ description: |
+ Match only rows where each column in `query` keys is equal to its associated value. Shorthand for multiple `.eq()`s.
+ params:
+ - name: query
+ isOptional: false
+ type: dict
+ description: The object to filter with, with column names as keys mapped to their filter values
+ examples:
+ - id: with-select
+ name: With `select()`
+ code: |
+ ```python
+ response = (
+ supabase.table("countries")
+ .select("*")
+ .match({"id": 2, "name": "Albania"})
+ .execute()
+ )
```
data:
sql: |
@@ -1620,54 +3466,95 @@ functions:
(3, 'Algeria');
```
response: |
- ```
- APIResponse(data=[{'id': 2, 'name': 'Albania'}], count=None)
+ ```json
+ {
+ "data": [
+ {
+ "id": 2,
+ "name": "Albania"
+ }
+ ],
+ "count": null
+ }
```
hideCodeBlock: true
isSpotlight: true
- id: not
title: not_()
+ description: |
+ Match only rows which doesn't satisfy the filter. `not_` expects you to use the raw PostgREST syntax for the filter values.
+ notes: |
+ ```python
+ .not_.in_('id', '(5,6,7)') # Use `()` for `in` filter
+ .not_.contains('arraycol', '{"a","b"}') # Use `{}` for array values
+ ```
examples:
- id: with-select
name: With `select()`
code: |
```python
- data, count = supabase.table('countries')
- .select('*')
- .not_.is_('name', 'null')
+ response = (
+ supabase.table("countries")
+ .select("*")
+ .not_.is_("name", "null")
.execute()
+ )
```
data:
- sql: |
- ```sql
- create table
- countries (id int8 primary key, name text);
+ sql: |
+ ```sql
+ create table
+ countries (id int8 primary key, name text);
- insert into
- countries (id, name)
- values
- (1, 'Albania'),
- (2, null);
- ```
+ insert into
+ countries (id, name)
+ values
+ (1, 'Albania'),
+ (2, null);
+ ```
response: |
- ```
- APIResponse(data=[{'id': 2, 'name': 'Albania'}], count=None)
+ ```json
+ {
+ "data": [
+ {
+ "id": 1,
+ "name": "Albania"
+ }
+ ],
+ "count": null
+ }
```
hideCodeBlock: true
isSpotlight: true
- - id: filter
- title: filter()
+ - id: or
+ title: or_()
+ params:
+ - name: filters
+ isOptional: false
+ type: string
+ description: The filters to use, following PostgREST syntax
+ - name: reference_table
+ isOptional: true
+ type: string
+ description: Set this to filter on referenced tables instead of the parent table
notes: |
- filter() expects you to use the raw PostgREST syntax for the filter values.
+ or_() expects you to use the raw PostgREST syntax for the filter names and values.
+
+ ```python
+ .or_('id.in.(5,6,7), arraycol.cs.{"a","b"}') # Use `()` for `in` filter, `{}` for array values and `cs` for `contains()`.
+ .or_('id.in.(5,6,7), arraycol.cd.{"a","b"}') # Use `cd` for `containedBy()`
+ ```
examples:
- id: with-select
name: With `select()`
code: |
```python
- data, count = supabase.table('countries')
- .select('*')
- .filter('name', 'in', '("Algeria","Japan")')
+ response = (
+ supabase.table("countries")
+ .select("name")
+ .or_("id.eq.2,name.eq.Algeria")
.execute()
+ )
```
data:
sql: |
@@ -1683,19 +3570,67 @@ functions:
(3, 'Algeria');
```
response: |
- ```
- APIResponse(data=[{'id': 3, 'name': 'Algeria'}], count=None)
+ ```json
+ {
+ "data": [
+ {
+ "name": "Albania"
+ },
+ {
+ "name": "Algeria"
+ }
+ ],
+ "count": null
+ }
```
hideCodeBlock: true
isSpotlight: true
- - id: on-a-foreign-table
- name: On a foreign table
+ - id: use-or-with-and
+ name: Use `or` with `and`
code: |
```python
- data, count = supabase.table('countries')
- .select('name, cities!inner (name)')
- .filter('cities.name', 'eq', 'Bali')
+ response = (
+ supabase.table("countries")
+ .select("name")
+ .or_("id.gt.3,and(id.eq.1,name.eq.Afghanistan)")
.execute()
+ )
+ ```
+ data:
+ sql: |
+ ```sql
+ create table
+ countries (id int8 primary key, name text);
+
+ insert into
+ countries (id, name)
+ values
+ (1, 'Afghanistan'),
+ (2, 'Albania'),
+ (3, 'Algeria');
+ ```
+ reponse: |
+ ```json
+ {
+ "data": [
+ {
+ "name": "Afghanistan"
+ }
+ ],
+ "count": null
+ }
+ ```
+ hideCodeBlock: true
+ - id: use-or-on-referenced-tables
+ name: Use `or` on referenced tables
+ code: |
+ ```python
+ response = (
+ supabase.table("countries")
+ .select("name, cities!inner(name)")
+ .or_("country_id.eq.1,name.eq.Beijing", reference_table="cities")
+ .execute()
+ )
```
data:
sql: |
@@ -1721,34 +3656,56 @@ functions:
(2, 1, 'Munich');
```
response: |
- ```
- APIResponse(data=[{'name': 'Indonesia', 'cities': [{'name': 'Bali'}]}], count=None)
+ ```json
+ {
+ "data": [
+ {
+ "name": "Germany",
+ "cities": [
+ {
+ "name": "Munich"
+ }
+ ]
+ }
+ ],
+ "count": null
+ }
```
hideCodeBlock: true
+
+ - id: filter
+ title: filter()
+ params:
+ - name: column
+ isOptional: false
+ type: string
+ description: The column to filter on
+ - name: operator
+ isOptional: true
+ type: string
+ description: The operator to filter with, following PostgREST syntax
+ - name: value
+ isOptional: true
+ type: any
+ description: The value to filter with, following PostgREST syntax
+ notes: |
+ filter() expects you to use the raw PostgREST syntax for the filter values.
- - 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).
-
- 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: order
- title: order()
+ ```python
+ .filter('id', 'in', '(5,6,7)') # Use `()` for `in` filter
+ .filter('arraycol', 'cs', '{"a","b"}') # Use `cs` for `contains()`, `{}` for array values
+ ```
examples:
- id: with-select
name: With `select()`
code: |
```python
- data, count = supabase.table('countries')
- .select('*')
- .order('name', desc=True)
- .execute()
+ response = (
+ supabase.table("countries")
+ .select("*")
+ .filter("name", "in", '("Algeria","Japan")')
+ .execute()
+ )
```
data:
sql: |
@@ -1764,14 +3721,16 @@ functions:
(3, 'Algeria');
```
response: |
- ```
- APIResponse(
- data=[
- {'id': 1, 'name': None},
- {'id': 3, 'name': 'Algeria'},
- {'id': 2, 'name': 'Albania'}],
- count=None
- )
+ ```json
+ {
+ "data": [
+ {
+ "id": 3,
+ "name": "Algeria"
+ }
+ ],
+ "count": null
+ }
```
hideCodeBlock: true
isSpotlight: true
@@ -1779,10 +3738,142 @@ functions:
name: On a foreign table
code: |
```python
- data, count = supabase.table('countries')
- .select('name, cities(name)')
- .order('name', desc=True, foreign_table='cities')
+ response = (
+ supabase.table("countries")
+ .select("name, cities!inner(name)")
+ .filter("cities.name", "eq", "Bali")
.execute()
+ )
+ ```
+ data:
+ sql: |
+ ```sql
+ create table
+ countries (id int8 primary key, name text);
+ create table
+ cities (
+ id int8 primary key,
+ country_id int8 not null references countries,
+ name text
+ );
+
+ insert into
+ countries (id, name)
+ values
+ (1, 'Germany'),
+ (2, 'Indonesia');
+ insert into
+ cities (id, country_id, name)
+ values
+ (1, 2, 'Bali'),
+ (2, 1, 'Munich');
+ ```
+ response: |
+ ```json
+ {
+ "data": [
+ {
+ "name": "Indonesia",
+ "cities": [
+ {
+ "name": "Bali"
+ }
+ ]
+ }
+ ],
+ "count": null
+ }
+ ```
+ hideCodeBlock: true
+ - 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).
+
+ 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: order
+ title: order()
+ description: Order the query result by `column`.
+ params:
+ - name: column
+ isOptional: false
+ type: string
+ description: The column to order by
+ - name: desc
+ isOptional: true
+ type: bool
+ description: Whether the rows should be ordered in descending order or not.
+ - name: foreign_table
+ isOptional: true
+ type: string
+ description: Foreign table name whose results are to be ordered.
+ - name: nullsfirst
+ isOptional: true
+ type: bool
+ description: Order by showing nulls first
+ examples:
+ - id: with-select
+ name: With `select()`
+ code: |
+ ```python
+ response = (
+ supabase.table("countries")
+ .select("*")
+ .order("name", desc=True)
+ .execute()
+ )
+ ```
+ data:
+ sql: |
+ ```sql
+ create table
+ countries (id int8 primary key, name text);
+
+ insert into
+ countries (id, name)
+ values
+ (1, 'Afghanistan'),
+ (2, 'Albania'),
+ (3, 'Algeria');
+ ```
+ response: |
+ ```json
+ {
+ "data": [
+ {
+ "id": 1,
+ "name": "Afghanistan"
+ },
+ {
+ "id": 2,
+ "name": "Albania"
+ },
+ {
+ "id": 3,
+ "name": "Algeria"
+ }
+ ],
+ "count": null
+ }
+ ```
+ hideCodeBlock: true
+ isSpotlight: true
+ - id: on-a-foreign-table
+ name: On a foreign table
+ code: |
+ ```python
+ response = (
+ supabase.table("countries")
+ .select("name, cities(name)")
+ .order("name", desc=True, foreign_table="cities")
+ .execute()
+ )
```
data:
sql: |
@@ -1806,8 +3897,27 @@ functions:
(1, 1, 'Atlanta'),
(2, 1, 'New York City');
response: |
- ```
- APIResponse(data=[{'name': 'United States', 'cities': [{'name': 'New York City'}, {'name': 'Atlanta'}]}, {'name': 'Vanuatu', 'cities': []}], count=None)
+ ```json
+ {
+ "data": [
+ {
+ "name": "United States",
+ "cities": [
+ {
+ "name": "New York City"
+ },
+ {
+ "name": "Atlanta"
+ }
+ ]
+ },
+ {
+ "name": "Vanuatu",
+ "cities": []
+ }
+ ],
+ "count": null
+ }
```
description: |
Ordering on foreign tables doesn't affect the ordering of
@@ -1815,15 +3925,21 @@ functions:
hideCodeBlock: true
- id: limit
title: limit()
+ params:
+ - name: size
+ isOptional: false
+ type: number
+ description: The maximum number of rows to return
+ - name: foreign_table
+ isOptional: true
+ type: string
+ description: Set this to limit rows of foreign tables instead of the parent table.
examples:
- id: with-select
name: With `select()`
code: |
```python
- data, count = supabase.table('countries')
- .select('*')
- .limit(1)
- .execute()
+ response = supabase.table("countries").select("name").limit(1).execute()
```
data:
sql: |
@@ -1839,8 +3955,15 @@ functions:
(3, 'Algeria');
```
response: |
- ```
- APIResponse(data=[{'id': 1, 'name': 'Afghanistan'}], count=None)
+ ```json
+ {
+ "data": [
+ {
+ "name": "Afghanistan"
+ }
+ ],
+ "count": null
+ }
```
hideCodeBlock: true
isSpotlight: true
@@ -1848,10 +3971,12 @@ functions:
name: On a foreign table
code: |
```python
- data, count = supabase.table('countries')
- .select('name, cities(name)')
- .limit(1, foreign_table='cities')
+ response = (
+ supabase.table("countries")
+ .select("name, cities(name)")
+ .limit(1, foreign_table="cities")
.execute()
+ )
```
data:
sql: |
@@ -1876,54 +4001,301 @@ functions:
(2, 1, 'New York City');
```
response: |
- ```
- APIResponse(data=[{'name': 'United States', 'cities': [{'name': 'Atlanta'}]}], count=None)
+ ```json
+ {
+ "data": [
+ {
+ "name": "United States",
+ "cities": [
+ {
+ "name": "Atlanta"
+ }
+ ]
+ }
+ ],
+ "count": null
+ }
```
hideCodeBlock: true
- - id: single
- title: single()
- examples:
- - id: with-select()
- name: With `select()`
- code: |
- ```python
- data, count = supabase.table('countries')
- .select('name')
- .limit(1)
- .single()
- .execute()
- ```
- data:
- sql: |
- ```sql
- create table
- countries (id int8 primary key, name text);
-
- insert into
- countries (id, name)
- values
- (1, 'Afghanistan'),
- (2, 'Albania'),
- (3, 'Algeria');
- ```
- response: |
- ```
- SingleAPIResponse(data={'name': 'Afghanistan'}, count=None)
- ```
- hideCodeBlock: true
- isSpotlight: true
- - id: maybe-single
- title: maybe_single()
+ - id: range
+ title: range()
+ params:
+ - name: start
+ isOptional: false
+ type: number
+ description: The starting index from which to limit the result.
+ - name: end
+ isOptional: false
+ type: number
+ description: The last index to which to limit the result.
+ - name: foreign_table
+ isOptional: true
+ type: string
+ description: Set this to limit rows of foreign tables instead of the parent table.
+ notes: |
+ Limit the query result by starting at an offset (`from`) and ending at the offset (`from + to`). Only records within this range are returned. This respects the query order and if there is no order clause the range could behave unexpectedly.
+
+ The `from` and `to` values are 0-based and inclusive: `range(1, 3)` will include the second, third and fourth rows of the query.
examples:
- id: with-select
name: With `select()`
code: |
```python
- data, count = supabase.table('countries')
- .select('*')
- .eq('name', 'Albania')
- .maybe_single()
- .execute()
+ response = supabase.table("countries").select("name").range(0, 1).execute()
+ ```
+ data:
+ sql: |
+ ```sql
+ create table
+ countries (id int8 primary key, name text);
+
+ insert into
+ countries (id, name)
+ values
+ (1, 'Afghanistan'),
+ (2, 'Albania'),
+ (3, 'Algeria');
+ ```
+ response: |
+ ```json
+ {
+ "data": [
+ {
+ "name": "Afghanistan"
+ },
+ {
+ "name": "Albania"
+ }
+ ],
+ "count": null
+ }
+ ```
+ hideCodeBlock: true
+ isSpotlight: true
+ - id: on-a-foreign-table
+ name: On a foreign table
+ code: |
+ ```python
+ response = (
+ supabase.table("countries")
+ .select("name, cities(name)")
+ .range(0, 1, foreign_table="cities")
+ .execute()
+ )
+ ```
+ data:
+ sql: |
+ ```sql
+ create table
+ countries (id int8 primary key, name text);
+ create table
+ cities (
+ id int8 primary key,
+ country_id int8 not null references countries,
+ name text
+ );
+
+ insert into
+ countries (id, name)
+ values
+ (1, 'Afghanistan'),
+ (2, 'Albania'),
+ (3, 'Algeria');
+ insert into
+ cities (id, country_id, name)
+ values
+ (1, 1, 'Kabul'),
+ (2, 1, 'Herat'),
+ (3, 2, 'Berat');
+ ```
+ response: |
+ ```json
+ {
+ "data": [
+ {
+ "name": "Afghanistan",
+ "cities": [
+ {
+ "name": "Kabul"
+ },
+ {
+ "name": "Herat"
+ }
+ ]
+ },
+ {
+ "name": "Albania",
+ "cities": [
+ {
+ "name": "Berat"
+ }
+ ]
+ },
+ {
+ "name": "Algeria",
+ "cities": []
+ }
+ ],
+ "count": null
+ }
+ ```
+ hideCodeBlock: true
+ - id: single
+ title: single()
+ notes: Return `data` as a single object instead of an array of objects.
+ examples:
+ - id: with-select()
+ name: With `select()`
+ code: |
+ ```python
+ response = supabase.table("countries").select("name").limit(1).single().execute()
+ ```
+ data:
+ sql: |
+ ```sql
+ create table
+ countries (id int8 primary key, name text);
+
+ insert into
+ countries (id, name)
+ values
+ (1, 'Afghanistan'),
+ (2, 'Albania'),
+ (3, 'Algeria');
+ ```
+ response: |
+ ```json
+ {
+ "data": {
+ "name": "Afghanistan"
+ },
+ "count": null
+ }
+ ```
+ hideCodeBlock: true
+ isSpotlight: true
+ - id: maybe-single
+ title: maybe_single()
+ notes: Return `data` as a single object instead of an array of objects.
+ examples:
+ - id: with-select
+ name: With `select()`
+ code: |
+ ```python
+ response = (
+ supabase.table("countries")
+ .select("*")
+ .eq("name", "Albania")
+ .maybe_single()
+ .execute()
+ )
+ ```
+ data:
+ sql: |
+ ```sql
+ create table
+ countries (id int8 primary key, name text);
+
+ insert into
+ countries (id, name)
+ values
+ (1, 'Afghanistan'),
+ (2, 'Albania'),
+ (3, 'Algeria');
+ ```
+ response: |
+ ```json
+ {
+ "data": {
+ "id": 2,
+ "name": "Albania"
+ },
+ "count": null
+ }
+ ```
+ hideCodeBlock: true
+ isSpotlight: true
+
+ - id: csv
+ title: csv()
+ notes: Return `data` as a string in CSV format.
+ examples:
+ - id: return-data-as-csv
+ name: Return data as CSV
+ code: |
+ ```python
+ response = supabase.table("countries").select("*").csv().execute()
+ ```
+ data:
+ sql: |
+ ```sql
+ create table
+ countries (id int8 primary key, name text);
+
+ insert into
+ countries (id, name)
+ values
+ (1, 'Afghanistan'),
+ (2, 'Albania'),
+ (3, 'Algeria');
+ ```
+ response: |
+ ```json
+ {
+ "data": "id,name\n1,Afghanistan\n2,Albania\n3,Algeria",
+ "count": null
+ }
+ ```
+ description: |
+ By default, the data is returned in JSON format, but can also be returned as Comma Separated Values.
+ hideCodeBlock: true
+ isSpotlight: true
+
+ - id: explain
+ title: Using Explain
+ params:
+ - name: wal
+ isOptional: true
+ type: boolean
+ description: If `true`, include information on WAL record generation.
+ - name: verbose
+ isOptional: true
+ type: boolean
+ description: If `true`, the query identifier will be returned and `data` will include the output columns of the query.
+ - name: settings
+ isOptional: true
+ type: boolean
+ description: If `true`, include information on configuration parameters that affect query planning.
+ - name: format
+ isOptional: true
+ type: boolean
+ description: The format of the output, can be `"text"` (default) or `"json"`.
+ - name: format
+ isOptional: true
+ type: '"text" | "json"'
+ description: The format of the output, can be `"text"` (default) or `"json"`.
+ - name: buffers
+ isOptional: true
+ type: boolean
+ description: If `true`, include information on buffer usage.
+ - name: analyze
+ isOptional: true
+ type: boolean
+ description: If `true`, the query will be executed and the actual run time will be returned.
+ description: |
+ For debugging slow queries, you can get the [Postgres `EXPLAIN` execution plan](https://www.postgresql.org/docs/current/sql-explain.html) of a query
+ using the `explain()` method. This works on any query, even for `rpc()` or writes.
+
+ Explain is not enabled by default as it can reveal sensitive information about your database.
+ It's best to only enable this for testing environments but if you wish to enable it for production you can provide additional protection by using a `pre-request` function.
+
+ Follow the [Performance Debugging Guide](/docs/guides/database/debugging-performance) to enable the functionality on your project.
+ examples:
+ - id: get-execution-plan
+ name: Get the execution plan
+ code: |
+ ```python
+ response = supabase.table("countries").select("*").explain().execute()
```
data:
sql: |
@@ -1940,11 +4312,56 @@ functions:
```
response: |
```
- SingleAPIResponse(data={'id': 2, 'name': 'Albania'}, count=None)
+ Aggregate (cost=33.34..33.36 rows=1 width=112)
+ -> Limit (cost=0.00..18.33 rows=1000 width=40)
+ -> Seq Scan on countries (cost=0.00..22.00 rows=1200 width=40)
```
+ description: |
+ By default, the data is returned in TEXT format, but can also be returned as JSON by using the `format` parameter.
hideCodeBlock: true
isSpotlight: true
+ - id: get-execution-plan-with-analyze-and-verbose
+ name: Get the execution plan with analyze and verbose
+ code: |
+ ```python
+ response = (
+ supabase.table("countries")
+ .select("*")
+ .explain(analyze=True, verbose=True)
+ .execute()
+ )
+ ```
+ data:
+ sql: |
+ ```sql
+ create table
+ countries (id int8 primary key, name text);
+
+ insert into
+ countries (id, name)
+ values
+ (1, 'Afghanistan'),
+ (2, 'Albania'),
+ (3, 'Algeria');
+ ```
+ response: |
+ ```
+ Aggregate (cost=33.34..33.36 rows=1 width=112) (actual time=0.041..0.041 rows=1 loops=1)
+ Output: NULL::bigint, count(ROW(countries.id, countries.name)), COALESCE(json_agg(ROW(countries.id, countries.name)), '[]'::json), NULLIF(current_setting('response.headers'::text, true), ''::text), NULLIF(current_setting('response.status'::text, true), ''::text)
+ -> Limit (cost=0.00..18.33 rows=1000 width=40) (actual time=0.005..0.006 rows=3 loops=1)
+ Output: countries.id, countries.name
+ -> Seq Scan on public.countries (cost=0.00..22.00 rows=1200 width=40) (actual time=0.004..0.005 rows=3 loops=1)
+ Output: countries.id, countries.name
+ Query Identifier: -4730654291623321173
+ Planning Time: 0.407 ms
+ Execution Time: 0.119 ms
+ ```
+ description: |
+ By default, the data is returned in TEXT format, but can also be returned as JSON by using the `format` parameter.
+ hideCodeBlock: true
+ isSpotlight: false
+
- id: invoke
title: 'invoke()'
description: |
@@ -1958,11 +4375,8 @@ functions:
description:
code: |
```python
- resp = supabase.functions.invoke(
- "hello-world",
- invoke_options={
- "body": { "foo": "bar" }
- },
+ response = supabase.functions.invoke(
+ "hello-world", invoke_options={"body": {"name": "Functions"}}
)
```
- id: error-handling
@@ -1978,7 +4392,7 @@ functions:
from supafunc.errors import FunctionsRelayError, FunctionsHttpError
try:
- resp = supabase.functions.invoke(
+ response = supabase.functions.invoke(
"hello-world",
invoke_options={
"body": {"foo": "bar"},
@@ -2001,7 +4415,7 @@ functions:
isSpotlight: true
code: |
```python
- resp = supabase.functions.invoke(
+ response = supabase.functions.invoke(
"hello-world",
invoke_options={
"headers": {
diff --git a/apps/docs/spec/supabase_swift_v2.yml b/apps/docs/spec/supabase_swift_v2.yml
index 1d645bcaeb7..e98c309698c 100644
--- a/apps/docs/spec/supabase_swift_v2.yml
+++ b/apps/docs/spec/supabase_swift_v2.yml
@@ -49,11 +49,31 @@ functions:
)
)
```
+ - id: api-schemas
+ name: With custom schemas
+ code: |
+ ```swift
+ let supabase = SupabaseClient(
+ supabaseURL: URL(string: "https://xyzcompany.supabase.co")!,
+ supabaseKey: "public-anon-key",
+ options: SupabaseClientOptions(
+ db: .init(
+ // Provide a custom schema. Defaults to "public".
+ schema: "other_schema"
+ )
+ )
+ )
+ ```
+ description: |
+ By default the API server points to the `public` schema. You can enable other database schemas within the Dashboard.
+ Go to [Settings > API > Exposed schemas](/dashboard/project/_/settings/api) and add the schema which you want to expose to the API.
+
+ Note: 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: auth-api
title: "Overview"
notes: |
The auth methods can be accessed via the `supabase.auth` namespace.
-
+
### Handling deep links
#### UIKit app lifecycle
@@ -100,7 +120,7 @@ functions:
supabase.auth.handle(url)
}
```
-
+
examples:
- id: create-auth-client
name: Create auth client
@@ -138,6 +158,32 @@ functions:
- 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.
- When either **Confirm email** or **Confirm phone** (even when phone provider is disabled) is disabled, the error message, `User already registered` is returned.
- To fetch the currently logged-in user, refer to [`getUser()`](/docs/reference/swift/get-user).
+ overwriteParams:
+ - name: email
+ isOptional: true
+ type: String
+ description: One of `email` or `phone` must be provided.
+ - name: phone
+ isOptional: true
+ type: String
+ description: One of `email` or `phone` must be provided.
+ - name: password
+ type: String
+ - name: data
+ isOptional: true
+ type: JSONObject
+ description: >
+ A custom data object to store additional user metadata.
+ - name: redirectTo
+ isOptional: true
+ type: URL
+ description: >
+ Only for email signups.
+ The redirect URL embedded in the email link.
+ Must be a configured redirect URL for your Supabase instance.
+ - name: captchaToken
+ isOptional: true
+ type: String
examples:
- id: sign-up
name: Sign up with email and password
@@ -232,7 +278,6 @@ functions:
- `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).
-
examples:
- id: listen-to-auth-changes
name: Listen to auth changes
@@ -292,6 +337,20 @@ functions:
title: "signInWithPassword()"
notes: |
- Requires either an email and password or a phone number and password.
+ overwriteParams:
+ - name: email
+ isOptional: true
+ type: String
+ description: One of `email` or `phone` must be provided.
+ - name: phone
+ isOptional: true
+ type: String
+ description: One of `email` or `phone` must be provided.
+ - name: password
+ type: String
+ - name: captchaToken
+ isOptional: true
+ type: String
examples:
- id: sign-in-with-email-and-password
name: Sign in with email and password
@@ -322,6 +381,42 @@ functions:
```
- id: sign-in-with-otp
title: "signInWithOTP()"
+ overwriteParams:
+ - name: email
+ isOptional: true
+ type: String
+ description: One of `email` or `phone` must be provided.
+ - name: phone
+ isOptional: true
+ type: String
+ description: One of `email` or `phone` must be provided.
+ - name: redirectTo
+ isOptional: true
+ type: String
+ description: >
+ Only for email signups.
+ The redirect URL embedded in the email link.
+ Must be a configured redirect URL for your Supabase instance.
+ - name: channel
+ isOptional: true
+ type: MessagingChannel
+ description: >
+ The channel to use for sending messages.
+ Only for phone signups.
+ - name: shouldCreateUser
+ isOptional: true
+ type: Bool
+ description: >
+ Whether to create the user if they don't already exist.
+ Defaults to true.
+ - name: data
+ isOptional: true
+ type: JSONObject
+ description: >
+ A custom data object to store additional user metadata.
+ - name: captchaToken
+ isOptional: true
+ type: String
notes: |
- Requires either an email or phone number.
- This method is used for passwordless sign-ins where a OTP is sent to the user's email or phone number.
@@ -365,6 +460,31 @@ functions:
```
- id: sign-in-with-oauth
title: "signInWithOAuth()"
+ overwriteParams:
+ - name: provider
+ type: Provider
+ description: >
+ The third-party provider.
+ - name: redirectTo
+ type: URL
+ isOptional: true
+ description: >
+ A URL to send the user to after they are confirmed.
+ - name: scopes
+ type: String
+ isOptional: true
+ description: >
+ A space-separated list of scopes granted to the OAuth application.
+ - name: queryParams
+ type: "[(name: String, value: String?)]"
+ isOptional: true
+ description: >
+ Additional query params.
+ - name: configure
+ type: Callback
+ isOptional: true
+ description: >
+ A custom configuration callback for opening the OAuth flow externally.
notes: |
- This method is used for signing in using a third-party provider.
- Supabase supports many different [third-party providers](https://supabase.com/docs/guides/auth#providers).
@@ -454,7 +574,27 @@ functions:
)
```
- id: sign-in-with-sso
- title: 'signInWithSSO()'
+ title: "signInWithSSO()"
+ overwriteParams:
+ - name: providerId
+ isOptional: true
+ type: String
+ description: >
+ UUID of the SSO provider.
+ One of `providerId` or `domain` is required.
+ - name: domain
+ isOptional: true
+ type: String
+ description: >
+ Domain name of the organization to use SSO with.
+ One of `providerId` or `domain` is required.
+ - name: redirectTo
+ type: String
+ description: >
+ The URL to redirect the user to after they have signed in.
+ Must be a configured redirect URL for your Supabase instance.
+ - name: captchaToken
+ type: String
notes: |
- 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.
- If you've associated an email domain to the identity provider, you can use the `domain` property to start a sign-in flow.
@@ -506,6 +646,37 @@ functions:
```
- id: verify-otp
title: "verifyOTP()"
+ overwriteParams:
+ - name: email
+ isOptional: true
+ type: String
+ description: One of `phone`, `email`, or `token_hash` must be provided.
+ - name: phone
+ isOptional: true
+ type: String
+ description: One of `phone`, `email`, or `token_hash` must be provided.
+ - name: token_hash
+ isOptional: true
+ type: String
+ description: >
+ The token hash from the user's email link.
+ One of `phone`, `email`, or `token_hash` must be provided.
+ - name: type
+ type: EmailOTPType | MobileOTPType
+ - name: token
+ isOptional: true
+ type: String
+ description: The OTP sent to the user. Required if using `phone` or `email`.
+ - name: redirectTo
+ isOptional: true
+ type: URL
+ description: >
+ A URL to redirect the user to after they are confirmed.
+ Must be in your configured redirect URLs.
+ - name: captchaToken
+ isOptional: true
+ type: String
+ description: Deprecated.
notes: |
- The `verifyOTP` method takes in different verification types. If a phone number is used, the type can either be `sms` or `phone_change`. If an email address is used, the type can be one of the following: `signup`, `magiclink`, `recovery`, `invite`, `email_change`, or `email`.
- The verification type used should be determined based on the corresponding auth method called before `verifyOTP` to sign up / sign-in a user.
@@ -596,6 +767,68 @@ functions:
```swift
try await supabase.auth.update(user: UserAttributes(email: "new@email.com"))
```
+ response: |
+ ```json
+ {
+ "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",
+ "new_email": "new@email.com",
+ "email_change_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
+ }
+ }
+ ```
+ - id: update-the-phone-for-an-authenticated-user
+ name: Update the phone number for an authenticated user
+ description: Sends a one-time password (OTP) to the new phone number.
+ isSpotlight: false
+ code: |
+ ```swift
+ try await supabase.auth.update(
+ user: UserAttributes(
+ phone: "123456789"
+ )
+ )
+ ```
- id: update-the-password-for-an-authenticated-user
name: Update the password for an authenticated user
isSpotlight: false
@@ -616,6 +849,20 @@ functions:
)
)
```
+ - id: update-password-with-reauthentication
+ name: Update the user's password with a nonce
+ 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.
+ isSpotlight: true
+ code: |
+ ```swift
+ try await supabase.auth.update(
+ user: UserAttributes(
+ password: "new password",
+ nonce: "123456"
+ )
+ )
+ ```
- id: get-user-identities
title: "userIdentities()"
notes: |
@@ -629,7 +876,7 @@ functions:
let identities = try await supabase.auth.userIdentities()
```
- id: link-identity
- title: 'linkIdentity()'
+ title: "linkIdentity()"
notes: |
- The **Enable Manual Linking** option must be enabled from your [project's authentication settings](/dashboard/project/_/settings/auth).
- The user needs to be signed in to call `linkIdentity()`.
@@ -657,7 +904,7 @@ functions:
}
```
- id: unlink-identity
- title: 'unlinkIdentity()'
+ title: "unlinkIdentity()"
notes: |
- The **Enable Manual Linking** option must be enabled from your [project's authentication settings](/dashboard/project/_/settings/auth).
- The user needs to be signed in to call `unlinkIdentity()`.
@@ -928,7 +1175,7 @@ functions:
let factors = try await supabase.auth.mfa.listFactors()
```
- id: admin-api
- title: 'Overview'
+ title: "Overview"
notes: |
- Any method under the `supabase.auth.admin` namespace requires a `service_role` key.
- These methods are considered admin methods and should be called on a trusted server. Never expose your `service_role` key in the browser.
@@ -949,7 +1196,7 @@ functions:
let adminAuthClient = supabase.auth.admin
```
- id: delete-user
- title: 'deleteUser()'
+ title: "deleteUser()"
notes: |
- The `deleteUser()` method requires the user's ID, which maps to the `auth.users.id` column.
examples:
@@ -1606,6 +1853,40 @@ functions:
If you don't want to return the foreign table contents, you can leave the parenthesis empty.
Like `.select('name, countries!inner()')`.
hideCodeBlock: true
+ - id: switching-schemas-per-query
+ name: Switching schemas per query
+ code: |
+ ```swift
+ try await supabase
+ .schema("myschema")
+ .from("mytable")
+ .select()
+ ```
+ data:
+ sql: |
+ ```sql
+ create schema myschema;
+
+ create table myschema.mytable (
+ id uuid primary key default gen_random_uuid(),
+ data text
+ );
+
+ insert into myschema.mytable (data) values ('mydata');
+ ```
+ response: |
+ ```json
+ [
+ {
+ "id": "4162e008-27b0-4c0f-82dc-ccaeee9a624d",
+ "data": "mydata"
+ }
+ ]
+ ```
+ description: |
+ In addition to setting the schema during initialization, you can also switch schemas on a per-query basis.
+ Make sure you've set up your [database privileges and API settings](/docs/guides/api/using-custom-schemas).
+ hideCodeBlock: true
- id: insert
title: "Create data: insert()"
diff --git a/apps/docs/spec/transforms/api_v1_openapi_deparsed.json b/apps/docs/spec/transforms/api_v1_openapi_deparsed.json
index d7520b69076..d2679ee2a5d 100644
--- a/apps/docs/spec/transforms/api_v1_openapi_deparsed.json
+++ b/apps/docs/spec/transforms/api_v1_openapi_deparsed.json
@@ -2,19 +2,55 @@
"openapi": "3.0.0",
"info": {
"title": "Supabase API (v1)",
- "description": "",
+ "description": "Supabase API generated from the OpenAPI specification. Visit [https://supabase.com/docs](https://supabase.com/docs) for a complete documentation.",
"version": "1.0.0",
"contact": {}
},
"servers": [],
"tags": [
{
- "name": "organizations",
- "description": "Organization endpoints"
+ "name": "Auth",
+ "description": "Auth related endpoints"
},
{
- "name": "projects",
- "description": "Project endpoints"
+ "name": "Database",
+ "description": "Database related endpoints"
+ },
+ {
+ "name": "Domains",
+ "description": "Domains related endpoints"
+ },
+ {
+ "name": "Edge Functions",
+ "description": "Edge related endpoints"
+ },
+ {
+ "name": "Environments",
+ "description": "Environments related endpoints"
+ },
+ {
+ "name": "OAuth",
+ "description": "OAuth related endpoints"
+ },
+ {
+ "name": "Organizations",
+ "description": "Organizations related endpoints"
+ },
+ {
+ "name": "Projects",
+ "description": "Projects related endpoints"
+ },
+ {
+ "name": "Rest",
+ "description": "Rest related endpoints"
+ },
+ {
+ "name": "Secrets",
+ "description": "Secrets related endpoints"
+ },
+ {
+ "name": "Storage",
+ "description": "Storage related endpoints"
}
],
"paths": {
@@ -60,10 +96,13 @@
"INACTIVE",
"INIT_FAILED",
"REMOVED",
- "RESTORING",
+ "RESTARTING",
"UNKNOWN",
"UPGRADING",
- "PAUSING"
+ "PAUSING",
+ "RESTORING",
+ "RESTORE_FAILED",
+ "PAUSE_FAILED"
],
"type": "string"
},
@@ -96,7 +135,7 @@
}
},
"tags": [
- "environments"
+ "Environments"
],
"security": [
{
@@ -220,7 +259,7 @@
}
},
"tags": [
- "environments"
+ "Environments"
],
"security": [
{
@@ -267,7 +306,7 @@
}
},
"tags": [
- "environments"
+ "Environments"
],
"security": [
{
@@ -316,7 +355,7 @@
}
},
"tags": [
- "environments"
+ "Environments"
],
"security": [
{
@@ -389,10 +428,13 @@
"INACTIVE",
"INIT_FAILED",
"REMOVED",
- "RESTORING",
+ "RESTARTING",
"UNKNOWN",
"UPGRADING",
- "PAUSING"
+ "PAUSING",
+ "RESTORING",
+ "RESTORE_FAILED",
+ "PAUSE_FAILED"
],
"type": "string"
}
@@ -412,7 +454,7 @@
}
},
"tags": [
- "projects"
+ "Projects"
],
"security": [
{
@@ -567,10 +609,13 @@
"INACTIVE",
"INIT_FAILED",
"REMOVED",
- "RESTORING",
+ "RESTARTING",
"UNKNOWN",
"UPGRADING",
- "PAUSING"
+ "PAUSING",
+ "RESTORING",
+ "RESTORE_FAILED",
+ "PAUSE_FAILED"
],
"type": "string"
}
@@ -589,7 +634,7 @@
}
},
"tags": [
- "projects"
+ "Projects"
],
"security": [
{
@@ -635,7 +680,7 @@
}
},
"tags": [
- "organizations"
+ "Organizations"
],
"security": [
{
@@ -693,7 +738,7 @@
}
},
"tags": [
- "organizations"
+ "Organizations"
],
"security": [
{
@@ -788,7 +833,7 @@
}
},
"tags": [
- "oauth"
+ "OAuth"
],
"security": [
{
@@ -882,7 +927,7 @@
}
},
"tags": [
- "oauth"
+ "OAuth"
],
"security": [
{
@@ -1022,7 +1067,7 @@
}
},
"tags": [
- "database"
+ "Database"
],
"security": [
{
@@ -1169,7 +1214,7 @@
}
},
"tags": [
- "database"
+ "Database"
],
"security": [
{
@@ -1226,7 +1271,7 @@
}
},
"tags": [
- "secrets"
+ "Secrets"
],
"security": [
{
@@ -1333,7 +1378,7 @@
}
},
"tags": [
- "environments"
+ "Environments"
],
"security": [
{
@@ -1459,7 +1504,7 @@
}
},
"tags": [
- "environments"
+ "Environments"
],
"security": [
{
@@ -1493,7 +1538,7 @@
}
},
"tags": [
- "environments"
+ "Environments"
],
"security": [
{
@@ -1541,7 +1586,121 @@
"type": "string"
},
"data": {
- "type": "object"
+ "type": "object",
+ "properties": {
+ "success": {
+ "type": "boolean"
+ },
+ "errors": {
+ "type": "array",
+ "items": {
+ "type": "object"
+ }
+ },
+ "messages": {
+ "type": "array",
+ "items": {
+ "type": "object"
+ }
+ },
+ "result": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "hostname": {
+ "type": "string"
+ },
+ "ssl": {
+ "type": "object",
+ "properties": {
+ "status": {
+ "required": true,
+ "type": "string"
+ },
+ "validation_records": {
+ "required": true,
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "txt_name": {
+ "type": "string"
+ },
+ "txt_value": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "txt_name",
+ "txt_value"
+ ]
+ }
+ },
+ "validation_errors": {
+ "required": false,
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "message": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "message"
+ ]
+ }
+ }
+ }
+ },
+ "ownership_verification": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "required": true,
+ "type": "string"
+ },
+ "name": {
+ "required": true,
+ "type": "string"
+ },
+ "value": {
+ "required": true,
+ "type": "string"
+ }
+ }
+ },
+ "custom_origin_server": {
+ "type": "string"
+ },
+ "verification_errors": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "status": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "id",
+ "hostname",
+ "ssl",
+ "ownership_verification",
+ "custom_origin_server",
+ "status"
+ ]
+ }
+ },
+ "required": [
+ "success",
+ "errors",
+ "messages",
+ "result"
+ ]
}
},
"required": [
@@ -1561,7 +1720,7 @@
}
},
"tags": [
- "domains"
+ "Domains"
],
"security": [
{
@@ -1597,7 +1756,7 @@
}
},
"tags": [
- "domains"
+ "Domains"
],
"security": [
{
@@ -1663,7 +1822,121 @@
"type": "string"
},
"data": {
- "type": "object"
+ "type": "object",
+ "properties": {
+ "success": {
+ "type": "boolean"
+ },
+ "errors": {
+ "type": "array",
+ "items": {
+ "type": "object"
+ }
+ },
+ "messages": {
+ "type": "array",
+ "items": {
+ "type": "object"
+ }
+ },
+ "result": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "hostname": {
+ "type": "string"
+ },
+ "ssl": {
+ "type": "object",
+ "properties": {
+ "status": {
+ "required": true,
+ "type": "string"
+ },
+ "validation_records": {
+ "required": true,
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "txt_name": {
+ "type": "string"
+ },
+ "txt_value": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "txt_name",
+ "txt_value"
+ ]
+ }
+ },
+ "validation_errors": {
+ "required": false,
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "message": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "message"
+ ]
+ }
+ }
+ }
+ },
+ "ownership_verification": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "required": true,
+ "type": "string"
+ },
+ "name": {
+ "required": true,
+ "type": "string"
+ },
+ "value": {
+ "required": true,
+ "type": "string"
+ }
+ }
+ },
+ "custom_origin_server": {
+ "type": "string"
+ },
+ "verification_errors": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "status": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "id",
+ "hostname",
+ "ssl",
+ "ownership_verification",
+ "custom_origin_server",
+ "status"
+ ]
+ }
+ },
+ "required": [
+ "success",
+ "errors",
+ "messages",
+ "result"
+ ]
}
},
"required": [
@@ -1683,7 +1956,7 @@
}
},
"tags": [
- "domains"
+ "Domains"
],
"security": [
{
@@ -1731,7 +2004,121 @@
"type": "string"
},
"data": {
- "type": "object"
+ "type": "object",
+ "properties": {
+ "success": {
+ "type": "boolean"
+ },
+ "errors": {
+ "type": "array",
+ "items": {
+ "type": "object"
+ }
+ },
+ "messages": {
+ "type": "array",
+ "items": {
+ "type": "object"
+ }
+ },
+ "result": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "hostname": {
+ "type": "string"
+ },
+ "ssl": {
+ "type": "object",
+ "properties": {
+ "status": {
+ "required": true,
+ "type": "string"
+ },
+ "validation_records": {
+ "required": true,
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "txt_name": {
+ "type": "string"
+ },
+ "txt_value": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "txt_name",
+ "txt_value"
+ ]
+ }
+ },
+ "validation_errors": {
+ "required": false,
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "message": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "message"
+ ]
+ }
+ }
+ }
+ },
+ "ownership_verification": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "required": true,
+ "type": "string"
+ },
+ "name": {
+ "required": true,
+ "type": "string"
+ },
+ "value": {
+ "required": true,
+ "type": "string"
+ }
+ }
+ },
+ "custom_origin_server": {
+ "type": "string"
+ },
+ "verification_errors": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "status": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "id",
+ "hostname",
+ "ssl",
+ "ownership_verification",
+ "custom_origin_server",
+ "status"
+ ]
+ }
+ },
+ "required": [
+ "success",
+ "errors",
+ "messages",
+ "result"
+ ]
}
},
"required": [
@@ -1751,7 +2138,7 @@
}
},
"tags": [
- "domains"
+ "Domains"
],
"security": [
{
@@ -1799,7 +2186,121 @@
"type": "string"
},
"data": {
- "type": "object"
+ "type": "object",
+ "properties": {
+ "success": {
+ "type": "boolean"
+ },
+ "errors": {
+ "type": "array",
+ "items": {
+ "type": "object"
+ }
+ },
+ "messages": {
+ "type": "array",
+ "items": {
+ "type": "object"
+ }
+ },
+ "result": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "hostname": {
+ "type": "string"
+ },
+ "ssl": {
+ "type": "object",
+ "properties": {
+ "status": {
+ "required": true,
+ "type": "string"
+ },
+ "validation_records": {
+ "required": true,
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "txt_name": {
+ "type": "string"
+ },
+ "txt_value": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "txt_name",
+ "txt_value"
+ ]
+ }
+ },
+ "validation_errors": {
+ "required": false,
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "message": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "message"
+ ]
+ }
+ }
+ }
+ },
+ "ownership_verification": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "required": true,
+ "type": "string"
+ },
+ "name": {
+ "required": true,
+ "type": "string"
+ },
+ "value": {
+ "required": true,
+ "type": "string"
+ }
+ }
+ },
+ "custom_origin_server": {
+ "type": "string"
+ },
+ "verification_errors": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "status": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "id",
+ "hostname",
+ "ssl",
+ "ownership_verification",
+ "custom_origin_server",
+ "status"
+ ]
+ }
+ },
+ "required": [
+ "success",
+ "errors",
+ "messages",
+ "result"
+ ]
}
},
"required": [
@@ -1819,7 +2320,7 @@
}
},
"tags": [
- "domains"
+ "Domains"
],
"security": [
{
@@ -1875,7 +2376,7 @@
}
},
"tags": [
- "projects"
+ "Projects"
],
"security": [
{
@@ -1934,7 +2435,7 @@
}
},
"tags": [
- "projects"
+ "Projects"
],
"security": [
{
@@ -2034,7 +2535,7 @@
}
},
"tags": [
- "projects"
+ "Projects"
],
"security": [
{
@@ -2158,7 +2659,7 @@
}
},
"tags": [
- "projects"
+ "Projects"
],
"security": [
{
@@ -2211,7 +2712,7 @@
}
},
"tags": [
- "secrets"
+ "Secrets"
],
"security": [
{
@@ -2280,7 +2781,7 @@
}
},
"tags": [
- "secrets"
+ "Secrets"
],
"security": [
{
@@ -2350,7 +2851,7 @@
}
},
"tags": [
- "rest"
+ "Rest"
],
"security": [
{
@@ -2443,7 +2944,7 @@
}
},
"tags": [
- "rest"
+ "Rest"
],
"security": [
{
@@ -2454,7 +2955,7 @@
},
"/v1/projects/{ref}": {
"delete": {
- "operationId": "v1-Delete a project",
+ "operationId": "v1-delete-a-project",
"summary": "Deletes the given project",
"parameters": [
{
@@ -2501,7 +3002,7 @@
}
},
"tags": [
- "projects"
+ "Projects"
],
"security": [
{
@@ -2562,7 +3063,7 @@
}
},
"tags": [
- "secrets"
+ "Secrets"
],
"security": [
{
@@ -2629,7 +3130,7 @@
}
},
"tags": [
- "secrets"
+ "Secrets"
],
"security": [
{
@@ -2686,7 +3187,7 @@
}
},
"tags": [
- "secrets"
+ "Secrets"
],
"security": [
{
@@ -2751,7 +3252,7 @@
}
},
"tags": [
- "database"
+ "Database"
],
"security": [
{
@@ -2840,7 +3341,7 @@
}
},
"tags": [
- "database"
+ "Database"
],
"security": [
{
@@ -2903,7 +3404,7 @@
}
},
"tags": [
- "database"
+ "Database"
],
"security": [
{
@@ -2964,7 +3465,7 @@
}
},
"tags": [
- "domains"
+ "Domains"
],
"security": [
{
@@ -3000,7 +3501,7 @@
}
},
"tags": [
- "domains"
+ "Domains"
],
"security": [
{
@@ -3071,7 +3572,7 @@
}
},
"tags": [
- "domains"
+ "Domains"
],
"security": [
{
@@ -3142,7 +3643,7 @@
}
},
"tags": [
- "domains"
+ "Domains"
],
"security": [
{
@@ -3213,7 +3714,7 @@
}
},
"tags": [
- "projects"
+ "Projects"
],
"security": [
{
@@ -3318,7 +3819,7 @@
}
},
"tags": [
- "projects"
+ "Projects"
],
"security": [
{
@@ -3361,6 +3862,9 @@
"initiated_at": {
"type": "string"
},
+ "latest_status_at": {
+ "type": "string"
+ },
"target_version": {
"type": "number"
},
@@ -3374,7 +3878,8 @@
"5_data_upgrade_completion_failed",
"6_volume_detachchment_from_original_instance_failed",
"7_volume_attachment_to_upgraded_instance_failed",
- "8_upgrade_completion_failed"
+ "8_upgrade_completion_failed",
+ "9_post_physical_backup_failed"
]
},
"progress": {
@@ -3389,7 +3894,8 @@
"6_completed_data_upgrade",
"7_detached_volume_from_original_instance",
"8_attached_volume_to_upgraded_instance",
- "9_completed_upgrade"
+ "9_completed_upgrade",
+ "10_completed_post_physical_backup"
]
},
"status": {
@@ -3403,6 +3909,7 @@
},
"required": [
"initiated_at",
+ "latest_status_at",
"target_version",
"status"
]
@@ -3425,7 +3932,7 @@
}
},
"tags": [
- "projects"
+ "Projects"
],
"security": [
{
@@ -3483,7 +3990,7 @@
}
},
"tags": [
- "database"
+ "Database"
],
"security": [
{
@@ -3518,7 +4025,7 @@
}
},
"tags": [
- "database"
+ "Database"
],
"security": [
{
@@ -3590,7 +4097,7 @@
}
},
"tags": [
- "database"
+ "Database"
],
"security": [
{
@@ -3643,7 +4150,7 @@
}
},
"tags": [
- "database"
+ "Database"
],
"security": [
{
@@ -3791,7 +4298,7 @@
}
},
"tags": [
- "projects"
+ "Projects"
],
"security": [
{
@@ -3894,7 +4401,7 @@
}
},
"tags": [
- "database"
+ "Database"
],
"security": [
{
@@ -4066,7 +4573,7 @@
}
},
"tags": [
- "database"
+ "Database"
],
"security": [
{
@@ -4130,7 +4637,7 @@
}
},
"tags": [
- "database"
+ "Database"
]
}
},
@@ -4228,7 +4735,7 @@
}
},
"tags": [
- "database"
+ "Database"
],
"security": [
{
@@ -4315,7 +4822,7 @@
}
},
"tags": [
- "database"
+ "Database"
],
"security": [
{
@@ -4537,6 +5044,18 @@
"type": "string",
"nullable": true
},
+ "external_slack_oidc_client_id": {
+ "type": "string",
+ "nullable": true
+ },
+ "external_slack_oidc_enabled": {
+ "type": "boolean",
+ "nullable": true
+ },
+ "external_slack_oidc_secret": {
+ "type": "string",
+ "nullable": true
+ },
"external_notion_client_id": {
"type": "string",
"nullable": true
@@ -4796,6 +5315,10 @@
"type": "number",
"nullable": true
},
+ "rate_limit_otp": {
+ "type": "number",
+ "nullable": true
+ },
"refresh_token_rotation_enabled": {
"type": "boolean",
"nullable": true
@@ -4804,6 +5327,10 @@
"type": "boolean",
"nullable": true
},
+ "saml_external_url": {
+ "type": "string",
+ "nullable": true
+ },
"security_captcha_enabled": {
"type": "boolean",
"nullable": true
@@ -5016,6 +5543,9 @@
"external_linkedin_oidc_client_id",
"external_linkedin_oidc_enabled",
"external_linkedin_oidc_secret",
+ "external_slack_oidc_client_id",
+ "external_slack_oidc_enabled",
+ "external_slack_oidc_secret",
"external_notion_client_id",
"external_notion_enabled",
"external_notion_secret",
@@ -5081,8 +5611,10 @@
"rate_limit_sms_sent",
"rate_limit_token_refresh",
"rate_limit_verify",
+ "rate_limit_otp",
"refresh_token_rotation_enabled",
"saml_enabled",
+ "saml_external_url",
"security_captcha_enabled",
"security_captcha_provider",
"security_captcha_secret",
@@ -5137,7 +5669,7 @@
}
},
"tags": [
- "auth"
+ "Auth"
],
"security": [
{
@@ -5265,6 +5797,10 @@
"saml_enabled": {
"type": "boolean"
},
+ "saml_external_url": {
+ "type": "string",
+ "pattern": "/^[^,]+$/"
+ },
"security_captcha_enabled": {
"type": "boolean"
},
@@ -5314,6 +5850,11 @@
"minimum": 1,
"maximum": 2147483647
},
+ "rate_limit_otp": {
+ "type": "number",
+ "minimum": 1,
+ "maximum": 2147483647
+ },
"mailer_secure_email_change_enabled": {
"type": "boolean"
},
@@ -5602,6 +6143,15 @@
"external_linkedin_oidc_secret": {
"type": "string"
},
+ "external_slack_oidc_enabled": {
+ "type": "boolean"
+ },
+ "external_slack_oidc_client_id": {
+ "type": "string"
+ },
+ "external_slack_oidc_secret": {
+ "type": "string"
+ },
"external_notion_enabled": {
"type": "boolean"
},
@@ -5875,6 +6425,18 @@
"type": "string",
"nullable": true
},
+ "external_slack_oidc_client_id": {
+ "type": "string",
+ "nullable": true
+ },
+ "external_slack_oidc_enabled": {
+ "type": "boolean",
+ "nullable": true
+ },
+ "external_slack_oidc_secret": {
+ "type": "string",
+ "nullable": true
+ },
"external_notion_client_id": {
"type": "string",
"nullable": true
@@ -6134,6 +6696,10 @@
"type": "number",
"nullable": true
},
+ "rate_limit_otp": {
+ "type": "number",
+ "nullable": true
+ },
"refresh_token_rotation_enabled": {
"type": "boolean",
"nullable": true
@@ -6142,6 +6708,10 @@
"type": "boolean",
"nullable": true
},
+ "saml_external_url": {
+ "type": "string",
+ "nullable": true
+ },
"security_captcha_enabled": {
"type": "boolean",
"nullable": true
@@ -6354,6 +6924,9 @@
"external_linkedin_oidc_client_id",
"external_linkedin_oidc_enabled",
"external_linkedin_oidc_secret",
+ "external_slack_oidc_client_id",
+ "external_slack_oidc_enabled",
+ "external_slack_oidc_secret",
"external_notion_client_id",
"external_notion_enabled",
"external_notion_secret",
@@ -6419,8 +6992,10 @@
"rate_limit_sms_sent",
"rate_limit_token_refresh",
"rate_limit_verify",
+ "rate_limit_otp",
"refresh_token_rotation_enabled",
"saml_enabled",
+ "saml_external_url",
"security_captcha_enabled",
"security_captcha_provider",
"security_captcha_secret",
@@ -6475,7 +7050,371 @@
}
},
"tags": [
- "auth"
+ "Auth"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/v1/projects/{ref}/config/auth/third-party-auth": {
+ "post": {
+ "operationId": "createTPAForProject",
+ "summary": "[Alpha] Creates a new third-party auth integration",
+ "parameters": [
+ {
+ "name": "ref",
+ "required": true,
+ "in": "path",
+ "description": "Project ref",
+ "schema": {
+ "minLength": 20,
+ "maxLength": 20,
+ "type": "string"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "oidc_issuer_url": {
+ "type": "string"
+ },
+ "jwks_url": {
+ "type": "string"
+ },
+ "custom_jwks": {
+ "type": "object"
+ }
+ }
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "type": {
+ "type": "string"
+ },
+ "oidc_issuer_url": {
+ "type": "string",
+ "nullable": true
+ },
+ "jwks_url": {
+ "type": "string",
+ "nullable": true
+ },
+ "custom_jwks": {
+ "type": "object",
+ "nullable": true
+ },
+ "resolved_jwks": {
+ "type": "object",
+ "nullable": true
+ },
+ "inserted_at": {
+ "type": "string"
+ },
+ "updated_at": {
+ "type": "string"
+ },
+ "resolved_at": {
+ "type": "string",
+ "nullable": true
+ }
+ },
+ "required": [
+ "id",
+ "type",
+ "inserted_at",
+ "updated_at"
+ ]
+ }
+ }
+ }
+ },
+ "403": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "Auth"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ },
+ "get": {
+ "operationId": "listTPAForProject",
+ "summary": "[Alpha] Lists all third-party auth integrations",
+ "parameters": [
+ {
+ "name": "ref",
+ "required": true,
+ "in": "path",
+ "description": "Project ref",
+ "schema": {
+ "minLength": 20,
+ "maxLength": 20,
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "type": {
+ "type": "string"
+ },
+ "oidc_issuer_url": {
+ "type": "string",
+ "nullable": true
+ },
+ "jwks_url": {
+ "type": "string",
+ "nullable": true
+ },
+ "custom_jwks": {
+ "type": "object",
+ "nullable": true
+ },
+ "resolved_jwks": {
+ "type": "object",
+ "nullable": true
+ },
+ "inserted_at": {
+ "type": "string"
+ },
+ "updated_at": {
+ "type": "string"
+ },
+ "resolved_at": {
+ "type": "string",
+ "nullable": true
+ }
+ },
+ "required": [
+ "id",
+ "type",
+ "inserted_at",
+ "updated_at"
+ ]
+ }
+ }
+ }
+ }
+ },
+ "403": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "Auth"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
+ },
+ "/v1/projects/{ref}/config/auth/third-party-auth/{tpa_id}": {
+ "delete": {
+ "operationId": "deleteTPAForProject",
+ "summary": "[Alpha] Removes a third-party auth integration",
+ "parameters": [
+ {
+ "name": "ref",
+ "required": true,
+ "in": "path",
+ "description": "Project ref",
+ "schema": {
+ "minLength": 20,
+ "maxLength": 20,
+ "type": "string"
+ }
+ },
+ {
+ "name": "tpa_id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "type": {
+ "type": "string"
+ },
+ "oidc_issuer_url": {
+ "type": "string",
+ "nullable": true
+ },
+ "jwks_url": {
+ "type": "string",
+ "nullable": true
+ },
+ "custom_jwks": {
+ "type": "object",
+ "nullable": true
+ },
+ "resolved_jwks": {
+ "type": "object",
+ "nullable": true
+ },
+ "inserted_at": {
+ "type": "string"
+ },
+ "updated_at": {
+ "type": "string"
+ },
+ "resolved_at": {
+ "type": "string",
+ "nullable": true
+ }
+ },
+ "required": [
+ "id",
+ "type",
+ "inserted_at",
+ "updated_at"
+ ]
+ }
+ }
+ }
+ },
+ "403": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "Auth"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ },
+ "get": {
+ "operationId": "getTPAForProject",
+ "summary": "[Alpha] Get a third-party integration",
+ "parameters": [
+ {
+ "name": "ref",
+ "required": true,
+ "in": "path",
+ "description": "Project ref",
+ "schema": {
+ "minLength": 20,
+ "maxLength": 20,
+ "type": "string"
+ }
+ },
+ {
+ "name": "tpa_id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "type": {
+ "type": "string"
+ },
+ "oidc_issuer_url": {
+ "type": "string",
+ "nullable": true
+ },
+ "jwks_url": {
+ "type": "string",
+ "nullable": true
+ },
+ "custom_jwks": {
+ "type": "object",
+ "nullable": true
+ },
+ "resolved_jwks": {
+ "type": "object",
+ "nullable": true
+ },
+ "inserted_at": {
+ "type": "string"
+ },
+ "updated_at": {
+ "type": "string"
+ },
+ "resolved_at": {
+ "type": "string",
+ "nullable": true
+ }
+ },
+ "required": [
+ "id",
+ "type",
+ "inserted_at",
+ "updated_at"
+ ]
+ }
+ }
+ }
+ },
+ "403": {
+ "description": ""
+ }
+ },
+ "tags": [
+ "Auth"
],
"security": [
{
@@ -6538,7 +7477,7 @@
}
},
"tags": [
- "database"
+ "Database"
],
"security": [
{
@@ -6576,7 +7515,7 @@
}
},
"tags": [
- "database"
+ "Database"
],
"security": [
{
@@ -6775,7 +7714,7 @@
}
},
"tags": [
- "edge functions"
+ "Edge Functions"
],
"security": [
{
@@ -6871,7 +7810,7 @@
}
},
"tags": [
- "edge functions"
+ "Edge Functions"
],
"security": [
{
@@ -6976,7 +7915,7 @@
}
},
"tags": [
- "edge functions"
+ "Edge Functions"
],
"security": [
{
@@ -7165,7 +8104,7 @@
}
},
"tags": [
- "edge functions"
+ "Edge Functions"
],
"security": [
{
@@ -7212,7 +8151,7 @@
}
},
"tags": [
- "edge functions"
+ "Edge Functions"
],
"security": [
{
@@ -7261,7 +8200,7 @@
}
},
"tags": [
- "edge functions"
+ "Edge Functions"
],
"security": [
{
@@ -7337,7 +8276,7 @@
}
},
"tags": [
- "storage"
+ "Storage"
],
"security": [
{
@@ -7421,6 +8360,9 @@
"items": {
"type": "string"
}
+ },
+ "array": {
+ "type": "boolean"
}
}
}
@@ -7496,6 +8438,9 @@
"items": {
"type": "string"
}
+ },
+ "array": {
+ "type": "boolean"
}
}
}
@@ -7556,7 +8501,7 @@
}
},
"tags": [
- "auth"
+ "Auth"
],
"security": [
{
@@ -7643,6 +8588,9 @@
"items": {
"type": "string"
}
+ },
+ "array": {
+ "type": "boolean"
}
}
}
@@ -7709,7 +8657,7 @@
}
},
"tags": [
- "auth"
+ "Auth"
],
"security": [
{
@@ -7801,6 +8749,9 @@
"items": {
"type": "string"
}
+ },
+ "array": {
+ "type": "boolean"
}
}
}
@@ -7861,7 +8812,7 @@
}
},
"tags": [
- "auth"
+ "Auth"
],
"security": [
{
@@ -7944,6 +8895,9 @@
"items": {
"type": "string"
}
+ },
+ "array": {
+ "type": "boolean"
}
}
}
@@ -8016,6 +8970,9 @@
"items": {
"type": "string"
}
+ },
+ "array": {
+ "type": "boolean"
}
}
}
@@ -8076,7 +9033,7 @@
}
},
"tags": [
- "auth"
+ "Auth"
],
"security": [
{
@@ -8166,6 +9123,9 @@
"items": {
"type": "string"
}
+ },
+ "array": {
+ "type": "boolean"
}
}
}
@@ -8226,7 +9186,7 @@
}
},
"tags": [
- "auth"
+ "Auth"
],
"security": [
{
@@ -8326,7 +9286,7 @@
}
},
"tags": [
- "database"
+ "Database"
],
"security": [
{
@@ -8376,7 +9336,7 @@
}
},
"tags": [
- "database"
+ "Database"
],
"security": [
{
@@ -8438,7 +9398,7 @@
}
},
"tags": [
- "organizations"
+ "Organizations"
],
"security": [
{
@@ -8505,7 +9465,7 @@
}
},
"tags": [
- "organizations"
+ "Organizations"
],
"security": [
{
@@ -8545,10 +9505,13 @@
"INACTIVE",
"INIT_FAILED",
"REMOVED",
- "RESTORING",
+ "RESTARTING",
"UNKNOWN",
"UPGRADING",
- "PAUSING"
+ "PAUSING",
+ "RESTORING",
+ "RESTORE_FAILED",
+ "PAUSE_FAILED"
],
"type": "string"
},
@@ -8744,10 +9707,13 @@
"INACTIVE",
"INIT_FAILED",
"REMOVED",
- "RESTORING",
+ "RESTARTING",
"UNKNOWN",
"UPGRADING",
- "PAUSING"
+ "PAUSING",
+ "RESTORING",
+ "RESTORE_FAILED",
+ "PAUSE_FAILED"
],
"type": "string"
}
@@ -9328,6 +10294,240 @@
"branch_name"
]
},
+ "ValidationRecord": {
+ "type": "object",
+ "properties": {
+ "txt_name": {
+ "type": "string"
+ },
+ "txt_value": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "txt_name",
+ "txt_value"
+ ]
+ },
+ "ValidationError": {
+ "type": "object",
+ "properties": {
+ "message": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "message"
+ ]
+ },
+ "CustomHostnameDetails": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "hostname": {
+ "type": "string"
+ },
+ "ssl": {
+ "type": "object",
+ "properties": {
+ "status": {
+ "required": true,
+ "type": "string"
+ },
+ "validation_records": {
+ "required": true,
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "txt_name": {
+ "type": "string"
+ },
+ "txt_value": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "txt_name",
+ "txt_value"
+ ]
+ }
+ },
+ "validation_errors": {
+ "required": false,
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "message": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "message"
+ ]
+ }
+ }
+ }
+ },
+ "ownership_verification": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "required": true,
+ "type": "string"
+ },
+ "name": {
+ "required": true,
+ "type": "string"
+ },
+ "value": {
+ "required": true,
+ "type": "string"
+ }
+ }
+ },
+ "custom_origin_server": {
+ "type": "string"
+ },
+ "verification_errors": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "status": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "id",
+ "hostname",
+ "ssl",
+ "ownership_verification",
+ "custom_origin_server",
+ "status"
+ ]
+ },
+ "CfResponse": {
+ "type": "object",
+ "properties": {
+ "success": {
+ "type": "boolean"
+ },
+ "errors": {
+ "type": "array",
+ "items": {
+ "type": "object"
+ }
+ },
+ "messages": {
+ "type": "array",
+ "items": {
+ "type": "object"
+ }
+ },
+ "result": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "hostname": {
+ "type": "string"
+ },
+ "ssl": {
+ "type": "object",
+ "properties": {
+ "status": {
+ "required": true,
+ "type": "string"
+ },
+ "validation_records": {
+ "required": true,
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "txt_name": {
+ "type": "string"
+ },
+ "txt_value": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "txt_name",
+ "txt_value"
+ ]
+ }
+ },
+ "validation_errors": {
+ "required": false,
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "message": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "message"
+ ]
+ }
+ }
+ }
+ },
+ "ownership_verification": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "required": true,
+ "type": "string"
+ },
+ "name": {
+ "required": true,
+ "type": "string"
+ },
+ "value": {
+ "required": true,
+ "type": "string"
+ }
+ }
+ },
+ "custom_origin_server": {
+ "type": "string"
+ },
+ "verification_errors": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "status": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "id",
+ "hostname",
+ "ssl",
+ "ownership_verification",
+ "custom_origin_server",
+ "status"
+ ]
+ }
+ },
+ "required": [
+ "success",
+ "errors",
+ "messages",
+ "result"
+ ]
+ },
"UpdateCustomHostnameResponse": {
"type": "object",
"properties": {
@@ -9345,7 +10545,121 @@
"type": "string"
},
"data": {
- "type": "object"
+ "type": "object",
+ "properties": {
+ "success": {
+ "type": "boolean"
+ },
+ "errors": {
+ "type": "array",
+ "items": {
+ "type": "object"
+ }
+ },
+ "messages": {
+ "type": "array",
+ "items": {
+ "type": "object"
+ }
+ },
+ "result": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "hostname": {
+ "type": "string"
+ },
+ "ssl": {
+ "type": "object",
+ "properties": {
+ "status": {
+ "required": true,
+ "type": "string"
+ },
+ "validation_records": {
+ "required": true,
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "txt_name": {
+ "type": "string"
+ },
+ "txt_value": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "txt_name",
+ "txt_value"
+ ]
+ }
+ },
+ "validation_errors": {
+ "required": false,
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "message": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "message"
+ ]
+ }
+ }
+ }
+ },
+ "ownership_verification": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "required": true,
+ "type": "string"
+ },
+ "name": {
+ "required": true,
+ "type": "string"
+ },
+ "value": {
+ "required": true,
+ "type": "string"
+ }
+ }
+ },
+ "custom_origin_server": {
+ "type": "string"
+ },
+ "verification_errors": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "status": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "id",
+ "hostname",
+ "ssl",
+ "ownership_verification",
+ "custom_origin_server",
+ "status"
+ ]
+ }
+ },
+ "required": [
+ "success",
+ "errors",
+ "messages",
+ "result"
+ ]
}
},
"required": [
@@ -9840,6 +11154,9 @@
"initiated_at": {
"type": "string"
},
+ "latest_status_at": {
+ "type": "string"
+ },
"target_version": {
"type": "number"
},
@@ -9853,7 +11170,8 @@
"5_data_upgrade_completion_failed",
"6_volume_detachchment_from_original_instance_failed",
"7_volume_attachment_to_upgraded_instance_failed",
- "8_upgrade_completion_failed"
+ "8_upgrade_completion_failed",
+ "9_post_physical_backup_failed"
]
},
"progress": {
@@ -9868,7 +11186,8 @@
"6_completed_data_upgrade",
"7_detached_volume_from_original_instance",
"8_attached_volume_to_upgraded_instance",
- "9_completed_upgrade"
+ "9_completed_upgrade",
+ "10_completed_post_physical_backup"
]
},
"status": {
@@ -9882,6 +11201,7 @@
},
"required": [
"initiated_at",
+ "latest_status_at",
"target_version",
"status"
]
@@ -9898,6 +11218,9 @@
"initiated_at": {
"type": "string"
},
+ "latest_status_at": {
+ "type": "string"
+ },
"target_version": {
"type": "number"
},
@@ -9911,7 +11234,8 @@
"5_data_upgrade_completion_failed",
"6_volume_detachchment_from_original_instance_failed",
"7_volume_attachment_to_upgraded_instance_failed",
- "8_upgrade_completion_failed"
+ "8_upgrade_completion_failed",
+ "9_post_physical_backup_failed"
]
},
"progress": {
@@ -9926,7 +11250,8 @@
"6_completed_data_upgrade",
"7_detached_volume_from_original_instance",
"8_attached_volume_to_upgraded_instance",
- "9_completed_upgrade"
+ "9_completed_upgrade",
+ "10_completed_post_physical_backup"
]
},
"status": {
@@ -9940,6 +11265,7 @@
},
"required": [
"initiated_at",
+ "latest_status_at",
"target_version",
"status"
]
@@ -10571,6 +11897,18 @@
"type": "string",
"nullable": true
},
+ "external_slack_oidc_client_id": {
+ "type": "string",
+ "nullable": true
+ },
+ "external_slack_oidc_enabled": {
+ "type": "boolean",
+ "nullable": true
+ },
+ "external_slack_oidc_secret": {
+ "type": "string",
+ "nullable": true
+ },
"external_notion_client_id": {
"type": "string",
"nullable": true
@@ -10830,6 +12168,10 @@
"type": "number",
"nullable": true
},
+ "rate_limit_otp": {
+ "type": "number",
+ "nullable": true
+ },
"refresh_token_rotation_enabled": {
"type": "boolean",
"nullable": true
@@ -10838,6 +12180,10 @@
"type": "boolean",
"nullable": true
},
+ "saml_external_url": {
+ "type": "string",
+ "nullable": true
+ },
"security_captcha_enabled": {
"type": "boolean",
"nullable": true
@@ -11050,6 +12396,9 @@
"external_linkedin_oidc_client_id",
"external_linkedin_oidc_enabled",
"external_linkedin_oidc_secret",
+ "external_slack_oidc_client_id",
+ "external_slack_oidc_enabled",
+ "external_slack_oidc_secret",
"external_notion_client_id",
"external_notion_enabled",
"external_notion_secret",
@@ -11115,8 +12464,10 @@
"rate_limit_sms_sent",
"rate_limit_token_refresh",
"rate_limit_verify",
+ "rate_limit_otp",
"refresh_token_rotation_enabled",
"saml_enabled",
+ "saml_external_url",
"security_captcha_enabled",
"security_captcha_provider",
"security_captcha_secret",
@@ -11260,6 +12611,10 @@
"saml_enabled": {
"type": "boolean"
},
+ "saml_external_url": {
+ "type": "string",
+ "pattern": "/^[^,]+$/"
+ },
"security_captcha_enabled": {
"type": "boolean"
},
@@ -11309,6 +12664,11 @@
"minimum": 1,
"maximum": 2147483647
},
+ "rate_limit_otp": {
+ "type": "number",
+ "minimum": 1,
+ "maximum": 2147483647
+ },
"mailer_secure_email_change_enabled": {
"type": "boolean"
},
@@ -11597,6 +12957,15 @@
"external_linkedin_oidc_secret": {
"type": "string"
},
+ "external_slack_oidc_enabled": {
+ "type": "boolean"
+ },
+ "external_slack_oidc_client_id": {
+ "type": "string"
+ },
+ "external_slack_oidc_secret": {
+ "type": "string"
+ },
"external_notion_enabled": {
"type": "boolean"
},
@@ -11671,6 +13040,63 @@
}
}
},
+ "CreateThirdPartyAuthBody": {
+ "type": "object",
+ "properties": {
+ "oidc_issuer_url": {
+ "type": "string"
+ },
+ "jwks_url": {
+ "type": "string"
+ },
+ "custom_jwks": {
+ "type": "object"
+ }
+ }
+ },
+ "ThirdPartyAuth": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "type": {
+ "type": "string"
+ },
+ "oidc_issuer_url": {
+ "type": "string",
+ "nullable": true
+ },
+ "jwks_url": {
+ "type": "string",
+ "nullable": true
+ },
+ "custom_jwks": {
+ "type": "object",
+ "nullable": true
+ },
+ "resolved_jwks": {
+ "type": "object",
+ "nullable": true
+ },
+ "inserted_at": {
+ "type": "string"
+ },
+ "updated_at": {
+ "type": "string"
+ },
+ "resolved_at": {
+ "type": "string",
+ "nullable": true
+ }
+ },
+ "required": [
+ "id",
+ "type",
+ "inserted_at",
+ "updated_at"
+ ]
+ },
"V1RunQueryBody": {
"type": "object",
"properties": {
@@ -11881,6 +13307,9 @@
"items": {
"type": "string"
}
+ },
+ "array": {
+ "type": "boolean"
}
}
},
@@ -11916,6 +13345,9 @@
"items": {
"type": "string"
}
+ },
+ "array": {
+ "type": "boolean"
}
}
}
@@ -11979,6 +13411,9 @@
"items": {
"type": "string"
}
+ },
+ "array": {
+ "type": "boolean"
}
}
}
@@ -12040,6 +13475,9 @@
"items": {
"type": "string"
}
+ },
+ "array": {
+ "type": "boolean"
}
}
}
@@ -12128,6 +13566,9 @@
"items": {
"type": "string"
}
+ },
+ "array": {
+ "type": "boolean"
}
}
}
@@ -12230,6 +13671,9 @@
"items": {
"type": "string"
}
+ },
+ "array": {
+ "type": "boolean"
}
}
}
@@ -12337,6 +13781,9 @@
"items": {
"type": "string"
}
+ },
+ "array": {
+ "type": "boolean"
}
}
}
@@ -12445,6 +13892,9 @@
"items": {
"type": "string"
}
+ },
+ "array": {
+ "type": "boolean"
}
}
}
@@ -12541,6 +13991,9 @@
"items": {
"type": "string"
}
+ },
+ "array": {
+ "type": "boolean"
}
}
}
@@ -12605,6 +14058,9 @@
"items": {
"type": "string"
}
+ },
+ "array": {
+ "type": "boolean"
}
}
}
@@ -12707,6 +14163,9 @@
"items": {
"type": "string"
}
+ },
+ "array": {
+ "type": "boolean"
}
}
}
diff --git a/apps/docs/styles/main.scss b/apps/docs/styles/main.scss
index 5d34e84cbfe..d66c3e7a4a3 100644
--- a/apps/docs/styles/main.scss
+++ b/apps/docs/styles/main.scss
@@ -29,6 +29,7 @@
:root {
--sidebar-width: 300px;
+ --header-height: 50px;
}
body {
@@ -231,6 +232,7 @@ article p code {
}
.short-inline-codeblock {
+ word-wrap: break-word;
@media screen and (min-width: 769px) {
white-space: pre !important;
}
@@ -266,6 +268,10 @@ article p code {
height: unset !important;
}
+#docs-content-container #introduction {
+ @apply scroll-mt-60;
+}
+
/* dat.GUI */
.dg.ac {
@@ -277,3 +283,55 @@ article p code {
th code {
@apply text-nowrap;
}
+
+/* Zoomable image */
+
+[data-rmiz-modal]:focus,
+[data-rmiz-modal-overlay]:focus {
+ outline: none !important;
+}
+
+[data-rmiz-modal-overlay],
+[data-rmiz-modal-img] {
+ transition-timing-function: cubic-bezier(0.24, 0.25, 0.05, 1) !important;
+}
+[data-rmiz-modal-overlay='visible'] {
+ background-color: hsl(var(--background-default)) !important;
+ opacity: 0.8;
+}
+[data-rmiz-modal-img] {
+ image-rendering: high-quality;
+}
+
+/* Loaders */
+
+.shimmering-loader {
+ animation: shimmer 2s infinite linear;
+ background: linear-gradient(
+ to right,
+ hsl(var(--border-default)) 4%,
+ hsl(var(--background-surface-200)) 25%,
+ hsl(var(--border-default)) 36%
+ );
+ background-size: 1000px 100%;
+}
+
+.dark .shimmering-loader {
+ animation: shimmer 2s infinite linear;
+ background: linear-gradient(
+ to right,
+ hsl(var(--border-default)) 4%,
+ hsl(var(--border-control)) 25%,
+ hsl(var(--border-default)) 36%
+ );
+ background-size: 1000px 100%;
+}
+
+@keyframes shimmer {
+ 0% {
+ background-position: -1000px 0;
+ }
+ 100% {
+ background-position: 1000px 0;
+ }
+}
diff --git a/apps/docs/tailwind.config.js b/apps/docs/tailwind.config.js
index b4b91c5d972..47217b6c131 100644
--- a/apps/docs/tailwind.config.js
+++ b/apps/docs/tailwind.config.js
@@ -2,9 +2,11 @@ const config = require('config/tailwind.config')
module.exports = config({
content: [
+ './app/**/*.{ts,tsx,mdx}',
'./components/**/*.tsx',
'./content/**/*.{ts,tsx,mdx}',
'./docs/**/*.{tsx,mdx}',
+ './features/**/*.{ts,tsx,mdx}',
'./layouts/**/*.tsx',
'./pages/**/*.{tsx,mdx}',
'./../../packages/ui/src/**/*.{tsx,ts,js}',
diff --git a/apps/docs/tsconfig.json b/apps/docs/tsconfig.json
index ae8e217aa85..0e8f0b99046 100644
--- a/apps/docs/tsconfig.json
+++ b/apps/docs/tsconfig.json
@@ -20,7 +20,13 @@
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
- "module": "esnext"
+ "module": "esnext",
+ "plugins": [
+ {
+ "name": "next"
+ }
+ ],
+ "strictNullChecks": false
},
"include": [
"next-env.d.ts",
@@ -28,6 +34,7 @@
"**/*.tsx",
"pages/guides/append-test.js",
"jest.config.mjs",
+ ".next/types/**/*.ts",
"./../../packages/ui/src/**/*.d.ts"
],
"exclude": ["node_modules"]
diff --git a/apps/docs/types/api.d.ts b/apps/docs/types/api.d.ts
deleted file mode 100644
index ef41f7bc31e..00000000000
--- a/apps/docs/types/api.d.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-/**
- * Avoid importing this file and import the types directly from api-types
- */
-export * from 'api-types'
diff --git a/apps/docs/types/next.ts b/apps/docs/types/next.ts
index b525bed86bc..a8c464c01fa 100644
--- a/apps/docs/types/next.ts
+++ b/apps/docs/types/next.ts
@@ -1,6 +1,6 @@
-import { NextPage } from 'next'
-import { AppProps } from 'next/app'
-import { ReactElement, ReactNode } from 'react'
+import type { NextPage } from 'next'
+import type { AppProps } from 'next/app'
+import type { ReactElement, ReactNode } from 'react'
export type AppPropsWithLayout = AppProps & {
Component: NextPageWithLayout
diff --git a/apps/docs/vitest.config.ts b/apps/docs/vitest.config.ts
new file mode 100644
index 00000000000..0e7ddac448c
--- /dev/null
+++ b/apps/docs/vitest.config.ts
@@ -0,0 +1,6 @@
+import { defineConfig } from 'vitest/config'
+import tsconfigPaths from 'vite-tsconfig-paths'
+
+export default defineConfig({
+ plugins: [tsconfigPaths({ root: import.meta.dirname })],
+})
diff --git a/apps/studio/.eslintrc.js b/apps/studio/.eslintrc.js
index c1858400302..45017c942f8 100644
--- a/apps/studio/.eslintrc.js
+++ b/apps/studio/.eslintrc.js
@@ -1,8 +1,10 @@
module.exports = {
extends: ['eslint-config-supabase/next'],
+ plugins: ['eslint-plugin-barrel-files'],
rules: {
'@next/next/no-img-element': 'off',
'react/no-unescaped-entities': 'off',
'react/display-name': 'warn',
+ 'barrel-files/avoid-re-export-all': 'error',
},
}
diff --git a/apps/studio/components/grid/SupabaseGrid.tsx b/apps/studio/components/grid/SupabaseGrid.tsx
index 7f2b1c374f8..1acae8f5b98 100644
--- a/apps/studio/components/grid/SupabaseGrid.tsx
+++ b/apps/studio/components/grid/SupabaseGrid.tsx
@@ -7,7 +7,7 @@ import { createPortal } from 'react-dom'
import { useParams } from 'common'
import { useProjectContext } from 'components/layouts/ProjectLayout/ProjectContext'
import { useTableRowsQuery } from 'data/table-rows/table-rows-query'
-import { useUrlState } from 'hooks'
+import { useUrlState } from 'hooks/ui/useUrlState'
import { useRoleImpersonationStateSnapshot } from 'state/role-impersonation-state'
import { useTableEditorStateSnapshot } from 'state/table-editor'
import {
@@ -17,13 +17,13 @@ import {
getStorageKey,
saveStorageDebounced,
} from './SupabaseGrid.utils'
-import { Shortcuts } from './components/common'
+import { Shortcuts } from './components/common/Shortcuts'
import Footer from './components/footer/Footer'
-import { Grid } from './components/grid'
+import { Grid } from './components/grid/Grid'
import Header from './components/header/Header'
import { RowContextMenu } from './components/menu'
import { STORAGE_KEY_PREFIX } from './constants'
-import { StoreProvider, useDispatch, useTrackedState } from './store'
+import { StoreProvider, useDispatch, useTrackedState } from './store/Store'
import { InitialStateType } from './store/reducers'
import type { SupabaseGridProps } from './types'
import { getGridColumns } from './utils/gridColumns'
@@ -271,7 +271,7 @@ const SupabaseGridLayout = (props: SupabaseGridProps) => {
onImportData={onImportData}
onEditForeignKeyColumnValue={onEditForeignKeyColumnValue}
/>
-
+
>
)}
diff --git a/apps/studio/components/grid/SupabaseGrid.utils.ts b/apps/studio/components/grid/SupabaseGrid.utils.ts
index a8dadb0c5df..1dcc9a2867d 100644
--- a/apps/studio/components/grid/SupabaseGrid.utils.ts
+++ b/apps/studio/components/grid/SupabaseGrid.utils.ts
@@ -2,7 +2,7 @@ import AwesomeDebouncePromise from 'awesome-debounce-promise'
import type { Filter } from 'components/grid/types'
import { compact } from 'lodash'
import type { Dictionary } from 'types'
-import { FilterOperatorOptions } from './components/header/filter'
+import { FilterOperatorOptions } from './components/header/filter/Filter.constants'
import { STORAGE_KEY_PREFIX } from './constants'
import { InitialStateType } from './store/reducers'
import type { Sort, SupabaseGridProps, SupaColumn, SupaTable } from './types'
@@ -115,6 +115,7 @@ export function parseSupaTable(
})
return {
+ id: table.id,
name: table.name,
comment: table.comment,
schema: table.schema,
diff --git a/apps/studio/components/grid/components/common/BlockKeys.tsx b/apps/studio/components/grid/components/common/BlockKeys.tsx
index bb3ecbab495..72f5d84a0c0 100644
--- a/apps/studio/components/grid/components/common/BlockKeys.tsx
+++ b/apps/studio/components/grid/components/common/BlockKeys.tsx
@@ -1,4 +1,4 @@
-import { useClickedOutside } from 'hooks'
+import { useClickedOutside } from 'hooks/ui/useClickedOutside'
import { KeyboardEvent, ReactNode, useCallback, useEffect, useRef } from 'react'
interface BlockKeysProps {
diff --git a/apps/studio/components/grid/components/common/Shortcuts.tsx b/apps/studio/components/grid/components/common/Shortcuts.tsx
index 4d14f6dae20..9544133c731 100644
--- a/apps/studio/components/grid/components/common/Shortcuts.tsx
+++ b/apps/studio/components/grid/components/common/Shortcuts.tsx
@@ -1,8 +1,8 @@
import * as React from 'react'
-import { useTrackedState } from '../../store'
-import { useKeyboardShortcuts } from './Hooks'
import type { DataGridHandle } from 'react-data-grid'
-import { formatClipboardValue, copyToClipboard } from '../../utils'
+import { useTrackedState } from '../../store/Store'
+import { copyToClipboard, formatClipboardValue } from '../../utils/common'
+import { useKeyboardShortcuts } from './Hooks'
type ShortcutsProps = {
gridRef: React.RefObject
diff --git a/apps/studio/components/grid/components/common/index.ts b/apps/studio/components/grid/components/common/index.ts
deleted file mode 100644
index 9ac92bc11a2..00000000000
--- a/apps/studio/components/grid/components/common/index.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-export * from './BlockKeys'
-export * from './DropdownControl'
-export * from './MonacoEditor'
-export * from './NullValue'
-export * from './Hooks'
-export * from './Shortcuts'
-export * from './EmptyValue'
diff --git a/apps/studio/components/grid/components/editor/BooleanEditor.tsx b/apps/studio/components/grid/components/editor/BooleanEditor.tsx
index 3ae4643b42d..0b411802cd5 100644
--- a/apps/studio/components/grid/components/editor/BooleanEditor.tsx
+++ b/apps/studio/components/grid/components/editor/BooleanEditor.tsx
@@ -1,6 +1,6 @@
-import { Select } from 'ui'
+import { useTrackedState } from 'components/grid/store/Store'
import type { RenderEditCellProps } from 'react-data-grid'
-import { useTrackedState } from 'components/grid/store'
+import { Select } from 'ui'
interface Props extends RenderEditCellProps {
isNullable?: boolean
diff --git a/apps/studio/components/grid/components/editor/JsonEditor.tsx b/apps/studio/components/grid/components/editor/JsonEditor.tsx
index 8b7523ed9cc..637df96e78b 100644
--- a/apps/studio/components/grid/components/editor/JsonEditor.tsx
+++ b/apps/studio/components/grid/components/editor/JsonEditor.tsx
@@ -6,15 +6,17 @@ import type { RenderEditCellProps } from 'react-data-grid'
import toast from 'react-hot-toast'
import { useParams } from 'common'
-import { BlockKeys, MonacoEditor, NullValue } from 'components/grid/components/common'
-import { useTrackedState } from 'components/grid/store'
+import { useTrackedState } from 'components/grid/store/Store'
import { useGetCellValueMutation } from 'data/table-rows/get-cell-value-mutation'
import { MAX_CHARACTERS } from 'data/table-rows/table-rows-query'
-import { useSelectedProject } from 'hooks'
+import { useSelectedProject } from 'hooks/misc/useSelectedProject'
import useTable from 'hooks/misc/useTable'
import { prettifyJSON, removeJSONTrailingComma, tryParseJson } from 'lib/helpers'
import { Popover, TooltipContent_Shadcn_, TooltipTrigger_Shadcn_, Tooltip_Shadcn_ } from 'ui'
-import { TruncatedWarningOverlay } from '.'
+import { BlockKeys } from '../common/BlockKeys'
+import { MonacoEditor } from '../common/MonacoEditor'
+import { NullValue } from '../common/NullValue'
+import { TruncatedWarningOverlay } from './TruncatedWarningOverlay'
const verifyJSON = (value: string) => {
try {
diff --git a/apps/studio/components/grid/components/editor/SelectEditor.tsx b/apps/studio/components/grid/components/editor/SelectEditor.tsx
index 06828236b06..0aa6a08e6c2 100644
--- a/apps/studio/components/grid/components/editor/SelectEditor.tsx
+++ b/apps/studio/components/grid/components/editor/SelectEditor.tsx
@@ -1,7 +1,7 @@
-import { Select } from 'ui'
import type { RenderEditCellProps } from 'react-data-grid'
+import { Select } from 'ui'
-import { useTrackedState } from 'components/grid/store'
+import { useTrackedState } from 'components/grid/store/Store'
interface SelectEditorProps
extends RenderEditCellProps {
diff --git a/apps/studio/components/grid/components/editor/TextEditor.tsx b/apps/studio/components/grid/components/editor/TextEditor.tsx
index 3579233e76b..5d81fd3a40c 100644
--- a/apps/studio/components/grid/components/editor/TextEditor.tsx
+++ b/apps/studio/components/grid/components/editor/TextEditor.tsx
@@ -1,14 +1,14 @@
import { PostgresTable } from '@supabase/postgres-meta'
+import { Maximize } from 'lucide-react'
+import { useCallback, useState } from 'react'
import type { RenderEditCellProps } from 'react-data-grid'
import toast from 'react-hot-toast'
import { useParams } from 'common'
import { useGetCellValueMutation } from 'data/table-rows/get-cell-value-mutation'
import { MAX_CHARACTERS } from 'data/table-rows/table-rows-query'
-import { useSelectedProject } from 'hooks'
+import { useSelectedProject } from 'hooks/misc/useSelectedProject'
import useTable from 'hooks/misc/useTable'
-import { Maximize } from 'lucide-react'
-import { useCallback, useState } from 'react'
import {
Button,
Popover,
@@ -16,9 +16,12 @@ import {
TooltipTrigger_Shadcn_,
Tooltip_Shadcn_,
} from 'ui'
-import { TruncatedWarningOverlay } from '.'
-import { useTrackedState } from '../../store'
-import { BlockKeys, EmptyValue, MonacoEditor, NullValue } from '../common'
+import { useTrackedState } from '../../store/Store'
+import { BlockKeys } from '../common/BlockKeys'
+import { EmptyValue } from '../common/EmptyValue'
+import { MonacoEditor } from '../common/MonacoEditor'
+import { NullValue } from '../common/NullValue'
+import { TruncatedWarningOverlay } from './TruncatedWarningOverlay'
export const TextEditor = ({
row,
diff --git a/apps/studio/components/grid/components/editor/index.tsx b/apps/studio/components/grid/components/editor/TruncatedWarningOverlay.tsx
similarity index 78%
rename from apps/studio/components/grid/components/editor/index.tsx
rename to apps/studio/components/grid/components/editor/TruncatedWarningOverlay.tsx
index c4881491269..bac260a8450 100644
--- a/apps/studio/components/grid/components/editor/index.tsx
+++ b/apps/studio/components/grid/components/editor/TruncatedWarningOverlay.tsx
@@ -1,15 +1,6 @@
import { MAX_CHARACTERS } from 'data/table-rows/table-rows-query'
import { Button, cn } from 'ui'
-export * from './BooleanEditor'
-export * from './DateEditor'
-export * from './DateTimeEditor'
-export * from './JsonEditor'
-export * from './NumberEditor'
-export * from './SelectEditor'
-export * from './TextEditor'
-export * from './TimeEditor'
-
export const TruncatedWarningOverlay = ({
isLoading,
loadFullValue,
diff --git a/apps/studio/components/grid/components/footer/Footer.tsx b/apps/studio/components/grid/components/footer/Footer.tsx
index e2482f54bb1..57cb0019c9e 100644
--- a/apps/studio/components/grid/components/footer/Footer.tsx
+++ b/apps/studio/components/grid/components/footer/Footer.tsx
@@ -1,17 +1,16 @@
-import { Pagination } from './pagination'
-import useTable from 'hooks/misc/useTable'
import { useParams } from 'common'
-import TwoOptionToggle from 'components/ui/TwoOptionToggle'
-import { useUrlState } from 'hooks'
-import RefreshButton from '../header/RefreshButton'
import { GridFooter } from 'components/ui/GridFooter'
+import TwoOptionToggle from 'components/ui/TwoOptionToggle'
+import useTable from 'hooks/misc/useTable'
+import { useUrlState } from 'hooks/ui/useUrlState'
+import RefreshButton from '../header/RefreshButton'
+import { Pagination } from './pagination'
export interface FooterProps {
- isLoading?: boolean
isRefetching?: boolean
}
-const Footer = ({ isLoading, isRefetching }: FooterProps) => {
+const Footer = ({ isRefetching }: FooterProps) => {
const { id: _id } = useParams()
const id = _id ? Number(_id) : undefined
const { data: selectedTable } = useTable(id)
@@ -30,7 +29,7 @@ const Footer = ({ isLoading, isRefetching }: FooterProps) => {
{selectedView === 'data' && }
-
+
{selectedTable && selectedView === 'data' && (
)}
diff --git a/apps/studio/components/grid/components/footer/pagination/Pagination.tsx b/apps/studio/components/grid/components/footer/pagination/Pagination.tsx
index f9d391e2c76..4b2d520ebe2 100644
--- a/apps/studio/components/grid/components/footer/pagination/Pagination.tsx
+++ b/apps/studio/components/grid/components/footer/pagination/Pagination.tsx
@@ -1,16 +1,25 @@
-import { ArrowLeft, ArrowRight } from 'lucide-react'
+import { ArrowLeft, ArrowRight, HelpCircle } from 'lucide-react'
import { useEffect, useState } from 'react'
+import { PostgresTable } from '@supabase/postgres-meta'
import { formatFilterURLParams } from 'components/grid/SupabaseGrid.utils'
import { useProjectContext } from 'components/layouts/ProjectLayout/ProjectContext'
-import { useTableRowsCountQuery } from 'data/table-rows/table-rows-count-query'
-import { useUrlState } from 'hooks'
+import { THRESHOLD_COUNT, useTableRowsCountQuery } from 'data/table-rows/table-rows-count-query'
+import useTable from 'hooks/misc/useTable'
+import { useUrlState } from 'hooks/ui/useUrlState'
import { useRoleImpersonationStateSnapshot } from 'state/role-impersonation-state'
import { useTableEditorStateSnapshot } from 'state/table-editor'
-import { Button, InputNumber } from 'ui'
+import {
+ Button,
+ InputNumber,
+ TooltipContent_Shadcn_,
+ TooltipTrigger_Shadcn_,
+ Tooltip_Shadcn_,
+} from 'ui'
import ConfirmationModal from 'ui-patterns/Dialogs/ConfirmationModal'
-import { useDispatch, useTrackedState } from '../../../store'
-import { DropdownControl } from '../../common'
+import { useParams } from 'common'
+import { useDispatch, useTrackedState } from '../../../store/Store'
+import { DropdownControl } from '../../common/DropdownControl'
const rowsPerPageOptions = [
{ value: 100, label: '100 rows' },
@@ -19,28 +28,36 @@ const rowsPerPageOptions = [
]
const Pagination = () => {
+ const { id: _id } = useParams()
+ const id = _id ? Number(_id) : undefined
+
const state = useTrackedState()
const dispatch = useDispatch()
-
+ const { project } = useProjectContext()
const snap = useTableEditorStateSnapshot()
- const page = snap.page
- const [{ filter }] = useUrlState({
- arrayKeys: ['filter'],
- })
+ const { data: selectedTable } = useTable(id)
+ // [Joshen] Only applicable to table entities
+ const rowsCountEstimate = (selectedTable as PostgresTable)?.live_rows_estimate ?? null
+
+ const [{ filter }] = useUrlState({ arrayKeys: ['filter'] })
const filters = formatFilterURLParams(filter as string[])
+ const page = snap.page
const table = state.table ?? undefined
const roleImpersonationState = useRoleImpersonationStateSnapshot()
+ const [isConfirmNextModalOpen, setIsConfirmNextModalOpen] = useState(false)
+ const [isConfirmPreviousModalOpen, setIsConfirmPreviousModalOpen] = useState(false)
+ const [isConfirmFetchExactCountModalOpen, setIsConfirmFetchExactCountModalOpen] = useState(false)
- const { project } = useProjectContext()
- const { data, isLoading, isSuccess, isError } = useTableRowsCountQuery(
+ const { data, isLoading, isSuccess, isError, isFetching } = useTableRowsCountQuery(
{
- queryKey: [table?.schema, table?.name, 'count'],
+ queryKey: [table?.schema, table?.name, 'count-estimate'],
projectRef: project?.ref,
connectionString: project?.connectionString,
table,
filters,
+ enforceExactCount: snap.enforceExactCount,
impersonatedRole: roleImpersonationState.role,
},
{
@@ -57,21 +74,6 @@ const Pagination = () => {
const maxPages = Math.ceil((data?.count ?? 0) / snap.rowsPerPage)
const totalPages = (data?.count ?? 0) > 0 ? maxPages : 1
- useEffect(() => {
- if (page && page > totalPages) {
- snap.setPage(totalPages)
- }
- }, [page, totalPages])
-
- // [Joshen] Oddly without this, state.selectedRows will be stale
- useEffect(() => {}, [state.selectedRows])
-
- // [Joshen] Note: I've made pagination buttons disabled while rows are being fetched for now
- // at least until we can send an abort signal to cancel requests if users are mashing the
- // pagination buttons to find the data they want
-
- const [isConfirmPreviousModalOpen, setIsConfirmPreviousModalOpen] = useState(false)
-
const onPreviousPage = () => {
if (page > 1) {
if (state.selectedRows.size >= 1) {
@@ -90,8 +92,6 @@ const Pagination = () => {
})
}
- const [isConfirmNextModalOpen, setIsConfirmNextModalOpen] = useState(false)
-
const onNextPage = () => {
if (page < maxPages) {
if (state.selectedRows.size >= 1) {
@@ -110,8 +110,6 @@ const Pagination = () => {
})
}
- // TODO: look at aborting useTableRowsQuery if the user presses the button quickly
-
const goToPreviousPage = () => {
const previousPage = page - 1
snap.setPage(previousPage)
@@ -122,96 +120,112 @@ const Pagination = () => {
snap.setPage(nextPage)
}
- function onPageChange(event: React.ChangeEvent
) {
+ const onPageChange = (event: React.ChangeEvent) => {
const value = event.target.value
const pageNum = Number(value) > maxPages ? maxPages : Number(value)
snap.setPage(pageNum || 1)
}
- function onRowsPerPageChange(value: string | number) {
+ const onRowsPerPageChange = (value: string | number) => {
const rowsPerPage = Number(value)
-
snap.setRowsPerPage(isNaN(rowsPerPage) ? 100 : rowsPerPage)
}
+ useEffect(() => {
+ if (page && page > totalPages) {
+ snap.setPage(totalPages)
+ }
+ }, [page, totalPages])
+
+ useEffect(() => {
+ if (id !== undefined) {
+ snap.setEnforceExactCount(rowsCountEstimate !== null && rowsCountEstimate <= THRESHOLD_COUNT)
+ }
+ }, [id])
+
return (
-
+
{isLoading &&
Loading records count...
}
{isSuccess && (
<>
-
}
- type="outline"
- className="px-1.5"
- disabled={page <= 1 || isLoading}
- onClick={onPreviousPage}
- />
-
Page
-
-
+ }
+ type="outline"
+ className="px-1.5"
+ disabled={page <= 1 || isLoading}
+ onClick={onPreviousPage}
/>
+ Page
+
+
+
+
+ of {totalPages.toLocaleString()}
+
+ }
+ type="outline"
+ className="px-1.5"
+ disabled={page >= maxPages || isLoading}
+ onClick={onNextPage}
+ />
+
+
+
+ {`${snap.rowsPerPage} rows`}
+
+
-
of {totalPages}
-
}
- type="outline"
- className="px-1.5"
- disabled={page >= maxPages || isLoading}
- onClick={onNextPage}
- />
-
-
- {`${snap.rowsPerPage} rows`}
-
-
-
{`${data.count.toLocaleString()} ${
- data.count === 0 || data.count > 1 ? `records` : 'record'
- }`}
-
-
setIsConfirmPreviousModalOpen(false)}
- onConfirm={() => {
- onConfirmPreviousPage()
- }}
- >
-
- The currently selected lines will be deselected, do you want to proceed?
+
+
+ {`${data.count.toLocaleString()} ${
+ data.count === 0 || data.count > 1 ? `records` : 'record'
+ }`}{' '}
+ {data.is_estimate ? '(estimated)' : ''}
-
-
setIsConfirmNextModalOpen(false)}
- onConfirm={() => {
- onConfirmNextPage()
- }}
- >
-
- The currently selected lines will be deselected, do you want to proceed?
-
-
+ {data.is_estimate && (
+
+
+ }
+ onClick={() => {
+ // Show warning if either NOT a table entity, or table rows estimate is beyond threshold
+ if (rowsCountEstimate === null || data.count > THRESHOLD_COUNT) {
+ setIsConfirmFetchExactCountModalOpen(true)
+ } else snap.setEnforceExactCount(true)
+ }}
+ />
+
+
+ This is an estimated value as your table has more than{' '}
+ {THRESHOLD_COUNT.toLocaleString()} rows.
+
+ Click to retrieve the exact count of the table.
+
+
+
+ )}
+
>
)}
@@ -220,6 +234,54 @@ const Pagination = () => {
Error fetching records count. Please refresh the page.
)}
+
+ setIsConfirmPreviousModalOpen(false)}
+ onConfirm={() => {
+ onConfirmPreviousPage()
+ }}
+ >
+
+ The currently selected lines will be deselected, do you want to proceed?
+
+
+
+ setIsConfirmNextModalOpen(false)}
+ onConfirm={() => {
+ onConfirmNextPage()
+ }}
+ >
+
+ The currently selected lines will be deselected, do you want to proceed?
+
+
+
+ setIsConfirmFetchExactCountModalOpen(false)}
+ onConfirm={() => {
+ snap.setEnforceExactCount(true)
+ setIsConfirmFetchExactCountModalOpen(false)
+ }}
+ >
+
+ {rowsCountEstimate === null
+ ? `If your table has a row count of greater than ${THRESHOLD_COUNT.toLocaleString()} rows,
+ retrieving the exact count of the table may cause performance issues on your database.`
+ : `Your table has a row count of greater than ${THRESHOLD_COUNT.toLocaleString()} rows, and
+ retrieving the exact count of the table may cause performance issues on your database.`}
+
+
)
}
diff --git a/apps/studio/components/grid/components/formatter/BooleanFormatter.tsx b/apps/studio/components/grid/components/formatter/BooleanFormatter.tsx
index a7f766806d5..df57b528b1e 100644
--- a/apps/studio/components/grid/components/formatter/BooleanFormatter.tsx
+++ b/apps/studio/components/grid/components/formatter/BooleanFormatter.tsx
@@ -1,7 +1,7 @@
import type { PropsWithChildren } from 'react'
import type { RenderCellProps } from 'react-data-grid'
import type { SupaRow } from '../../types'
-import { NullValue } from '../common'
+import { NullValue } from '../common/NullValue'
export const BooleanFormatter = (p: PropsWithChildren
>) => {
const value = p.row[p.column.key] as boolean | null
diff --git a/apps/studio/components/grid/components/formatter/DefaultFormatter.tsx b/apps/studio/components/grid/components/formatter/DefaultFormatter.tsx
index 325fee62e19..98de5f3797d 100644
--- a/apps/studio/components/grid/components/formatter/DefaultFormatter.tsx
+++ b/apps/studio/components/grid/components/formatter/DefaultFormatter.tsx
@@ -1,8 +1,8 @@
import * as React from 'react'
import type { RenderCellProps } from 'react-data-grid'
import type { SupaRow } from '../../types'
-import { NullValue } from '../common'
import { EmptyValue } from '../common/EmptyValue'
+import { NullValue } from '../common/NullValue'
export const DefaultFormatter = (p: React.PropsWithChildren>) => {
let value = p.row[p.column.key]
diff --git a/apps/studio/components/grid/components/formatter/ForeignKeyFormatter.tsx b/apps/studio/components/grid/components/formatter/ForeignKeyFormatter.tsx
index 034f4be7a05..5f104a5e133 100644
--- a/apps/studio/components/grid/components/formatter/ForeignKeyFormatter.tsx
+++ b/apps/studio/components/grid/components/formatter/ForeignKeyFormatter.tsx
@@ -9,7 +9,7 @@ import { useTableQuery } from 'data/tables/table-query'
import { useTablesQuery } from 'data/tables/tables-query'
import { useTableEditorStateSnapshot } from 'state/table-editor'
import type { SupaRow } from '../../types'
-import { NullValue } from '../common'
+import { NullValue } from '../common/NullValue'
interface Props extends PropsWithChildren> {
projectRef?: string
diff --git a/apps/studio/components/grid/components/formatter/JsonFormatter.tsx b/apps/studio/components/grid/components/formatter/JsonFormatter.tsx
index 3e12bfe7db4..f54c207efbe 100644
--- a/apps/studio/components/grid/components/formatter/JsonFormatter.tsx
+++ b/apps/studio/components/grid/components/formatter/JsonFormatter.tsx
@@ -2,7 +2,8 @@ import { PropsWithChildren } from 'react'
import type { RenderCellProps } from 'react-data-grid'
import type { SupaRow } from '../../types'
-import { EmptyValue, NullValue } from '../common'
+import { EmptyValue } from '../common/EmptyValue'
+import { NullValue } from '../common/NullValue'
export const JsonFormatter = (p: PropsWithChildren>) => {
let value = p.row[p.column.key]
diff --git a/apps/studio/components/grid/components/formatter/index.ts b/apps/studio/components/grid/components/formatter/index.ts
deleted file mode 100644
index f53ab6cc653..00000000000
--- a/apps/studio/components/grid/components/formatter/index.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export * from './BooleanFormatter'
-export * from './DefaultFormatter'
-export * from './ForeignKeyFormatter'
-export * from './JsonFormatter'
diff --git a/apps/studio/components/grid/components/grid/AddColumn.tsx b/apps/studio/components/grid/components/grid/AddColumn.tsx
index b9cb11ce8d1..1da2237d25b 100644
--- a/apps/studio/components/grid/components/grid/AddColumn.tsx
+++ b/apps/studio/components/grid/components/grid/AddColumn.tsx
@@ -2,8 +2,8 @@ import type { CalculatedColumn } from 'react-data-grid'
import { Button, IconPlus } from 'ui'
import { ADD_COLUMN_KEY } from '../../constants'
-import { useTrackedState } from '../../store'
-import { DefaultFormatter } from '../formatter'
+import { useTrackedState } from '../../store/Store'
+import { DefaultFormatter } from '../formatter/DefaultFormatter'
export const AddColumn: CalculatedColumn = {
key: ADD_COLUMN_KEY,
diff --git a/apps/studio/components/grid/components/grid/ColumnHeader.tsx b/apps/studio/components/grid/components/grid/ColumnHeader.tsx
index a8fac748b5b..9e99ea16d81 100644
--- a/apps/studio/components/grid/components/grid/ColumnHeader.tsx
+++ b/apps/studio/components/grid/components/grid/ColumnHeader.tsx
@@ -3,12 +3,12 @@ import { getForeignKeyCascadeAction } from 'components/interfaces/TableGridEdito
import { FOREIGN_KEY_CASCADE_ACTION } from 'data/database/database-query-constants'
import type { XYCoord } from 'dnd-core'
import * as React from 'react'
+import { useEffect } from 'react'
import { useDrag, useDrop } from 'react-dnd'
import { IconArrowRight, IconKey, IconLink, IconLock } from 'ui'
-import { useDispatch, useTrackedState } from '../../store'
+import { useDispatch, useTrackedState } from '../../store/Store'
import type { ColumnHeaderProps, ColumnType, DragItem, GridForeignKey } from '../../types'
import { ColumnMenu } from '../menu'
-import { useEffect } from 'react'
export function ColumnHeader({
column,
diff --git a/apps/studio/components/grid/components/grid/Grid.tsx b/apps/studio/components/grid/components/grid/Grid.tsx
index dfd01db594a..447ed7e731e 100644
--- a/apps/studio/components/grid/components/grid/Grid.tsx
+++ b/apps/studio/components/grid/components/grid/Grid.tsx
@@ -1,22 +1,20 @@
-/* eslint-disable react/display-name */
-
import AwesomeDebouncePromise from 'awesome-debounce-promise'
import { forwardRef, useRef } from 'react'
import DataGrid, { DataGridHandle, RowsChangeData } from 'react-data-grid'
-import 'react-data-grid/lib/styles.css'
import { memo } from 'react-tracked'
-import { Button } from 'ui'
-import { formatClipboardValue } from 'components/grid/utils'
+import { formatClipboardValue } from 'components/grid/utils/common'
import { ForeignRowSelectorProps } from 'components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/ForeignRowSelector/ForeignRowSelector'
import { useProjectContext } from 'components/layouts/ProjectLayout/ProjectContext'
import AlertError from 'components/ui/AlertError'
import { GenericSkeletonLoader } from 'components/ui/ShimmeringLoader'
import { useForeignKeyConstraintsQuery } from 'data/database/foreign-key-constraints-query'
-import { useKeyboardShortcuts, useUrlState } from 'hooks'
+import { useUrlState } from 'hooks/ui/useUrlState'
import { copyToClipboard } from 'lib/helpers'
-import { useDispatch, useTrackedState } from '../../store'
+import { Button } from 'ui'
+import { useDispatch, useTrackedState } from '../../store/Store'
import type { Filter, GridProps, SupaRow } from '../../types'
+import { useKeyboardShortcuts } from '../common/Hooks'
import RowRenderer from './RowRenderer'
const rowKeyGetter = (row: SupaRow) => {
@@ -102,7 +100,8 @@ export const Grid = memo(
const selectedCellRef = useRef<{ rowIdx: number; row: any; column: any } | null>(null)
function copyCellValue() {
- const selectedCellValue = selectedCellRef.current?.row[selectedCellRef.current?.column?.key]
+ const selectedCellValue =
+ selectedCellRef.current?.row?.[selectedCellRef.current?.column?.key]
const text = formatClipboardValue(selectedCellValue)
if (!text) return
copyToClipboard(text)
diff --git a/apps/studio/components/grid/components/grid/SelectColumn.tsx b/apps/studio/components/grid/components/grid/SelectColumn.tsx
index 42b7aff7b55..56fb381511b 100644
--- a/apps/studio/components/grid/components/grid/SelectColumn.tsx
+++ b/apps/studio/components/grid/components/grid/SelectColumn.tsx
@@ -8,10 +8,10 @@ import {
} from 'react-data-grid'
import { Button, IconMaximize2 } from 'ui'
-import { SELECT_COLUMN_KEY } from '../../constants'
-import { useTrackedState } from '../../store'
-import type { SupaRow } from '../../types'
import { ChangeEvent, InputHTMLAttributes, SyntheticEvent } from 'react'
+import { SELECT_COLUMN_KEY } from '../../constants'
+import { useTrackedState } from '../../store/Store'
+import type { SupaRow } from '../../types'
export const SelectColumn: CalculatedColumn