Merge pull request #13633 from supabase/master

Prod deploy dashboard
This commit is contained in:
Joshen Lim authored and GitHub committed 2023-04-12 14:50:32 +07:00
commit ad60ad2e63
498 files changed
+44563 -40083

No files matched your search

+5 -1
View File
@@ -17,4 +17,8 @@ jobs:
locale: "US"
reporter: github-pr-review
level: error
exclude: "*.css"
exclude: |
"*.css"
"**/package.json"
"**/package-lock.json"
".git/*"
+2 -1
View File
@@ -122,4 +122,5 @@ typings/
apps/new-docs/*
gcloud.json
# For self-hosted logs: https://github.com/supabase/supabase/blob/86e3ab20abfdb9c3e666334d3d2f8efeef9ccf2c/docker/docker-compose-logging.yml#L101
gcloud.json
+2 -1
View File
@@ -13,8 +13,8 @@
- [x] Authentication and Authorization. [Docs](https://supabase.com/docs/guides/auth)
- [x] Auto-generated APIs.
- [x] REST. [Docs](https://supabase.com/docs/guides/database/api#rest-api)
- [x] GraphQL. [Docs](https://supabase.com/docs/guides/database/api#graphql-api)
- [x] Realtime subscriptions. [Docs](https://supabase.com/docs/guides/database/api#realtime-api)
- [x] GraphQL (Beta). [Docs](https://supabase.com/docs/guides/database/api#graphql-api)
- [x] Functions.
- [x] Database Functions. [Docs](https://supabase.com/docs/guides/database/functions)
- [x] Edge Functions [Docs](https://supabase.com/docs/guides/functions)
@@ -63,6 +63,7 @@ You can also [self-host](https://supabase.com/docs/guides/hosting/overview) and
- [PostgreSQL](https://www.postgresql.org/) is an object-relational database system with over 30 years of active development that has earned it a strong reputation for reliability, feature robustness, and performance.
- [Realtime](https://github.com/supabase/realtime) is an Elixir server that allows you to listen to PostgreSQL inserts, updates, and deletes using websockets. Realtime polls Postgres' built-in replication functionality for database changes, converts changes to JSON, then broadcasts the JSON over websockets to authorized clients.
- [PostgREST](http://postgrest.org/) is a web server that turns your PostgreSQL database directly into a RESTful API
- [pg_graphql](http://github.com/supabase/pg_graphql/) a PostgreSQL extension that exposes a GraphQL API
- [Storage](https://github.com/supabase/storage-api) provides a RESTful interface for managing Files stored in S3, using Postgres to manage permissions.
- [postgres-meta](https://github.com/supabase/postgres-meta) is a RESTful API for managing your Postgres, allowing you to fetch tables, add roles, and run queries, etc.
- [GoTrue](https://github.com/netlify/gotrue) is an SWT based API for managing users and issuing SWT tokens.
+37 -23
View File
@@ -5,32 +5,46 @@ const Favicons = () => {
const { basePath } = useRouter()
return (
<Head>
<link
rel="apple-touch-icon"
sizes="180x180"
href={`${basePath}/favicon/apple-touch-icon.png`}
/>
<link
rel="icon"
type="image/png"
sizes="32x32"
href={`${basePath}/favicon/favicon-32x32.png`}
/>
<link
rel="icon"
type="image/png"
sizes="16x16"
href={`${basePath}/favicon/favicon-16x16.png`}
/>
<link rel="manifest" href={`${basePath}/favicon/site.webmanifest`} />
{/* <link rel="mask-icon" href={`${basePath}/favicon/safari-pinned-tab.svg`} color="#333333" /> */}
<link rel="shortcut icon" href={`${basePath}/favicon/favicon.ico`} />
{/* prettier-ignore */}
<link rel="apple-touch-icon-precomposed" sizes="57x57" href={`${basePath}/favicon/apple-touch-icon-57x57.png`}/>
{/* prettier-ignore */}
<link rel="apple-touch-icon-precomposed" sizes="114x114" href={`${basePath}/favicon/apple-touch-icon-114x114.png`}/>
{/* prettier-ignore */}
<link rel="apple-touch-icon-precomposed" sizes="72x72" href={`${basePath}/favicon/apple-touch-icon-72x72.png`}/>
{/* prettier-ignore */}
<link rel="apple-touch-icon-precomposed" sizes="144x144" href={`${basePath}/favicon/apple-touch-icon-144x144.png`}/>
{/* prettier-ignore */}
<link rel="apple-touch-icon-precomposed" sizes="60x60" href={`${basePath}/favicon/apple-touch-icon-60x60.png`}/>
{/* prettier-ignore */}
<link rel="apple-touch-icon-precomposed" sizes="120x120" href={`${basePath}/favicon/apple-touch-icon-120x120.png`}/>
{/* prettier-ignore */}
<link rel="apple-touch-icon-precomposed" sizes="76x76" href={`${basePath}/favicon/apple-touch-icon-76x76.png`}/>
{/* prettier-ignore */}
<link rel="apple-touch-icon-precomposed" sizes="152x152" href={`${basePath}/favicon/apple-touch-icon-152x152.png`}/>
{/* prettier-ignore */}
<link rel="icon" type="image/png" href={`${basePath}/favicon/favicon-196x196.png" sizes="196x196`}/>
{/* prettier-ignore */}
<link rel="icon" type="image/png" href={`${basePath}/favicon/favicon-96x96.png" sizes="96x96`}/>
{/* prettier-ignore */}
<link rel="icon" type="image/png" href={`${basePath}/favicon/favicon-32x32.png" sizes="32x32`}/>
{/* prettier-ignore */}
<link rel="icon" type="image/png" href={`${basePath}/favicon/favicon-16x16.png" sizes="16x16`}/>
{/* prettier-ignore */}
<link rel="icon" type="image/png" href={`${basePath}/favicon/favicon-128.png" sizes="128x128`}/>
<meta name="application-name" content="&nbsp;" />
<meta name="msapplication-TileColor" content="#1E1E1E" />
<meta name="msapplication-config" content={`${basePath}/favicon/browserconfig.xml`} />
<meta name="msapplication-TileImage" content="mstile-144x144.png" />
<meta name="msapplication-square70x70logo" content="mstile-70x70.png" />
<meta name="msapplication-square150x150logo" content="mstile-150x150.png" />
<meta name="msapplication-wide310x150logo" content="mstile-310x150.png" />
<meta name="msapplication-square310x310logo" content="mstile-310x310.png" />
<meta name="theme-color" content="#1E1E1E" />
<link rel="alternate" type="application/rss+xml" href={`${basePath}/feed.xml`} />
<link rel="shortcut icon" href={`${basePath}/favicon/favicon.ico`} />
<link rel="icon" type="image/png" href={`${basePath}/favicon/favicon.ico`} />
<link rel="apple-touch-icon" href={`${basePath}/favicon/favicon.ico`} />
{/* misc */}
<link rel="manifest" href={`${basePath}/favicon/site.webmanifest`} />
<meta name="msapplication-config" content={`${basePath}/favicon/browserconfig.xml`} />
<link rel="alternate" type="application/rss+xml" href={`${basePath}/feed.xml`} />
</Head>
)
}
-207
View File
@@ -1,207 +0,0 @@
import { useTheme } from 'common/Providers'
import Image from 'next/image'
import Link from 'next/link'
import { useRouter } from 'next/router'
import { FC, useEffect, useState } from 'react'
import { IconCommand, IconMenu, IconMoon, IconSearch, IconSun, Listbox, SearchButton } from 'ui'
import { REFERENCES } from './Navigation.constants'
import { getPageType } from '~/lib/helpers'
const NavBar: FC = () => {
const { isDarkMode, toggleTheme } = useTheme()
const [mounted, setMounted] = useState(false)
const [mobileMenuOpen, setMobileMenuOpen] = useState(false)
const { asPath, push } = useRouter()
const pathSegments = asPath.split('/')
const library = pathSegments.length >= 3 ? pathSegments[2] : undefined
const libraryMeta = REFERENCES?.[library] ?? undefined
const versions = libraryMeta?.versions ?? []
const version = versions.includes(pathSegments[pathSegments.indexOf(library) + 1])
? pathSegments[pathSegments.indexOf(library) + 1]
: versions[0]
const pageType = getPageType(asPath)
useEffect(() => {
setMounted(true)
}, [isDarkMode])
const pageLinks = [
{ text: 'Guides', key: 'docs', link: '/' },
{ text: 'Reference', key: 'reference', link: '/reference' },
]
const onSelectVersion = (version: string) => {
// [Joshen] Ideally we use <Link> but this works for now
if (!library) return
if (version === versions[0]) {
push(`/reference/${library}`)
} else {
push(`/reference/${library}/${version}`)
}
}
// [Joshen] Kaizen: Use UI library's SidePanel for this
const toggleMobileMenu = () => {
setMobileMenuOpen(!mobileMenuOpen)
const sidebar = document.querySelector('.sidebar-menu-container')
const contentPane = document.querySelector('.main-content-pane')
sidebar.classList.toggle('hidden')
contentPane.classList.toggle('hidden')
}
return (
<nav
className={[
'sticky top-0 z-10 flex items-center justify-between',
'h-[60px] border-b bg-white px-4 backdrop-blur backdrop-filter',
'dark:border-scale-400 dark:bg-scale-200',
].join(' ')}
>
<div className="flex items-center">
<button className="mr-4 block stroke-2 lg:hidden" onClick={toggleMobileMenu}>
<IconMenu className="text-scale-1100" />
</button>
{mounted && (
<Link href="/">
<a className="flex items-center">
<Image
className="cursor-pointer"
src={isDarkMode ? '/docs/supabase-dark.svg' : '/docs/supabase-light.svg'}
width={124}
height={24}
alt="Supabase Logo"
/>
</a>
</Link>
)}
<nav className="ml-8 hidden lg:flex">
<ul className="hidden space-x-8 lg:flex">
{pageLinks.map((p) => (
<li key={`${p.text}-${p.link}`}>
<Link href={p.link}>
<a
className={`text-sm ${
pageType.includes(p.key) ? 'text-brand-900' : 'text-scale-1100'
}`}
>
{p.text}
</a>
</Link>
</li>
))}
</ul>
</nav>
{versions.length > 0 && (
<div className="ml-8">
<Listbox
size="small"
defaultValue={version}
style={{ width: '70px' }}
onChange={onSelectVersion}
>
{versions.map((version) => (
<Listbox.Option key={version} label={version} value={version}>
{version}
</Listbox.Option>
))}
</Listbox>
</div>
)}
</div>
<div className="flex items-center space-x-4">
<div className="hidden items-center md:flex">
<ul className="flex items-center">
<li className="px-4">
<a
href="https://app.supabase.com"
className="text-scale-1100 text-sm"
target="_blank"
rel="noreferrer noopener"
>
Dashboard
</a>
</li>
<li className="px-4">
<a
href="https://github.com/supabase/supabase"
target="_blank"
rel="noreferrer noopener"
>
<div
className="h-4 w-4 !bg-no-repeat !bg-center"
style={{
background: isDarkMode
? "url(\"data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%23fff' d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E\") 50% no-repeat"
: "url(\"data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E\")",
}}
/>
</a>
</li>
<li className="px-4">
<a
href="https://discord.supabase.com"
rel="noreferrer noopener"
target="_blank"
className="text-scale-1100"
>
<div
className="h-4 w-4 !bg-no-repeat !bg-center"
style={{
background: isDarkMode
? "url(\"data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 71 55' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cg clip-path='url(%23a)'%3E%3Cpath d='M60.105 4.898A58.55 58.55 0 0 0 45.653.415a.22.22 0 0 0-.233.11 40.784 40.784 0 0 0-1.8 3.697c-5.456-.817-10.886-.817-16.23 0-.485-1.164-1.201-2.587-1.828-3.697a.228.228 0 0 0-.233-.11 58.386 58.386 0 0 0-14.451 4.483.207.207 0 0 0-.095.082C1.578 18.73-.944 32.144.293 45.39a.244.244 0 0 0 .093.167c6.073 4.46 11.955 7.167 17.729 8.962a.23.23 0 0 0 .249-.082 42.08 42.08 0 0 0 3.627-5.9.225.225 0 0 0-.123-.312 38.772 38.772 0 0 1-5.539-2.64.228.228 0 0 1-.022-.378c.372-.279.744-.569 1.1-.862a.22.22 0 0 1 .23-.03c11.619 5.304 24.198 5.304 35.68 0a.219.219 0 0 1 .233.027c.356.293.728.586 1.103.865a.228.228 0 0 1-.02.378 36.384 36.384 0 0 1-5.54 2.637.227.227 0 0 0-.121.315 47.249 47.249 0 0 0 3.624 5.897.225.225 0 0 0 .249.084c5.801-1.794 11.684-4.502 17.757-8.961a.228.228 0 0 0 .092-.164c1.48-15.315-2.48-28.618-10.497-40.412a.18.18 0 0 0-.093-.084Zm-36.38 32.427c-3.497 0-6.38-3.211-6.38-7.156 0-3.944 2.827-7.156 6.38-7.156 3.583 0 6.438 3.24 6.382 7.156 0 3.945-2.827 7.156-6.381 7.156Zm23.593 0c-3.498 0-6.38-3.211-6.38-7.156 0-3.944 2.826-7.156 6.38-7.156 3.582 0 6.437 3.24 6.38 7.156 0 3.945-2.798 7.156-6.38 7.156Z' fill='%23fff'/%3E%3C/g%3E%3Cdefs%3E%3CclipPath id='a'%3E%3Cpath fill='%23fff' d='M0 0h71v55H0z'/%3E%3C/clipPath%3E%3C/defs%3E%3C/svg%3E\") 50% no-repeat"
: "url(\"data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 71 55' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cg clip-path='url(%23a)'%3E%3Cpath d='M60.105 4.898A58.55 58.55 0 0 0 45.653.415a.22.22 0 0 0-.233.11 40.784 40.784 0 0 0-1.8 3.697c-5.456-.817-10.886-.817-16.23 0-.485-1.164-1.201-2.587-1.828-3.697a.228.228 0 0 0-.233-.11 58.386 58.386 0 0 0-14.451 4.483.207.207 0 0 0-.095.082C1.578 18.73-.944 32.144.293 45.39a.244.244 0 0 0 .093.167c6.073 4.46 11.955 7.167 17.729 8.962a.23.23 0 0 0 .249-.082 42.08 42.08 0 0 0 3.627-5.9.225.225 0 0 0-.123-.312 38.772 38.772 0 0 1-5.539-2.64.228.228 0 0 1-.022-.378c.372-.279.744-.569 1.1-.862a.22.22 0 0 1 .23-.03c11.619 5.304 24.198 5.304 35.68 0a.219.219 0 0 1 .233.027c.356.293.728.586 1.103.865a.228.228 0 0 1-.02.378 36.384 36.384 0 0 1-5.54 2.637.227.227 0 0 0-.121.315 47.249 47.249 0 0 0 3.624 5.897.225.225 0 0 0 .249.084c5.801-1.794 11.684-4.502 17.757-8.961a.228.228 0 0 0 .092-.164c1.48-15.315-2.48-28.618-10.497-40.412a.18.18 0 0 0-.093-.084Zm-36.38 32.427c-3.497 0-6.38-3.211-6.38-7.156 0-3.944 2.827-7.156 6.38-7.156 3.583 0 6.438 3.24 6.382 7.156 0 3.945-2.827 7.156-6.381 7.156Zm23.593 0c-3.498 0-6.38-3.211-6.38-7.156 0-3.944 2.826-7.156 6.38-7.156 3.582 0 6.437 3.24 6.38 7.156 0 3.945-2.798 7.156-6.38 7.156Z' fill='%2323272A'/%3E%3C/g%3E%3Cdefs%3E%3CclipPath id='a'%3E%3Cpath fill='%23fff' d='M0 0h71v55H0z'/%3E%3C/clipPath%3E%3C/defs%3E%3C/svg%3E\")",
}}
/>
</a>
</li>
<li className="px-4">
<a href="https://twitter.com/supabase" target="_blank" rel="noreferrer noopener">
<div
className="h-4 w-4 !bg-no-repeat !bg-center"
style={{
background: isDarkMode
? "url(\"data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 335 276' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%23fff' d='M302 70A195 195 0 0 1 3 245a142 142 0 0 0 97-30 70 70 0 0 1-58-47 70 70 0 0 0 31-2 70 70 0 0 1-57-66 70 70 0 0 0 28 5 70 70 0 0 1-18-90 195 195 0 0 0 141 72 67 67 0 0 1 116-62 117 117 0 0 0 43-17 65 65 0 0 1-31 38 117 117 0 0 0 39-11 65 65 0 0 1-32 35'/%3E%3C/svg%3E\") 50% no-repeat"
: "url(\"data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 335 276' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M302 70A195 195 0 0 1 3 245a142 142 0 0 0 97-30 70 70 0 0 1-58-47 70 70 0 0 0 31-2 70 70 0 0 1-57-66 70 70 0 0 0 28 5 70 70 0 0 1-18-90 195 195 0 0 0 141 72 67 67 0 0 1 116-62 117 117 0 0 0 43-17 65 65 0 0 1-31 38 117 117 0 0 0 39-11 65 65 0 0 1-32 35'/%3E%3C/svg%3E\")",
}}
/>
</a>
</li>
<li className="px-4">
<div className="cursor-pointer" onClick={() => toggleTheme()}>
{isDarkMode ? (
<IconMoon size={18} strokeWidth={2} className="text-scale-1200" />
) : (
<IconSun size={18} strokeWidth={2} className="text-scale-1200" />
)}
</div>
</li>
</ul>
</div>
<SearchButton>
<div className="flex items-center justify-between space-x-6 bg-scale-300 border border-scale-700 pl-3 pr-1.5 py-1.5 rounded">
<div className="flex items-center space-x-2">
<IconSearch className="text-scale-1100" size={18} strokeWidth={2} />
<p className="text-scale-800 text-sm">Search</p>
</div>
<div className="flex items-center space-x-1">
<div className="hidden text-scale-1200 md:flex items-center justify-center h-6 w-6 rounded bg-scale-500">
<IconCommand size={12} strokeWidth={1.5} />
</div>
<div className="hidden text-xs text-scale-1200 md:flex items-center justify-center h-6 w-6 rounded bg-scale-500">
K
</div>
</div>
</div>
</SearchButton>
</div>
</nav>
)
}
export default NavBar
@@ -1,431 +0,0 @@
// [Terry] Also need to look at getPageType() in ./lib/helpers
// to set a menu to a page
import SupabaseJsV1Nav from 'data/nav/supabase-js/v1'
import SupabaseJsV2Nav from 'data/nav/supabase-js/v2'
import SupabaseDartV0Nav from 'data/nav/supabase-dart/v0'
import SupabaseDartV1Nav from 'data/nav/supabase-dart/v1'
import SupabaseCLINav from 'data/nav/supabase-cli'
import SupabaseAPINav from 'data/nav/supabase-api'
import AuthServerNav from 'data/nav/auth-server'
import RealtimeServerNav from 'data/nav/realtime-server'
import StorageServerNav from 'data/nav/storage-server'
import { NavMenu, References } from './Navigation.types'
export const REFERENCES: References = {
javascript: {
name: 'supabase-js',
library: 'supabase-js',
versions: ['v2', 'v1'],
icon: '/docs/img/icons/javascript-icon.svg',
},
dart: {
name: 'Flutter',
library: 'supabase-dart',
versions: ['v1', 'v0'],
icon: '/docs/img/icons/flutter-icon.svg',
},
cli: {
name: 'CLI',
library: undefined,
versions: [],
icon: '/docs/img/icons/cli-icon.svg',
},
api: {
name: 'API',
library: undefined,
versions: [],
icon: '/docs/img/icons/api-icon.svg',
},
}
export const menuItems: NavMenu = {
docs: [
{
label: 'Overview',
items: [
{ name: 'Introduction', url: '/', items: [] },
{ name: 'Features', url: '/features', items: [] },
{ name: 'Architecture', url: '/architecture', items: [] },
],
},
{
label: 'Quickstarts',
items: [
{ name: 'Angular', url: '/guides/with-angular', items: [] },
{ name: 'Expo', url: '/guides/with-expo', items: [] },
{ name: 'Flutter', url: '/guides/with-flutter', items: [] },
{ name: 'Ionic Angular', url: '/guides/with-ionic-angular', items: [] },
{ name: 'Ionic React', url: '/guides/with-ionic-react', items: [] },
{ name: 'Ionic Vue', url: '/guides/with-ionic-vue', items: [] },
{ name: 'Next.js', url: '/guides/with-nextjs', items: [] },
{ name: 'Nuxt 3', url: '/guides/with-nuxt-3', items: [] },
{ name: 'React', url: '/guides/with-react', items: [] },
{ name: 'RedwoodJS', url: '/guides/with-redwoodjs', items: [] },
{ name: 'SolidJS', url: '/guides/with-solidjs', items: [] },
{ name: 'Svelte', url: '/guides/with-svelte', items: [] },
{ name: 'SvelteKit', url: '/guides/with-sveltekit', items: [] },
{ name: 'Vue 3', url: '/guides/with-vue-3', items: [] },
],
},
{
label: 'CLI',
items: [
{ name: 'Overview', url: '/guides/cli', items: [] },
{ name: 'Local Development', url: '/guides/cli/local-development', items: [] },
{ name: 'Managing Environments', url: '/guides/cli/managing-environments', items: [] },
],
},
{
label: 'Auth',
items: [
{ name: 'Overview', url: '/guides/auth', items: [] },
{ name: 'Quickstarts', url: '/guides/auth/quickstarts/react', items: [] },
{
name: 'Authentication',
url: undefined,
items: [
{ name: 'Login with Email', url: '/guides/auth/auth-email', items: [] },
{ name: 'Login with Magic Link', url: '/guides/auth/auth-magic-link', items: [] },
{ name: 'Login with Apple', url: '/guides/auth/auth-apple', items: [] },
{ name: 'Login with Azure', url: '/guides/auth/auth-azure', items: [] },
{ name: 'Login with Bitbucket', url: '/guides/auth/auth-bitbucket', items: [] },
{ name: 'Login with Discord', url: '/guides/auth/auth-discord', items: [] },
{ name: 'Login with Facebook', url: '/guides/auth/auth-facebook', items: [] },
{ name: 'Login with Github', url: '/guides/auth/auth-github', items: [] },
{ name: 'Login with Gitlab', url: '/guides/auth/auth-gitlab', items: [] },
{ name: 'Login with Google', url: '/guides/auth/auth-google', items: [] },
{ name: 'Login with Keycloak', url: '/guides/auth/auth-keycloak', items: [] },
{ name: 'Login with LinkedIn', url: '/guides/auth/auth-linkedin', items: [] },
{ name: 'Login with Notion', url: '/guides/auth/auth-notion', items: [] },
{ name: 'Login with Slack', url: '/guides/auth/auth-slack', items: [] },
{ name: 'Login with Spotify', url: '/guides/auth/auth-spotify', items: [] },
{ name: 'Login with Twitch', url: '/guides/auth/auth-twitch', items: [] },
{ name: 'Login with Twitter', url: '/guides/auth/auth-twitter', items: [] },
{ name: 'Login with WorkOS', url: '/guides/auth/auth-workos', items: [] },
{ name: 'Login with Zoom', url: '/guides/auth/auth-zoom', items: [] },
{ name: 'Phone Auth with Twilio', url: '/guides/auth/auth-twilio', items: [] },
{ name: 'Phone Auth with Vonage', url: '/guides/auth/auth-vonage', items: [] },
{
name: 'Phone Auth with MessageBird',
url: '/guides/auth/auth-messagebird',
items: [],
},
],
},
{
name: 'Authorization',
url: undefined,
items: [
{ name: 'Row Level Security', url: '/guides/auth/row-level-security', items: [] },
{ name: 'Managing User Data', url: '/guides/auth/managing-user-data', items: [] },
{ name: 'Enable Captcha Protection', url: '/guides/auth/auth-captcha', items: [] },
{ name: 'Server-side Rendering', url: '/guides/auth/server-side-rendering', items: [] },
{ name: 'Multi-Factor Authentication', url: '/guides/auth/auth-mfa', items: [] },
],
},
{
name: 'Auth Helpers',
url: undefined,
items: [
{ name: 'Overview', url: '/guides/auth/auth-helpers', items: [] },
{ name: 'Auth UI', url: '/guides/auth/auth-helpers/auth-ui', items: [] },
{ name: 'Next.js (pages)', url: '/guides/auth/auth-helpers/nextjs', items: [] },
{
name: 'Next.js (app)',
url: '/guides/auth/auth-helpers/nextjs-server-components',
items: [],
},
{ name: 'SvelteKit', url: '/guides/auth/auth-helpers/sveltekit', items: [] },
{ name: 'Remix', url: '/guides/auth/auth-helpers/remix', items: [] },
],
},
{
name: 'Deep Dive',
url: undefined,
items: [
{
name: 'Part One: JWTs',
url: '/learn/auth-deep-dive/auth-deep-dive-jwts',
items: [],
},
{
name: 'Part Two: Row Level Security',
url: '/learn/auth-deep-dive/auth-row-level-security',
items: [],
},
{ name: 'Part Three: Policies', url: '/learn/auth-deep-dive/auth-policies', items: [] },
{ name: 'Part Four: GoTrue', url: '/learn/auth-deep-dive/auth-gotrue', items: [] },
{
name: 'Part Five: Google OAuth',
url: '/learn/auth-deep-dive/auth-google-oauth',
items: [],
},
],
},
],
},
{
label: 'Database',
items: [
{ name: 'Overview', url: '/guides/database', items: [] },
{ name: 'Database Connections', url: '/guides/database/connecting-to-postgres', items: [] },
{ name: 'Tables and Data', url: '/guides/database/tables', items: [] },
{ name: 'Database Functions', url: '/guides/database/functions', items: [] },
{ name: 'Database Webhooks', url: '/guides/database/webhooks', items: [] },
{ name: 'Full Text Search', url: '/guides/database/full-text-search', items: [] },
{ name: 'Database Testing', url: '/guides/database/testing', items: [] },
{
name: 'Extensions',
url: undefined,
items: [
{ name: 'Overview', url: '/guides/database/extensions', items: [] },
{ name: 'http: RESTful Client', url: '/guides/database/extensions/http', items: [] },
{
name: 'pg_cron: Job Scheduling',
url: '/guides/database/extensions/pgcron',
items: [],
},
{
name: 'pg_net: Async Networking',
url: '/guides/database/extensions/pgnet',
items: [],
},
{ name: 'pgTAP: Unit Testing', url: '/guides/database/extensions/pgtap', items: [] },
{
name: 'plv8: Javascript Language',
url: '/guides/database/extensions/plv8',
items: [],
},
{
name: 'PostGIS: Geo queries',
url: '/guides/database/extensions/postgis',
items: [],
},
{
name: 'uuid-ossp: Unique Identifiers',
url: '/guides/database/extensions/uuid-ossp',
items: [],
},
],
},
{
name: 'Configuration',
url: undefined,
items: [
{ name: 'Timeouts', url: '/guides/database/timeouts', items: [] },
{ name: 'Replication', url: '/guides/database/replication', items: [] },
{ name: 'Passwords', url: '/guides/database/managing-passwords', items: [] },
{ name: 'Timezones', url: '/guides/database/managing-timezones', items: [] },
],
},
],
},
{
label: 'Serverless APIs',
items: [
{ name: 'Overview', url: '/guides/api', items: [] },
{ name: 'Generating Types', url: '/guides/api/generating-types', items: [] },
],
},
{
label: 'Edge Functions',
items: [
{ name: 'Overview', url: '/guides/functions', items: [] },
{ name: 'Quickstart', url: '/guides/functions/quickstart', items: [] },
{ name: 'Auth', url: '/guides/functions/auth', items: [] },
{ name: 'Best Practices', url: '/guides/functions/best-practices', items: [] },
{ name: 'CI/CD Workflow', url: '/guides/functions/cicd-workflow', items: [] },
],
},
{
label: 'Realtime',
items: [
{
name: 'Overview',
url: '/guides/realtime',
items: [],
},
{
name: 'Quickstart',
url: '/guides/realtime/quickstart',
items: [],
},
{
name: 'Features',
url: undefined,
items: [
{ name: 'Channels', url: '/guides/realtime/channels', items: [] },
{
name: 'Extensions',
url: '/guides/realtime/extensions',
items: [
{ name: 'Broadcast', url: '/guides/realtime/broadcast', items: [] },
{ name: 'Presence', url: '/guides/realtime/presence', items: [] },
{ name: 'Postgres Changes', url: '/guides/realtime/postgres-changes', items: [] },
],
},
],
},
{
name: 'Guides',
url: undefined,
items: [
{
name: 'Subscribing to Database Changes',
url: '/guides/realtime/subscribing-to-database-changes',
items: [],
},
{
name: 'Bring Your Own Database',
url: '/guides/realtime/bring-your-own-database',
items: [],
},
{
name: 'Using Realtime with Next.js',
url: '/guides/realtime/realtime-with-nextjs',
items: [],
},
],
},
{
name: 'Deep dive',
url: undefined,
items: [
{ name: 'Rate Limits', url: '/guides/realtime/rate-limits', items: [] },
{ name: 'Architecture', url: '/guides/realtime/architecture', items: [] },
{ name: 'Protocol', url: '/guides/realtime/protocol', items: [] },
],
},
],
},
{
label: 'Storage',
items: [
{ name: 'Overview', url: '/guides/storage', items: [] },
{ name: 'Quickstart', url: '/guides/storage/quickstart', items: [] },
{ name: 'Access Control', url: '/guides/storage/access-control', items: [] },
{ name: 'CDN', url: '/guides/storage/cdn', items: [] },
{ name: 'Image Transformations', url: '/guides/storage/image-transformations', items: [] },
],
},
{
label: 'Platform',
items: [
{ name: 'Overview', url: '/guides/platform', items: [] },
{ name: 'Compute Add-ons', url: '/guides/platform/compute-add-ons', items: [] },
{ name: 'Custom Domains', url: '/guides/platform/custom-domains', items: [] },
{ name: 'Database Usage', url: '/guides/platform/database-usage', items: [] },
{ name: 'HTTP Status Codes', url: '/guides/platform/http-status-codes', items: [] },
{ name: 'Logging', url: '/guides/platform/logs', items: [] },
{ name: 'Metrics', url: '/guides/platform/metrics', items: [] },
{
name: 'Migrating and upgrading',
url: '/guides/platform/migrating-and-upgrading-projects',
items: [],
},
{ name: 'Network Restrictions', url: '/guides/platform/network-restrictions', items: [] },
{ name: 'Performance Tuning', url: '/guides/platform/performance', items: [] },
{ name: 'Permissions', url: '/guides/platform/permissions', items: [] },
{ name: 'Production Readiness', url: '/guides/platform/going-into-prod', items: [] },
{ name: 'SSL Enforcement', url: '/guides/platform/ssl-enforcement', items: [] },
{ name: 'Troubleshooting', url: '/guides/platform/troubleshooting', items: [] },
],
},
{
label: 'Self Hosting',
items: [
{ name: 'Overview', url: '/guides/hosting/overview', items: [] },
{ name: 'Docker', url: '/guides/hosting/docker', items: [] },
],
},
{
label: 'Migrate to Supabase',
items: [
{ name: 'Firebase Auth', url: '/guides/migrations/firebase-auth', items: [] },
{ name: 'Firestore Data', url: '/guides/migrations/firestore-data', items: [] },
{ name: 'Firebase Storage', url: '/guides/migrations/firebase-storage', items: [] },
{ name: 'Heroku', url: '/guides/migrations/heroku', items: [] },
],
},
{
label: 'Integrations',
items: [
{ name: 'Supabase Marketplace', url: '/guides/integrations/integrations', items: [] },
{
name: 'Auth',
url: undefined,
items: [
{ name: 'Auth0', url: '/guides/integrations/auth0', items: [] },
{ name: 'Authsignal', url: '/guides/integrations/authsignal', items: [] },
{ name: 'Clerk', url: '/guides/integrations/clerk', items: [] },
{ name: 'keyri', url: '/guides/integrations/keyri', items: [] },
{ name: 'Picket', url: '/guides/integrations/picket', items: [] },
{ name: 'Stytch', url: '/guides/integrations/stytch', items: [] },
{ name: 'SuperTokens', url: '/guides/integrations/supertokens', items: [] },
],
},
{
name: 'Caching / Offline-first',
url: undefined,
items: [{ name: 'Polyscale', url: '/guides/integrations/polyscale', items: [] }],
},
{
name: 'Developer Tools',
url: undefined,
items: [
{ name: 'Estuary', url: '/guides/integrations/estuary', items: [] },
{ name: 'pgMustard', url: '/guides/integrations/pgmustard', items: [] },
{ name: 'Prisma', url: '/guides/integrations/prisma', items: [] },
{ name: 'Sequin', url: '/guides/integrations/sequin', items: [] },
{ name: 'Snaplet', url: '/guides/integrations/snaplet', items: [] },
{ name: 'Vercel', url: '/guides/integrations/vercel', items: [] },
{ name: 'Zuplo', url: '/guides/integrations/zuplo', items: [] },
],
},
{
name: 'Low-code',
url: undefined,
items: [
{ name: 'Appsmith', url: '/guides/integrations/appsmith', items: [] },
{ name: 'DhiWise', url: '/guides/integrations/dhiwise', items: [] },
{ name: 'Directus', url: '/guides/integrations/directus', items: [] },
{ name: 'Draftbit', url: '/guides/integrations/draftbit', items: [] },
{ name: 'Plasmic', url: '/guides/integrations/plasmic', items: [] },
{ name: 'WeWeb', url: '/guides/integrations/weweb', items: [] },
{ name: 'ILLA', url: '/guides/integrations/illa', items: [] },
],
},
],
},
],
reference: [
{
label: 'Official',
items: [
{ name: 'Reference Documentation', url: '/reference', items: [] },
{ name: 'Supabase JavaScript Library', url: '/reference/javascript', items: [] },
{ name: 'Supabase Flutter Library', url: '/reference/dart', items: [] },
{ name: 'Supabase CLI', url: '/reference/cli', items: [] },
{ name: 'Management API', url: '/reference/api', items: [] },
],
},
{
label: 'Self-hosting',
items: [
{ name: 'Auth Server', url: '/reference/auth', items: [] },
{ name: 'Realtime Server', url: '/reference/realtime', items: [] },
{ name: 'Storage Server', url: '/reference/storage', items: [] },
],
},
],
'reference/javascript': SupabaseJsV2Nav,
'reference/javascript/v1': SupabaseJsV1Nav,
'reference/dart': SupabaseDartV1Nav,
'reference/dart/v0': SupabaseDartV0Nav,
'reference/cli': SupabaseCLINav,
'reference/api': SupabaseAPINav,
'reference/auth': AuthServerNav,
'reference/realtime': RealtimeServerNav,
'reference/storage': StorageServerNav,
}
@@ -1,13 +1,4 @@
// import SupabaseJsV1Nav from 'data/nav/supabase-js/v1'
// import SupabaseJsV2Nav from 'data/nav/supabase-js/v2'
// import SupabaseDartV0Nav from 'data/nav/supabase-dart/v0'
// import SupabaseDartV1Nav from 'data/nav/supabase-dart/v1'
// import SupabaseCLINav from 'data/nav/supabase-cli'
// import SupabaseAPINav from 'data/nav/supabase-api'
// import AuthServerNav from 'data/nav/auth-server'
// import StorageServerNav from 'data/nav/storage-server'
import { NavMenu, References } from '../Navigation.types'
import { References } from '../Navigation.types'
export const REFERENCES: References = {
javascript: {
@@ -54,12 +45,13 @@ export const gettingstarted = {
items: [
{ name: 'Features', url: '/guides/getting-started/features' },
{ name: 'Architecture', url: '/guides/getting-started/architecture' },
{ name: 'Local Development', url: '/guides/cli/local-development' },
// { name: 'Local Development', url: '/guides/cli/local-development' }, // Disabling this until we actually move the doc into this section
{
name: 'Framework Quickstarts',
items: [
{ name: 'React', url: '/guides/getting-started/quickstarts/reactjs' },
{ name: 'NextJS', url: '/guides/getting-started/quickstarts/nextjs' },
{ name: 'RedwoodJS', url: '/guides/getting-started/quickstarts/redwoodjs' },
{ name: 'Flutter', url: '/guides/getting-started/quickstarts/flutter' },
{ name: 'SvelteKit', url: '/guides/getting-started/quickstarts/sveltekit' },
{ name: 'SolidJS', url: '/guides/getting-started/quickstarts/solidjs' },
@@ -133,6 +125,15 @@ export const gettingstarted = {
},
],
},
{
name: 'AI & ML',
items: [
{
name: 'Vector Search with OpenAI',
url: '/guides/getting-started/openai/vector-search',
},
],
},
],
}
@@ -801,6 +802,11 @@ export const resources = {
name: 'Render',
url: '/guides/resources/migrating-to-supabase/render',
},
{
name: 'Amazon RDS',
url: '/guides/resources/migrating-to-supabase/amazon-rds',
items: [],
},
],
},
],
@@ -853,6 +859,7 @@ export const migrate = {
{ name: 'Firebase Storage', url: '/guides/migrations/firebase-storage' },
{ name: 'Heroku', url: '/guides/migrations/heroku' },
{ name: 'Render', url: '/guides/migrations/render' },
{ name: 'Amazon RDS', url: '/guides/migrations/amazon-rds' },
],
}
@@ -86,7 +86,7 @@ const NavigationMenuCliList = ({ currentLevel, setLevel, id }) => {
return (
<div
className={[
'transition-all ml-8 duration-150 ease-out',
'transition-all duration-150 ease-out',
// enabled
currentLevel === id && 'opacity-100 ml-0 delay-150 h-auto',
// move menu back to margin-left
@@ -4,7 +4,6 @@ import Link from 'next/link'
import { useRouter } from 'next/router'
import React from 'react'
import { IconChevronLeft } from '~/../../packages/ui'
import * as NavItems from './NavigationMenu.constants'
import * as Accordion from '@radix-ui/react-accordion'
const HeaderImage = React.memo(function HeaderImage(props: any) {
@@ -32,7 +32,7 @@ const NavigationMenuRefList: React.FC<INavigationMenuRefList> = ({
return (
<div
className={[
'transition-all ml-8 duration-150 ease-out',
'transition-all duration-150 ease-out',
// enabled
active && 'opacity-100 ml-0 delay-150 h-auto',
// move menu back to margin-left
@@ -13,9 +13,7 @@ import {
Listbox,
SearchButton,
} from 'ui'
import { REFERENCES } from '~/components/Navigation/Navigation.constants'
import { getPageType } from '~/lib/helpers'
import { REFERENCES } from './NavigationMenu.constants'
const TopNavBar: FC = () => {
const { isDarkMode, toggleTheme } = useTheme()
@@ -33,17 +31,10 @@ const TopNavBar: FC = () => {
? pathSegments[pathSegments.indexOf(library) + 1]
: versions[0]
const pageType = getPageType(asPath)
useEffect(() => {
setMounted(true)
}, [isDarkMode])
const pageLinks = [
{ text: 'Guides', key: 'docs', link: '/' },
{ text: 'Reference', key: 'reference', link: '/reference' },
]
const onSelectVersion = (version: string) => {
// [Joshen] Ideally we use <Link> but this works for now
if (!library) return
@@ -4,9 +4,9 @@ import Link from 'next/link'
import { useRouter } from 'next/router'
import { FC, useEffect, useState } from 'react'
import { Button, IconCommand, IconGitHub, IconMoon, IconSearch, IconSun, SearchButton } from 'ui'
import { REFERENCES } from '~/components/Navigation/Navigation.constants'
import { getPageType } from '~/lib/helpers'
import { REFERENCES } from './NavigationMenu.constants'
const TopNavBarRef: FC = () => {
const { isDarkMode, toggleTheme } = useTheme()
+2 -1
View File
@@ -2,7 +2,8 @@ import Link from 'next/link'
import Image from 'next/image'
import { useRouter } from 'next/router'
import { IconChevronRight, IconArrowLeft } from '~/../../packages/ui'
import { REFERENCES } from './Navigation.constants'
import { REFERENCES } from './NavigationMenu/NavigationMenu.constants'
import { NavMenuGroup, NavMenuSection } from './Navigation.types'
import * as Accordion from '@radix-ui/react-accordion'
@@ -14,6 +14,8 @@ export type Flag = {
default_value: string
accepted_values: AcceptedValue[]
required?: boolean
/** Whether subcommands inherit this flag. */
inherit?: boolean
}
export type AcceptedValue = {
@@ -46,6 +48,14 @@ export type Command = {
const CliCommandSection = (props) => {
const command = spec.commands.find((x: any) => x.id === props.funcData.id)
const parentCommand = spec.commands.find(
(x: any) => x.subcommands && x.subcommands.find((y: any) => y === props.funcData.id)
)
const commandFlags = [
...(parentCommand?.flags?.filter((x: any) => x.inherit) || []),
...command.flags,
]
return (
<RefSubLayout.Section
@@ -76,7 +86,7 @@ const CliCommandSection = (props) => {
)}
</header>
{command.subcommands.length > 0 && (
{command.subcommands?.length > 0 && (
<div className="mb-3">
<h3 className="text-lg text-scale-1200 mb-3">Available Commands</h3>
<ul>
@@ -96,11 +106,11 @@ const CliCommandSection = (props) => {
</ul>
</div>
)}
{command.flags.length > 0 && (
{commandFlags.length > 0 && (
<>
<h3 className="text-lg text-scale-1200 mb-3">Flags</h3>
<ul className="">
{command.flags.map((flag: Flag) => (
{commandFlags.map((flag: Flag) => (
<>
<li className="mt-0">
<Param {...flag} isOptional={!flag.required}>
+5
View File
@@ -160,6 +160,11 @@ const Nav = [
url: '/reference/javascript/storage-from-createsignedurls',
items: [],
},
{
name: 'from.createSignedUploadUrl()',
url: '/reference/javascript/storage-from-createsigneduploadurl',
items: [],
},
{
name: 'from.getPublicUrl()',
url: '/reference/javascript/storage-from-getpublicurl',
@@ -19,3 +19,14 @@ hideTitle: true
changes, invoke Deno Edge Functions, build login and user management functionality, and manage
large files.
</div>
<div className="max-w-xl bg-slate-300 px-4 py-2 rounded-md">
<p>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.</p>
<p>
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).
</p>
<p>
Shoutout to [timkpaine](https://github.com/timkpaine) for maintaining our Conda libraries as well.
</p>
</div>
@@ -26,8 +26,57 @@ However, it's important to note that certain [differences](#differences) may ari
## Getting Started
### Pre-requisites
Logflare currently requires BigQuery usage. You will need to create a Google Cloud project with billing enabled.
The requirements are as follows after creating the project:
- Project ID
- Project number
- A service account key
#### Setting up BigQuery Service Account
To ensure that you have sufficient permissions to insert into your Google Cloud BigQuery, ensure that you have created a service account with either:
- BigQuery Admin role; or
- The following permissions:
- bigquery.datasets.create
- bigquery.datasets.get
- bigquery.datasets.getIamPolicy
- bigquery.datasets.update
- bigquery.jobs.create
- bigquery.routines.create
- bigquery.routines.update
- bigquery.tables.create
- bigquery.tables.delete
- bigquery.tables.get
- bigquery.tables.getData
- bigquery.tables.update
- bigquery.tables.updateData
You can create the service account via the web console or `gcloud`, as per the [Google Cloud documentation](https://cloud.google.com/iam/docs/keys-create-delete). In the web console, you can create the key by navigating to IAM > Service Accounts > Actions (dropdown) > Manage Keys
We recommend setting the BigQuery Admin role, as it simplifies permissions setup.
#### Downloading the Service Account key
After the service account is created, you will need to create a key for the service account. This key will sign the JWTs for API requests that the Analytics server makes with BigQuery.
### Docker Compose
Using the example [self-hosting stack based on docker-compose](https://github.com/supabase/supabase/tree/master/docker), you include the logging related services using the following command
You will first need to update the `.env.example` file with the necessary environment variables.
- `GOOGLE_PROJECT_ID`
- `GOOGLE_PROJECT_NUMBER`
You will need to place your Service Account key in your present working directory with the filename `gcloud.json`.
Thereafter, you can run the docker-compose commands and include the logging-specific compose file.
```bash
# assuming you clone the supabase/supabase repo.
cd docker
@@ -41,6 +90,18 @@ This would include two additional docker services to your compose stack: Logflar
server.
</Admonition>
#### Vector Usage
In the Docker Compose example, we utilize vector to coordinate the logging pipeline between the services. However, if you peer into the [vector configuration file](https://github.com/supabase/supabase/blob/master/docker/volumes/logs/vector.yml), you will be able to see that Vector sends logs to the Analytics ingestion endpoint.
If you need to customize the logging pipeline for your own needs, you must ensure that the payloads matches the expected event schema structure. Without the correct structure, it would cause the Studio Logs UI features to break.
### Standalone Docker Container
If desired, you can utilize the standalone docker-container. Please refer to the [docker-compose file](https://github.com/supabase/supabase/tree/master/docker/docker-compose-logging.yml) for required docker configuration.
Additional supplementary technical documentation on self-hosting and using the `supabase/logflare` image for a full Logflare experience is available at the [official Logflare documentation](https://docs.logflare.app/self-hosting/).
## Differences
API logs rely on Kong instead of the Supabase Cloud API Gateway. Logs from Kong are not enriched with platform-only data.
@@ -98,7 +159,6 @@ The self-hosted example is only used as a minimal example on running the entire
### Additional links
- [Source code](https://github.com/logflare/logflare)
- [Analytics guides](/docs/guides/analytics) - TODO
- [OpenAPI docs](https://logflare.app/api/openapi)
- [Supabase Acquires Logflare](https://supabase.com/blog/supabase-acquires-logflare)
- [Logflare self-hosting docs](https://docs.logflare.app/self-hosting)
+1
View File
@@ -2,6 +2,7 @@ import * as _ from 'lodash'
import * as fs from 'fs'
export const slugify = (text: string) => {
if (!text) return ''
return text
.toString()
.toLowerCase()
-14
View File
@@ -314,20 +314,6 @@ const NavContainer = memo(function NavContainer() {
})
const SiteLayout = ({ children }) => {
// const mobileMenuOpen = useMenuMobileOpen()
useEffect(() => {
const key = localStorage.getItem('supabaseDarkMode')
if (!key) {
// Default to dark mode if no preference config
document.documentElement.className = 'dark'
document.documentElement.style.colorScheme = 'dark'
} else {
document.documentElement.className = key === 'true' ? 'dark' : ''
document.documentElement.style.colorScheme = key === 'true' ? 'dark' : ''
}
}, [])
return (
<>
<Head>
@@ -14,19 +14,8 @@ interface Props {
}
const Layout: FC<Props> = (props: Props) => {
// const contentString = renderToString(props.children)
const [active, setActive] = useState(false)
useEffect(() => {
const key = localStorage.getItem('supabaseDarkMode')
if (!key) {
// Default to dark mode if no preference config
document.documentElement.className = 'dark'
} else {
document.documentElement.className = key === 'true' ? 'dark' : ''
}
}, [])
useEffect(() => {
setTimeout(function () {
setActive(true)
+1 -1
View File
@@ -2,7 +2,7 @@ import fs from 'fs'
import { join } from 'path'
import matter from 'gray-matter'
import nonGeneratedReferencePages from 'data/nonGeneratedReferencePages'
import { REFERENCES } from 'components/Navigation/Navigation.constants'
import { REFERENCES } from '~/components/Navigation/NavigationMenu/NavigationMenu.constants'
const docsDirectory = process.cwd()
+1
View File
@@ -267,6 +267,7 @@ export function gen_v3(spec: OpenAPIV3.Document, dest: string, { apiUrl }: { api
}
const slugify = (text: string) => {
if (!text) return ''
return text
.toString()
.toLowerCase()
+12 -3
View File
@@ -24,7 +24,7 @@ function MyApp({ Component, pageProps }: AppPropsWithLayout) {
IS_PLATFORM || LOCAL_SUPABASE ? createBrowserSupabaseClient() : undefined
)
function telemetry(route: string) {
function handlePageTelemetry(route: string) {
return post(`https://api.supabase.io/platform/telemetry/page`, {
referrer: document.referrer,
title: document.title,
@@ -37,7 +37,7 @@ function MyApp({ Component, pageProps }: AppPropsWithLayout) {
/*
* handle telemetry
*/
telemetry(url)
handlePageTelemetry(url)
/*
* handle "scroll to top" behaviour on route change
*/
@@ -59,6 +59,15 @@ function MyApp({ Component, pageProps }: AppPropsWithLayout) {
}
}, [router.events])
useEffect(() => {
/**
* Send page telemetry on first page load
*/
if (router.isReady) {
handlePageTelemetry(router.route)
}
}, [router.isReady])
const SITE_TITLE = 'Supabase Documentation'
const AuthContainer = (props) => {
@@ -78,7 +87,7 @@ function MyApp({ Component, pageProps }: AppPropsWithLayout) {
<ThemeProvider>
<CommandMenuProvider
site="docs"
MarkdownHandler={({ ...props }) => (
MarkdownHandler={(props) => (
<ReactMarkdown remarkPlugins={[remarkGfm]} components={components} {...props} />
)}
>
+2 -2
View File
@@ -2,11 +2,11 @@ import { Html, Head, Main, NextScript } from 'next/document'
export default function Document() {
return (
<Html lang="en" className="dark">
<Html lang="en">
<Head>
<meta name="viewport" content="width=device-width, initial-scale=1.0"></meta>
</Head>
<body>
<body className="dark">
<Main />
<NextScript />
</body>
+30 -7
View File
@@ -11,8 +11,8 @@ export const meta = {
Supabase auto-generates three types of API directly from your database schema.
- REST - connect to your database through a restful interface, directly from the browser.
- Realtime - for listening to database changes.
- GraphQL - a fast and auto-generate GraphQL API.
- GraphQL - manipulate your database using a graph-like query language.
- Realtime - listen to database changes.
All the APIs are auto-generated from your database and are designed to get you building as fast as possible, without writing a single line of code.
@@ -29,17 +29,40 @@ You can use them directly from the browser (two-tier architecture), or as a comp
## REST API [#rest-api-overview]
Supabase provides a RESTful API using [PostgREST](https://postgrest.org/). This is a very thin API layer on top of Postgres.
It provides everything you need from a CRUD API:
It provides everything you need from a CRUD API at the URL `https://<project_ref>.supabase.co/rest/v1/`.
- Basic CRUD operations
- Deeply nested joins, allowing you to fetch data from multiple tables in a single fetch
- Works with Postgres Views
The REST interface is automatically reflected from your database's schema and supports:
- Basic CRUD operations (Create/Read/Update/Delete)
- Arbitrarily deep relationships among tables/views, functions that return table types can also nest related tables/views.
- Works with Postgres Views, Materialized Views and Foreign Tables
- Works with Postgres Functions
- User defined computed columns and computed relationships
- Works with the Postgres security model - including Row Level Security, Roles, and Grants.
The REST API resolves all requests to a single SQL statement leading to fast response times and high throughput.
Reference:
- [Docs](https://postgrest.org/)
- [Source Code](https://github.com/PostgREST/postgrest)
## GraphQL API [#graphql-api-overview]
GraphQL in Supabase works through [pg_graphql](https://supabase.com/blog/pg-graphql), an open source PostgreSQL extension for GraphQL.
Supabase uses [pg_graphql](https://supabase.github.io/pg_graphql/) to expose a GraphQL API endpoint at `https://<project_ref>.supabase.co/graphql/v1/`.
You can introspect and query the GraphQL API of an existing Supabase project within Studio [here](https://app.supabase.com/project/_/api/graphiql),
or navigate there manually at `API Docs > GraphQL > GraphiQL`.
The GraphQL interface is automatically reflected from your database's schema and supports:
- Basic CRUD operations (Create/Read/Update/Delete)
- Support for Tables, Views, Materialized Views, and Foreign Tables
- Arbitrarily deep relationships among tables/views
- User defined computed fields
- The Postgres security model - including Row Level Security, Roles, and Grants.
The GraphQL API resolves all requests in a single round-trip leading to fast response times and high throughput.
Reference:
- [Docs](https://supabase.github.io/pg_graphql/)
- [Source Code](https://github.com/supabase/pg_graphql)
## Realtime API [#realtime-api-overview]
@@ -66,7 +66,7 @@ const App = () => (
### Social Providers
The Auth component also supports login with [offical social providers](../../auth#providers).
The Auth component also supports login with [official social providers](../../auth#providers).
```js lines=13 title=/src/index.js
import { createClient } from '@supabase/supabase-js'
@@ -322,6 +322,8 @@ const App = () => (
)
```
Currently, translating error messages (e.g. "Invalid credentials") is not supported. Check [related issue.](https://github.com/supabase/auth-ui/issues/86)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page
@@ -199,8 +199,8 @@ For [row level security](https://supabase.com/docs/guides/auth/row-level-securit
let loadedData = [];
async function loadData() {
const { data } = await data.supabase.from('test').select('*').limit(20);
loadedData = data;
const { data: result } = await data.supabase.from('test').select('*').limit(20);
loadedData = result;
}
$: if (data.session) {
@@ -367,7 +367,6 @@ protect multiple routes at once.
```ts
// src/hooks.server.ts
import type { RequestHandler } from './$types';
import { getSupabase } from '@supabase/auth-helpers-sveltekit';
import { redirect, error } from '@sveltejs/kit';
export const handle: Handle = async ({ event, resolve }) => {
@@ -1,5 +1,4 @@
import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'auth-twilio',
title: 'Phone Auth with Twilio',
@@ -295,6 +294,56 @@ and the response should also be the same as above:
The user does not have a password therefore will need to sign in via this method each time they want to access your service.
## WhatsApp OTP Logins
In some cases, you may wish to use WhatsApp as a delivery channel instead. Here are some examples our users have cited:
- You want higher deliverability
- You wish for a secure channel
- Your users mostly use WhatsApp as a messaging platform
To make use of WhatsApp OTP, please complete the following steps:
- Go through the [Twilio self sign up guide for WhatsApp](https://www.twilio.com/docs/whatsapp/self-sign-up)
- Submit a template via the [Twilio Guide For Submitting WhatsApp templates](https://www.twilio.com/docs/whatsapp/tutorial/send-whatsapp-notification-messages-templates#creating-message-templates-and-submitting-them-for-approval)
<Admonition type="caution">
The message template submitted to Twilio must exactly match the SMS Body entered on the Supabase dashboard.
</Admonition>
The sign in process with WhatsApp is similar to the sign in process for SMS. Do note the additional `whatsapp` parameter added:
```js
const {data, error } = await supabase.auth.signInWithOtp({
phone: '+57336567365',
options: {
channel:'whatsapp'
}
})
```
You can also sign up with `whatsapp` as a channel:
```js
const {data, error }= await supabase.auth.signUp({
phone: '+57336567365',
password: 'testsupabasenow',
options: {
channel:'whatsapp',
}
})
```
There is no change in the verification process, you should continue to use the `sms` type for verification
```js
// After receiving a WhatsApp OTP
let { data, error } = await supabase.auth.verifyOtp({
phone: '+57336567365',
token: '123456',
type: 'sms',
})
```
## Resources
- [Twilio Signup](https://www.twilio.com/try-twilio)
@@ -1,4 +1,5 @@
import Layout from '~/layouts/DefaultGuideLayout'
import { Accordion } from 'ui'
export const meta = {
id: 'server-side-rendering',
@@ -55,8 +56,25 @@ like `*` and `**` to allow redirects to different forms of URLs.
</Admonition>
These redirect URLs have the following structure:
Supabase Auth supports two authentication flows: **Implicit** and **PKCE**. The **PKCE** flow is generally preferred when on the server.
It introduces a few additional steps which guard a against replay and URL capture attacks. Unlike the implicit flow, it also allows users to access the
`access_token` and `refresh_token` on the server.
<Accordion
type="default"
openBehaviour="multiple"
chevronAlign="right"
justified
size="medium"
className="text-scale-900 dark:text-white"
>
<div className="border-b pb-3">
<Accordion.Item
header={<span className="text-scale-1200 font-bold">Implicit</span>}
id={`ssr-implicit-flow`}
>
When using the implicit flow, a redirect URL will be returned with the following structure:
```
https://yourapp.com/...#access_token=<...>&refresh_token=<...>&...
```
@@ -77,9 +95,76 @@ your direct control (such as on GitHub Pages or other freemium hosting
providers), we want to prevent hosting services from getting access to your
user's authorization credentials by default. Even if the server is under your
direct control, `GET` requests and their full URLs are often logged. This
approach also avoids leaking credentials in request or access logs.
approach also avoids leaking credentials in request or access logs. If you wish to obtain the
`access_token` and `refresh_token` on a server, please consider using the PKCE flow.
</Admonition>
</Accordion.Item>
</div>
<div className="border-b pb-3">
<Accordion.Item
header={<span className="text-scale-1200 font-bold">PKCE</span>}
id={`ssr-pkce-flow`}
>
When using the PKCE flow, a redirect URL will be returned with the following structure:
```
https://yourapp.com/...?code=<...>
```
The `code` parameter is commonly known as the Auth Code and can be exchanged for an access token by calling `exchangeCodeForSession(code)`.
<Admonition type="info">
For security purposes, the code has a validity of 5 minutes and can only be exchanged for an access token once. You
will need to restart the authentication flow from scratch if you wish to obtain a new access token.
</Admonition>
As the flow is run server side, `localStorage` may not be available. You may configure the client library to use a custom storage adapter an alternate backing storage such as cookies
by setting the `storage` option to an object with the following methods:
```js
const customStorageAdapter: SupportedStorage = {
getItem: (key) => {
if (!supportsLocalStorage()) {
// Configure alternate storage
return null
}
return globalThis.localStorage.getItem(key)
},
setItem: (key, value) => {
if (!supportsLocalStorage()) {
// Configure alternate storage here
return
}
globalThis.localStorage.setItem(key, value)
},
removeItem: (key) => {
if (!supportsLocalStorage()) {
// Configure alternate storage here
return
}
globalThis.localStorage.removeItem(key)
},
}
```
You may also configure the client library to automatically exchange it for a session after a successful redirect. This can be done by setting the `detectSessionInUrl` option to `true`.
Putting it all together, your client library initialization may look like this:
```js
const supabase = createClient(
'https://xyzcompany.supabase.co',
'public-anon-key',
options: {
...
auth: {
...
detectSessionInUrl: true,
flowType: 'pkce',
storage: customStorageAdapter,
}
...
}
)
```
You can read more about the PKCE flow [here](https://oauth.net/2/pkce/)
</Accordion.Item>
</div>
</Accordion>
## Bringing it together
@@ -220,3 +305,4 @@ cache keys every hour or less.
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page
@@ -21,6 +21,8 @@ If you're having issues with identity provider software not on this list, please
This guide requires the use of the [Supabase CLI](/docs/guides/cli). Please make sure you're using version v1.46.4 or higher. You can use `supabase -v` to see the currently installed version.
You can use the `supabase sso` [subcommands](/docs/reference/cli/supabase-sso) to manage your project's configuration.
SAML 2.0 support is disabled by default on Supabase projects. You can configure this on the [Auth Providers](https://app.supabase.com/project/_/auth/providers) page on your project.
Please note that SAML 2.0 support is offered on tiers Pro and above. Check the [Pricing](https://supabase.com/pricing) page for more information.
@@ -67,7 +69,7 @@ Note that SLO (Single Logout) is not supported at this time with Supabase Auth a
Append `?download=true` to the Metadata URL to download the Metadata XML file. This is useful in cases where the identity provider requires a file.
Alternatively, you can use the `supabase sso info --project-ref <your-project>` command to get setup information for your project.
Alternatively, you can use the `supabase sso info --project-ref <your-project>` [command](/docs/reference/cli/supabase-sso-info) to get setup information for your project.
### User accounts and identities
@@ -129,7 +131,7 @@ CREATE POLICY "View organization settings."
## Managing SAML 2.0 connections
Once you've enabled SAML 2.0 support on your project via the [Auth Providers](https://app.supabase.com/project/_/auth/providers) page in the dashboard, you can use the [Supabase CLI](/docs/guides/cli) to add, update, remove and view information about identity providers.
Once you've enabled SAML 2.0 support on your project via the [Auth Providers](https://app.supabase.com/project/_/auth/providers) page in the dashboard, you can use the [Supabase CLI](/docs/reference/cli/supabase-sso) to add, update, remove and view information about identity providers.
### Add a connection
@@ -152,7 +154,7 @@ Commonly used SAML 2.0 Identity Providers that only support Metadata XML files:
- Google Workspaces (GSuite)
- Any self-hosted or on-prem identity provider behind a VPN
Once you've obtained the SAML 2.0 Metadata XML file or URL you can establish a connection with your project's Supabase Auth server by using the [Supabase CLI](/docs/guides/cli):
Once you've obtained the SAML 2.0 Metadata XML file or URL you can [establish a connection](/docs/reference/cli/supabase-sso-add) with your project's Supabase Auth server by running:
```bash
supabase sso add --type saml --project-ref <your-project> \
@@ -185,7 +187,7 @@ supabase.auth.signInWithSSO({
})
```
Calling this method starts the sign-in process using the identity provider registered for the `company.com` domain name. It is not required that identity providers be assigned one or multiple domain names, in which case you can use the provider's unique ID instead.
Calling [`signInWithSSO`](/docs/reference/javascript/auth-signinwithsso) starts the sign-in process using the identity provider registered for the `company.com` domain name. It is not required that identity providers be assigned one or multiple domain names, in which case you can use the provider's unique ID instead.
### Understanding attribute mappings
@@ -272,7 +274,7 @@ Most SAML 2.0 identity providers use Lightweight Directory Access Protocol (LDAP
### Remove a connection
Once a connection to an identity provider is established, you can remove it by running:
Once a connection to an identity provider is established, you can [remove it](/docs/reference/cli/supabase-sso-remove) by running:
```bash
supabase sso remove <provider-id> --project-ref <your-project>
@@ -282,7 +284,7 @@ If successful, the details of the removed identity provider will be shown. All u
If you need to reassign those user accounts to another identity provider, please [open a support ticket](https://app.supabase.com/support/new).
A list of all registered identity providers can be displayed by running:
A [list of all](/docs/reference/cli/supabase-sso-list) registered identity providers can be displayed by running:
```bash
supabase sso list --project-ref <your-project>
@@ -299,7 +301,7 @@ Commonly this is necessary when:
- Other SAML 2.0 Metadata attributes have changed, but it is still the same identity provider
- You are updating the domains or attribute mapping
You can use the following command to update the configuration of an identity provider:
You can use this command to [update](/docs/reference/cli/supabase-sso-update) the configuration of an identity provider:
```bash
supabase sso update <provider-id> --project-ref <your-project>
@@ -311,13 +313,13 @@ It is not possible to change the unique SAML identifier of the identity provider
### Retrieving information about a connection
You can always obtain a list of all registered providers using:
You can always obtain a [list](/docs/reference/cli/supabase-sso-list) of all registered providers using:
```bash
supabase sso list --project-ref <your-project>
```
This list will only include basic information about each provider. To see all of the information about a provider you can use:
This list will only include basic information about each provider. To see [all of the information](/docs/reference/cli/supabase-sso-show) about a provider you can use:
```bash
supabase sso show <provider-id> --project-ref <your-project>
@@ -412,14 +412,15 @@ supabase functions deploy <function_name>
Local logs rely on the Supabase Analytics Server. This can be enabled via the CLI configuration, and requires a Google Cloud project and BigQuery access.
<Admonition type="note">
The Google Cloud project must have billing enabled.
The Google Cloud project must have billing enabled. Read more about this requirement
[here](https://supabase.com/docs/reference/self-hosting-analytics/introduction#bigquery).
</Admonition>
Requirements:
1. Google Cloud project number (must be paid)
1. Google Cloud project number
2. Google Cloud project ID
3. Google Cloud JWT, obtained through [Google Cloud IAM dashboard](https://console.cloud.google.com/iam-admin/iam)
3. Google Cloud Service Account Key, obtained through [Google Cloud IAM dashboard](https://console.cloud.google.com/iam-admin/iam), with BigQuery Admin role assigned to the service account.
Once you have these 3 items, follow these steps:
@@ -433,7 +434,7 @@ gcp_project_id = "my-project-id"
gcp_jwt_path = "supabase/gcloud.json"
```
2. Place your JWT file at the corresponding path and ensure that it is correctly named.
2. Place your service account key (a JSON file) at the corresponding path and ensure that it is correctly named.
3. Start your local stack using `supabase start`
+2 -2
View File
@@ -140,7 +140,7 @@ returns:
This returns the entire array field:
```js
const { data, error } = await supabase.from('arraytest').select('textarray[]')
const { data, error } = await supabase.from('arraytest').select('textarray')
console.log(JSON.stringify(data, null, 2))
```
@@ -161,7 +161,7 @@ returns:
- [Supabase JS Client](https://github.com/supabase/supabase-js)
- [Supabase Account - Free Tier OK](https://supabase.com)
- [PostgreSQL Arrays](https://www.postgresql.org/docs/12/arrays.html)
- [PostgreSQL Arrays](https://www.postgresql.org/docs/15/arrays.html)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
@@ -2,7 +2,7 @@ import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'cicd-workflow',
title: 'Deploying with Git',
title: 'Deploying with GitHub Actions',
description: 'How to deploy Supabase Edge Functions with a CI / CD pipeline.',
video: 'https://www.youtube.com/v/6OMVWiiycLs',
}
@@ -36,6 +36,22 @@ export const meta = {
</div>
### Use Cases
<div className="grid lg:grid-cols-12 gap-6 not-prose">
{useCases.map((item) => {
return (
<Link href={`${item.href}`} key={item.title} passHref>
<a className={'col-span-4'}>
<GlassPanel title={item.title} span="col-span-6" background={false} icon={item.icon}>
{item.description}
</GlassPanel>
</a>
</Link>
)
})}
</div>
### Framework Quickstarts
<div className="grid lg:grid-cols-12 gap-6 not-prose">
@@ -84,6 +100,27 @@ export const meta = {
})}
</div>
export const useCases = [
{
title: 'OpenAI Vector Search',
href: '/guides/getting-started/openai/vector-search',
description: `Build your own custom ChatGPT with Next.js, OpenAI and pg_vector.`,
icon: '/docs/img/icons/openai_logo',
},
{
title: 'Subscription Payments (SaaS)',
href: 'https://github.com/vercel/nextjs-subscription-payments#nextjs-subscription-payments-starter',
description: `Clone, deploy, and fully customize a SaaS subscription application with Next.js.`,
icon: '/docs/img/icons/nextjs-icon',
},
{
title: 'Partner Gallery',
href: 'https://github.com/supabase-community/partner-gallery-example#supabase-partner-gallery-example',
description: `Postgres full-text search, image storage, and more.`,
icon: '/docs/img/icons/nextjs-icon',
},
]
export const quickstarts = [
{
title: 'React',
@@ -99,6 +136,13 @@ export const quickstarts = [
'Learn how to create a Supabase project, add some sample data to your database, and query the data from a NextJS app.',
icon: '/docs/img/icons/nextjs-icon',
},
{
title: 'RedwoodJS',
href: '/guides/getting-started/quickstarts/redwoodjs',
description:
'Learn how to create a Supabase project, add some sample data to your database using Prisma migration and seeds, and query the data from a RedwoodJS app.',
icon: '/docs/img/icons/redwood-icon',
},
{
title: 'Flutter',
href: '/guides/getting-started/quickstarts/flutter',
@@ -106,6 +150,27 @@ export const quickstarts = [
'Learn how to create a Supabase project, add some sample data to your database, and query the data from a Flutter app.',
icon: '/docs/img/icons/flutter-icon',
},
{
title: 'SvelteKit',
href: '/guides/getting-started/quickstarts/sveltekit',
description:
'Learn how to create a Supabase project, add some sample data to your database, and query the data from a SvelteKit app.',
icon: '/docs/img/icons/svelte-icon',
},
{
title: 'SolidJS',
href: '/guides/getting-started/quickstarts/solidjs',
description:
'Learn how to create a Supabase project, add some sample data to your database, and query the data from a SolidJS app.',
icon: '/docs/img/icons/solidjs-icon',
},
{
title: 'Vue',
href: '/guides/getting-started/quickstarts/solidjs',
description:
'Learn how to create a Supabase project, add some sample data to your database, and query the data from a Vue app.',
icon: '/docs/img/icons/vuejs-icon',
},
]
export const webapps = [
@@ -0,0 +1,544 @@
import Layout from '~/layouts/DefaultGuideLayout'
import StepHikeCompact from '~/components/StepHikeCompact'
export const meta = {
title: 'OpenAI Embeddings & Vector Search',
subtitle:
'Learn how to build a ChatGPT-style doc search powered by Next.js, OpenAI, and Supabase.',
breadcrumb: 'OpenAI',
}
In this tutorial we'll look at how you can build a custom ChatGPT-like search experience for your own knowledge base. See our [Supabase Clippy](https://supabase.com/blog/chatgpt-supabase-docs) blog post for an example of how this will look.
We assume that you have a Next.js project with a collection of `.mdx` files nested inside your `pages` directory. We will start developing locally with the Supabase CLI and then push our local database changes to our hosted Supabase project.
<Admonition type="note">
You can find the [full example on
GitHub](https://github.com/supabase-community/nextjs-openai-doc-search).
</Admonition>
## Create a project
1. [Create a new project](https://app.supabase.com) in the Supabase Dashboard.
1. Enter your project details.
1. Wait for the new database to launch.
## Prepare the database
Let's prepare the database schema. We can use the "OpenAI Vector Search" quickstart in the [SQL Editor](https://app.supabase.com/project/_/sql), or you can copy/paste the SQL below and run it yourself.
<Tabs
scrollable
size="small"
type="underlined"
defaultActiveId="dashboard"
>
<TabPanel id="dashboard" label="Dashboard">
1. Go to the [SQL Editor](https://app.supabase.com/project/_/sql) page in the Dashboard.
2. Click **OpenAI Vector Search**.
3. Click **Run**.
</TabPanel>
<TabPanel id="sql" label="SQL">
<StepHikeCompact>
<StepHikeCompact.Step step={1}>
<StepHikeCompact.Details title="Set up Supabase locally">
Make sure you have the latest version of the [Supabase CLI installed]().
Initialize Supabase in the root directory of your app.
</StepHikeCompact.Details>
<StepHikeCompact.Details>
```bash
supabase init
```
</StepHikeCompact.Details>
</StepHikeCompact.Step>
<StepHikeCompact.Step step={2}>
<StepHikeCompact.Details title="Create a migrations file">
To make changes to our local database, we need to create a new migration. This will create a new `.sql` file in our `supabase/migrations` folder, where we can write SQL that will be applied to our local database when starting Supabase locally.
</StepHikeCompact.Details>
<StepHikeCompact.Code>
```bash
supabase migration new init
```
</StepHikeCompact.Code>
</StepHikeCompact.Step>
<StepHikeCompact.Step step={3}>
<StepHikeCompact.Details title="Enable the pgvector extension">
Copy the following SQL line into the newly created migration file to enable the pgvector extension.
</StepHikeCompact.Details>
<StepHikeCompact.Code>
```sql
-- Enable pgvector extension
create extension if not exists vector with schema public;
```
</StepHikeCompact.Code>
</StepHikeCompact.Step>
<StepHikeCompact.Step step={3}>
<StepHikeCompact.Details title="Create the database schema">
Copy these SQL queries to your migration file. It will create two tables in our database schema.
</StepHikeCompact.Details>
<StepHikeCompact.Code>
```sql
-- Stores the checksum of our pages.
-- This ensures that we only regenerate embeddings
-- when the page content has changed.
create table "public"."nods_page" (
id bigserial primary key,
parent_page_id bigint references public.nods_page,
path text not null unique,
checksum text,
meta jsonb,
type text,
source text
);
alter table "public"."nods_page"
enable row level security;
-- Stores the actual embeddings with some metadata
create table "public"."nods_page_section" (
id bigserial primary key,
page_id bigint not null references public.nods_page on delete cascade,
content text,
token_count int,
embedding vector(1536),
slug text,
heading text
);
alter table "public"."nods_page_section"
enable row level security;
```
</StepHikeCompact.Code>
</StepHikeCompact.Step>
<StepHikeCompact.Step step={4}>
<StepHikeCompact.Details title="Create similarity search database function">
Anytime the user sends a query, we want to find the content that's relevant to their questions. We can do this using pgvector's similarity search.
These are quite complex SQL operations, so let's wrap them in database functions that we can call from our frontend using [RPC](https://supabase.com/docs/reference/javascript/rpc).
</StepHikeCompact.Details>
<StepHikeCompact.Code>
```sql
-- Create embedding similarity search functions
create or replace function match_page_sections(
embedding vector(1536),
match_threshold float,
match_count int,
min_content_length int
)
returns table (
id bigint,
page_id bigint,
slug text,
heading text,
content text,
similarity float
)
language plpgsql
as $$
#variable_conflict use_variable
begin
return query
select
nods_page_section.id,
nods_page_section.page_id,
nods_page_section.slug,
nods_page_section.heading,
nods_page_section.content,
(nods_page_section.embedding <#> embedding) * -1 as similarity
from nods_page_section
-- We only care about sections that have a useful amount of content
where length(nods_page_section.content) >= min_content_length
-- The dot product is negative because of a Postgres limitation, so we negate it
and (nods_page_section.embedding <#> embedding) * -1 > match_threshold
-- OpenAI embeddings are normalized to length 1, so
-- cosine similarity and dot product will produce the same results.
-- Using dot product which can be computed slightly faster.
--
-- For the different syntaxes, see https://github.com/pgvector/pgvector
order by nods_page_section.embedding <#> embedding
limit match_count;
end;
$$;
```
</StepHikeCompact.Code>
</StepHikeCompact.Step>
<StepHikeCompact.Step step={5}>
<StepHikeCompact.Details title="Start Supabase Locally">
Start Supabase locally. At this point all files in `supabase/migrations` will be applied to your database and you're ready to go.
</StepHikeCompact.Details>
<StepHikeCompact.Code>
```bash
supabase start
```
</StepHikeCompact.Code>
</StepHikeCompact.Step>
<StepHikeCompact.Step step={6}>
<StepHikeCompact.Details title="Push changes to your Supabase database">
Once ready, you can link your local project to your cloud hosted Supabase project and push the local changes to your hosted instance.
</StepHikeCompact.Details>
<StepHikeCompact.Code>
```bash
supabase link --project-ref=your-project-ref
supabase db push
```
</StepHikeCompact.Code>
</StepHikeCompact.Step>
</StepHikeCompact>
</TabPanel>
</Tabs>
## Pre-process the knowledge base at build time
With our database set up, we need to process and store all `.mdx` files in the `pages` directory. You can find the full script [here](https://github.com/supabase-community/nextjs-openai-doc-search/blob/main/lib/generate-embeddings.ts), or follow the steps below:
<StepHikeCompact>
<StepHikeCompact.Step step={1}>
<StepHikeCompact.Details title="Generate Embeddings">
Create a new file `lib/generate-embeddings.ts` and copy the code over from [GitHub](https://github.com/supabase-community/nextjs-openai-doc-search/blob/main/lib/generate-embeddings.ts).
</StepHikeCompact.Details>
<StepHikeCompact.Code>
```bash
curl \
https://raw.githubusercontent.com/supabase-community/nextjs-openai-doc-search/main/lib/generate-embeddings.ts \
-o "lib/generate-embeddings.ts"
```
</StepHikeCompact.Code>
</StepHikeCompact.Step>
<StepHikeCompact.Step step={2}>
<StepHikeCompact.Details title="Set up environment variables">
We need some environment variables to run the script. Add them to your `.env` file and make sure your `.env` file is not committed to source control!
You can get your local Supabase credentials by running `supabase status`.
</StepHikeCompact.Details>
<StepHikeCompact.Code>
```txt
NEXT_PUBLIC_SUPABASE_URL=
NEXT_PUBLIC_SUPABASE_ANON_KEY=
SUPABASE_SERVICE_ROLE_KEY=
# Get your key at https://platform.openai.com/account/api-keys
OPENAI_KEY=
```
</StepHikeCompact.Code>
</StepHikeCompact.Step>
<StepHikeCompact.Step step={3}>
<StepHikeCompact.Details title="Run script at build time">
Include the script in your `package.json` script commands to enable Vercel to automaticall run it at build time.
</StepHikeCompact.Details>
<StepHikeCompact.Code>
```json
"scripts": {
"dev": "next dev",
"build": "pnpm run embeddings && next build",
"start": "next start",
"embeddings": "tsx lib/generate-embeddings.ts"
},
```
</StepHikeCompact.Code>
</StepHikeCompact.Step>
</StepHikeCompact>
## Create Text Completion with OpenAI API
Anytime a user asks a question, we need to create an embedding for their question, perform a similarity search, and then send a text completion request to the OpenAI API with the query and then context content merged together into a prompt.
All of this is glued together in a [Vercel Edge Function](https://vercel.com/docs/concepts/functions/edge-functions), the code for which can be found on [GitHub](https://github.com/supabase-community/nextjs-openai-doc-search/blob/main/pages/api/vector-search.ts).
<StepHikeCompact>
<StepHikeCompact.Step step={1}>
<StepHikeCompact.Details title="Create Embedding for Question">
In order to perform similarity search we need to turn the question into an embedding.
</StepHikeCompact.Details>
<StepHikeCompact.Code>
```ts
const embeddingResponse = await fetch('https://api.openai.com/v1/embeddings', {
method: 'POST',
headers: {
Authorization: `Bearer ${openAiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'text-embedding-ada-002',
input: sanitizedQuery.replaceAll('\n', ' '),
}),
})
if (embeddingResponse.status !== 200) {
throw new ApplicationError('Failed to create embedding for question', embeddingResponse)
}
const {
data: [{ embedding }],
} = await embeddingResponse.json()
```
</StepHikeCompact.Code>
</StepHikeCompact.Step>
<StepHikeCompact.Step step={2}>
<StepHikeCompact.Details title="Perform similarity search">
Using the `embeddingResponse` we can now perform similarity search by performing an remote procedure call (RPC) to the database function we created earlier.
</StepHikeCompact.Details>
<StepHikeCompact.Code>
```ts
const { error: matchError, data: pageSections } = await supabaseClient.rpc(
'match_page_sections',
{
embedding,
match_threshold: 0.78,
match_count: 10,
min_content_length: 50,
}
)
```
</StepHikeCompact.Code>
</StepHikeCompact.Step>
<StepHikeCompact.Step step={3}>
<StepHikeCompact.Details title="Perform text completion request">
With the relevant content for the user's question identified, we can now build the prompt and make a text completion request via the OpenAI API.
If successful, the OpenAI API will respond with a `text/event-stream` response that we can simply forward to the client where we'll process the event stream to smoothly print the answer to the user.
</StepHikeCompact.Details>
<StepHikeCompact.Code>
```ts
const prompt = codeBlock`
${oneLine`
You are a very enthusiastic Supabase representative who loves
to help people! Given the following sections from the Supabase
documentation, answer the question using only that information,
outputted in markdown format. If you are unsure and the answer
is not explicitly written in the documentation, say
"Sorry, I don't know how to help with that."
`}
Context sections:
${contextText}
Question: """
${sanitizedQuery}
"""
Answer as markdown (including related code snippets if available):
`
const completionOptions: CreateCompletionRequest = {
model: 'text-davinci-003',
prompt,
max_tokens: 512,
temperature: 0,
stream: true,
}
const response = await fetch('https://api.openai.com/v1/completions', {
method: 'POST',
headers: {
Authorization: `Bearer ${openAiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(completionOptions),
})
if (!response.ok) {
const error = await response.json()
throw new ApplicationError('Failed to generate completion', error)
}
// Proxy the streamed SSE response from OpenAI
return new Response(response.body, {
headers: {
'Content-Type': 'text/event-stream',
},
})
```
</StepHikeCompact.Code>
</StepHikeCompact.Step>
</StepHikeCompact>
## Display the answer on the frontend
In a last step, we need to process the event stream from the OpenAI API and print the answer to the user. The full code for this can be found on [GitHub](https://github.com/supabase-community/nextjs-openai-doc-search/blob/main/components/SearchDialog.tsx).
```tsx
const handleConfirm = React.useCallback(
async (query: string) => {
setAnswer(undefined)
setQuestion(query)
setSearch('')
dispatchPromptData({ index: promptIndex, answer: undefined, query })
setHasError(false)
setIsLoading(true)
const eventSource = new SSE(`api/vector-search`, {
headers: {
apikey: process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY ?? '',
Authorization: `Bearer ${process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY}`,
'Content-Type': 'application/json',
},
payload: JSON.stringify({ query }),
})
function handleError<T>(err: T) {
setIsLoading(false)
setHasError(true)
console.error(err)
}
eventSource.addEventListener('error', handleError)
eventSource.addEventListener('message', (e: any) => {
try {
setIsLoading(false)
if (e.data === '[DONE]') {
setPromptIndex((x) => {
return x + 1
})
return
}
const completionResponse: CreateCompletionResponse = JSON.parse(e.data)
const text = completionResponse.choices[0].text
setAnswer((answer) => {
const currentAnswer = answer ?? ''
dispatchPromptData({
index: promptIndex,
answer: currentAnswer + text,
})
return (answer ?? '') + text
})
} catch (err) {
handleError(err)
}
})
eventSource.stream()
eventSourceRef.current = eventSource
setIsLoading(true)
},
[promptIndex, promptData]
)
```
## Learn More
Want to learn more about the awesome tech that is powering this?
- Read about how we built [ChatGPT for the Supabase Docs](https://supabase.com/blog/chatgpt-supabase-docs).
- Read the pgvector Docs for [Embeddings and vector similarity](https://supabase.com/docs/guides/database/extensions/pgvector)
- Watch Greg's video for a full breakdown:
<div class="video-container">
<iframe
src="https://www.youtube-nocookie.com/embed/Yhtjd7yGGGA"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</div>
export const Page = ({ children }) => <Layout meta={meta} children={children} hideToc={true} />
export default Page
@@ -0,0 +1,242 @@
import Layout from '~/layouts/DefaultGuideLayout'
import StepHikeCompact from '~/components/StepHikeCompact'
export const meta = {
title: 'Use Supabase with RedwoodJS',
subtitle:
'Learn how to create a Supabase project, add some sample data to your database using Prisma migration and seeds, and query the data from a RedwoodJS app.',
breadcrumb: 'Framework Quickstarts',
}
<StepHikeCompact>
<StepHikeCompact.Step step={1}>
<StepHikeCompact.Details title="Setup your new Supabase Project">
[Create a new project](https://app.supabase.com) in the Supabase Dashboard.
<Admonition type="important">
Be sure to make note of the Database Password you used as you will need this later to connect to your database.
</Admonition>
</StepHikeCompact.Details>
<StepHikeCompact.Code>
![New Project](/docs/img/redwoodjs-qs-new-project.png)
</StepHikeCompact.Code>
</StepHikeCompact.Step>
<StepHikeCompact.Step step={2}>
<StepHikeCompact.Details title="Gather Database Connection Strings">
After your project is ready, gather the following information about your [database connections](https://app.supabase.com/project/_/settings/database):
* Connection String (port 5432)
* Connection Pooling / Connection String (port 6543)
You will need these to setup environment variables in Step 5.
<Admonition type="tip">
You can copy and paste these connection strings from the Supabase Dashboard when needed in later steps.
</Admonition>
</StepHikeCompact.Details>
<StepHikeCompact.Code>
![New Project](/docs/img/redwoodjs-qs-connection-strings-pool.png)
</StepHikeCompact.Code>
</StepHikeCompact.Step>
<StepHikeCompact.Step step={3}>
<StepHikeCompact.Details title="Create a RedwoodJS app">
Create a RedwoodJS app with TypeScript.
<Admonition type="note">
The [`yarn` package manager](https://yarnpkg.com) is required to create a RedwoodJS app. You will use it to run RedwoodJS commands later.
While TypeScript is recommended, If you want a JavaScript app, omit the `--ts` flag.
</Admonition>
</StepHikeCompact.Details>
<StepHikeCompact.Code>
```bash Terminal
yarn create redwood-app my-app --ts
```
</StepHikeCompact.Code>
</StepHikeCompact.Step>
<StepHikeCompact.Step step={4}>
<StepHikeCompact.Details title="Open your RedwoodJS app in VS Code">
You'll develop your app, manage database migrations, and run your app in VS Code.
</StepHikeCompact.Details>
<StepHikeCompact.Code>
```bash Terminal
cd my-app
code .
```
</StepHikeCompact.Code>
</StepHikeCompact.Step>
<StepHikeCompact.Step step={5}>
<StepHikeCompact.Details title="Configure Environment Variables">
In your `.env` file, add the following environment variables for your database connection:
* The `DIRECT_URL` should use the `Connection String` from your Supabase project. Hint: the port is `5432`.
* The `DATABASE_URL` should use the `Connection Pooling / Connection String` from your Supabase project. Hint: the port is `6432`.
<Admonition type="note">
Be sure to append `?pgbouncer=true` to the end of the `DATABASE_URL` connection string.
Also, replace `[YOUR-PASSWORD]` and `[YOUR-PROJECT-REF]` with the password you used when creating your Supabase project and the project reference from the URL in your browser.
</Admonition>
</StepHikeCompact.Details>
<StepHikeCompact.Code>
```bash terminal
# .env
# PostgreSQL connection string used for migrations
DIRECT_URL="postgres://postgres:[YOUR-PASSWORD]@db.[YOUR-PROJECT-REF].supabase.co:5432/postgres"
# PostgreSQL connection string with pgBouncer config — used by Prisma Client
DATABASE_URL="postgres://postgres:[YOUR-PASSWORD]@db.[YOUR-PROJECT-REF].supabase.co:6543/postgres?pgbouncer=true"
```
</StepHikeCompact.Code>
</StepHikeCompact.Step>
<StepHikeCompact.Step step={6}>
<StepHikeCompact.Details title="Update your Prisma Schema">
By default, RedwoodJS ships with a SQLite database, but we want to use PostgreSQL.
Update your Prisma schema file `api/db/schema.prisma` to use your Supabase PostgreSQL database connection environment variables you setup in Step 5.
</StepHikeCompact.Details>
<StepHikeCompact.Code>
```file="api/prisma/schema.prisma" title="api/prisma/schema.prisma"
// api/db/schema.prisma
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
directUrl = env("DIRECT_URL")
}
```
</StepHikeCompact.Code>
</StepHikeCompact.Step>
<StepHikeCompact.Step step={7}>
<StepHikeCompact.Details title="Create the Country model and apply a schema migration">
Create the Country model in `api/db/schema.prisma` and then run `yarn rw prisma migrate dev` from your terminal to apply the migration.
</StepHikeCompact.Details>
<StepHikeCompact.Code>
```js
// api/db/schema.prisma
model Country {
id Int @id @default(autoincrement())
name String @unique
}
```
</StepHikeCompact.Code>
</StepHikeCompact.Step>
<StepHikeCompact.Step step={8}>
<StepHikeCompact.Details title="Update seed script">
Let's seed the database with a few countries.
Update the file `scripts/seeds.ts` to contain the following code:
</StepHikeCompact.Details>
<StepHikeCompact.Code>
```ts
// scripts/seed.ts
import type { Prisma } from '@prisma/client'
import { db } from 'api/src/lib/db'
export default async () => {
try {
const data: Prisma.CountryCreateArgs['data'][] = [
{ name: 'United States' },
{ name: 'Canada' },
{ name: 'Mexico' },
]
console.log('Seeding countries ...')
const countries = await db.country.createMany({ data })
console.log('Done.', countries)
} catch (error) {
console.error(error)
}
}
```
</StepHikeCompact.Code>
</StepHikeCompact.Step>
<StepHikeCompact.Step step={9}>
<StepHikeCompact.Details title="Seed your database">
Run the seed database command to populate the `Country` table with the countries you just created.
<Admonition type="tip">
The reset database command `yarn rw prisma db reset` will recreate the tables and will also run the seed script.
</Admonition>
</StepHikeCompact.Details>
<StepHikeCompact.Code>
```bash Terminal
yarn rw prisma db seed
```
</StepHikeCompact.Code>
</StepHikeCompact.Step>
<StepHikeCompact.Step step={10}>
<StepHikeCompact.Details title="Scaffold the Country UI">
Now, we'll use RedwoodJS generators to scaffold a CRUD UI for the `Country` model.
</StepHikeCompact.Details>
<StepHikeCompact.Code>
```bash Terminal
yarn rw g scaffold country
```
</StepHikeCompact.Code>
</StepHikeCompact.Step>
<StepHikeCompact.Step step={11}>
<StepHikeCompact.Details title="Start the app">
Start the app via `yarn rw dev`. A browser will open to the RedwoodJS Splash page.
</StepHikeCompact.Details>
<StepHikeCompact.Code>
![RedwoodJS Splash Page](/docs/img/redwoodjs-qs-splash.png)
</StepHikeCompact.Code>
</StepHikeCompact.Step>
<StepHikeCompact.Step step={12}>
<StepHikeCompact.Details title="View Countries UI">
Click on `/countries` to visit http://localhost:8910/countries where should see the list of countries.
You may now edit, delete, and add new countries using the scaffolded UI.
</StepHikeCompact.Details>
<StepHikeCompact.Code>
![RedwoodJS Splash Page](/docs/img/redwoodjs-qs-countries-ui.png)
</StepHikeCompact.Code>
</StepHikeCompact.Step>
</StepHikeCompact>
export const Page = ({ children }) => <Layout meta={meta} children={children} hideToc={true} />
export default Page
+2 -9
View File
@@ -4,23 +4,16 @@ import { logConstants } from 'shared-data'
export const meta = {
id: 'logs',
title: 'Logging',
description: 'Getting started with Supabase Platform Log Browser',
description: 'Getting started with Supabase Log Browser',
}
The Supabase Platform includes a Logs Explorer that allows log tracing and debugging. Log retention is based on your [project's pricing plan](https://supabase.com/pricing).
<Admonition type="note">
These features are not currently available for self-hosting and local development.<br/>
This is on the roadmap and you can follow the progress in the [Logflare repository](https://github.com/Logflare/logflare).
</Admonition>
## Product Logs
Supabase provides a logging interface specific to each product. You can use simple regular expressions for keywords and patterns to search log event messages. You can also export and download the log events matching your query as a spreadsheet.
{/* <!-- To update the screenshots, ensure that at least one log line is selected to display the metadata. Can use meme.town as an example. --> */}
{/* <!-- To update screenshots, ensure that at least one log line is selected to display the metadata. Can use meme.town as an example. --> */}
<Tabs
scrollable
@@ -7,7 +7,7 @@ export const meta = {
Supabase offers a "Spend Cap" on each project to manage your usage and costs.
This Spend Cap determines whether your project can exceed the free quota allowance of any [line item](#what-can-i-be-charged-for) in a given billing cycle.
This Spend Cap determines whether your project can exceed the free quota allowance of any [line item](#what-additional-usage-can-i-be-charged-for) in a given billing cycle.
If you exceed the free quota allowance of a line item, and the Spend Cap is **"off"**, then you will be billed for any additional usage on that line item.
## What additional usage can I be charged for?
@@ -35,13 +35,13 @@ From there, you can click on "Change subscription" to select the plan you want t
## What happens when the Spend Cap is on?
Once you use all your free quota allowance for a [line item](#what-can-i-be-charged-for), your project will not allow any further usage on that line item until the next billing cycle begins.
Once you use all your free quota allowance for a [line item](#what-additional-usage-can-i-be-charged-for), your project will not allow any further usage on that line item until the next billing cycle begins.
This can help you to avoid unexpected costs and manage your expenses more effectively.
## What happens when Spend Cap is off?
Your project will continue to operate after using all the free quota allowance for each [line item](#what-can-i-be-charged-for).
Your project will continue to operate after using all the free quota allowance for each [line item](#what-additional-usage-can-i-be-charged-for).
This additional usage will be charged based on the line item's cost per unit outlined on the [pricing page](/pricing).
<Admonition type="note">
+6
View File
@@ -141,6 +141,12 @@ export const migrationGuides = [
href: '/guides/resources/migrating-to-supabase/render',
description: 'Migrate your Render Postgres database to Supabase.',
},
{
title: 'Amazon RDS',
icon: '/docs/img/icons/aws-rds-icon',
href: '/guides/resources/migrating-to-supabase/amazon-rds',
description: 'Migrate your Amazon RDS database to Supabase.',
},
]
export const postgres = [
@@ -0,0 +1,95 @@
import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
title: 'Migrate from Amazon RDS to Supabase',
description: 'Migrate your Amazon RDS MySQL or MS SQL database to Supabase Postgres database.',
}
This guide aims to exhibit the process of transferring your Amazon RDS database from any of these engines Postgres, MySQL or MS SQL to Supabase's Postgres database. Although Amazon RDS is a favored managed database service provided by AWS, it may not suffice for all use cases. Supabase, on the other hand, provides an excellent free and open source option that encompasses all the necessary backend features to develop a product: a Postgres database, authentication, instant APIs, edge functions, real-time subscriptions, and storage.
Supabase's core is Postgres, enabling the use of row-level security and providing access to over 40 Postgres extensions. By migrating from Amazon RDS to Supabase, you can leverage Postgres to its fullest potential and acquire all the features you need to complete your project.
## Retrieve your Amazon RDS database credentials [#retrieve-rds-credentials]
1. Log in to your [Amazon RDS account](https://aws.amazon.com/rds/).
1. Select the region where your RDS database is located.
1. Navigate to the **Databases** tab.
1. Select the database that you want to migrate.
1. In the **Connectivity & Security** tab, note down the Endpoint and the port number.
1. In the **Configuration** tab, note down the Database name and the Username.
1. If you do not have the password, create a new one and note it down.
![Copying RDS credentials from AWS Management Console](/docs/img/guides/resources/migrating-to-supabase/amazon-rds/amazon-rds_credentials.png)
## Retrieve your Supabase Host [#retrieve-supabase-host]
1. If you're new to Supabase, [create a project](https://app.supabase.com).
1. Go to the [Database settings](https://app.supabase.com/project/_/settings/database) for your project in the Supabase Dashboard.
1. Under **Connection Info**, note your Host (`$SUPABASE_HOST`).
1. Save your password or [reset it](https://app.supabase.com/project/_/settings/database) if you forgot it.
![Finding Supabase host address](/docs/img/guides/resources/migrating-to-supabase/amazon-rds/supabase_dashboard.png)
## Migrate the database
The fastest way to migrate your database is with the Supabase migration tool on
[Google Colab](https://colab.research.google.com/github/mansueli/Supa-Migrate/blob/main/Amazon_RDS_to_Supabase.ipynb).
Alternatively, you can use [pgloader](https://github.com/dimitri/pgloader), a flexible and powerful data migration tool that supports a wide range of source database engines, including MySQL and MS SQL, and migrates the data to a Postgres database. For databases using the Postgres engine, we recommend using the pg_dump and psql command line tools, which are included in a full PostgreSQL installation.
<Tabs
scrollable
size="small"
type="underlined"
defaultActiveId="colab"
>
<TabPanel id="colab" label="Migrate using Colab">
1. Select the Dabase Engine from the Source database in the dropdown
1. Set the environment variables (`HOST`, `USER`, `SOURCE_DB`,`PASSWORD`, `SUPABASE_URL`, and `SUPABASE_PASSWORD`) in the Colab notebook.
2. Run the first two steps in [the notebook](https://colab.research.google.com/github/mansueli/Supa-Migrate/blob/main/Amazon_RDS_to_Supabase.ipynb) in order. The first sets engine and installs the necessary files.
3. Run the third step to start the migration. This will take a few minutes.
</TabPanel>
<TabPanel id="MySQL" label="Migrate from MySQL with pgloader">
Install pgloader.
Create a configuration file (e.g., config.load).
```sql
LOAD DATABASE
FROM mysql://USER:PASSWORD@HOST/SOURCE_DB
INTO postgres://postgres:password@db.xxxx.supabase.co:6543/postgres
ALTER SCHEMA 'public' OWNER TO 'postgres';
set wal_buffers = '64MB', max_wal_senders = 0, statement_timeout = 0, work_mem to '2GB';
````
##Run the migration with pgloader
```bash
pgloader config.load
```
</TabPanel>
<TabPanel id="MS SQL" label="Migrate from MSSQL">
Install pgloader.
Create a configuration file (e.g., config.load).
```sql
LOAD DATABASE
FROM mssql://USER:PASSWORD@HOST/SOURCE_DB
INTO postgres://postgres:password@db.xxxx.supabase.co:6543/postgres
ALTER SCHEMA 'public' OWNER TO 'postgres';
set wal_buffers = '64MB', max_wal_senders = 0, statement_timeout = 0, work_mem to '2GB';
````
##Run the migration with pgloader
```bash
pgloader config.load
```
</TabPanel>
</Tabs>
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page
+5
View File
@@ -72,6 +72,11 @@ export const meta = {
<IconPanel title="NextJS" icon="/docs/img/icons/nextjs-icon" />
</a>
</Link>
<Link href={`/guides/getting-started/quickstarts/redwoodjs`} passHref>
<a className="no-underline">
<IconPanel title="RedwoodJS" icon="/docs/img/icons/redwoodjs-icon" />
</a>
</Link>
<Link href={`/guides/getting-started/quickstarts/flutter`} passHref>
<a className="no-underline">
<IconPanel title="Flutter" icon="/docs/img/icons/flutter-icon" />
Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 475 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 869 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 445 B

After

Width:  |  Height:  |  Size: 452 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 791 B

After

Width:  |  Height:  |  Size: 859 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

@@ -1,19 +0,0 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="512.000000pt" height="512.000000pt" viewBox="0 0 512.000000 512.000000"
preserveAspectRatio="xMidYMid meet">
<metadata>
Created by potrace 1.11, written by Peter Selinger 2001-2013
</metadata>
<g transform="translate(0.000000,512.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M1040 5110 c-25 -4 -63 -11 -84 -14 -60 -10 -207 -61 -287 -101 -165
-81 -317 -208 -430 -358 -106 -141 -203 -370 -226 -534 -4 -32 -8 -735 -8
-1563 l0 -1505 22 -93 c116 -485 498 -847 979 -926 135 -23 2988 -22 3114 0
303 54 576 222 761 466 99 132 190 340 225 513 11 55 15 3029 5 3085 -5 25
-12 63 -15 84 -8 49 -57 197 -87 262 -163 351 -504 610 -894 678 -66 12 -334
14 -1555 14 -811 0 -1495 -4 -1520 -8z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 932 B

+2 -2
View File
@@ -3,12 +3,12 @@
"short_name": "Supabase",
"icons": [
{
"src": "/favicons/android-chrome-192x192.png",
"src": "/favicon/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/favicons/android-chrome-512x512.png",
"src": "/favicon/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
+2
View File
@@ -11,6 +11,7 @@ Ariuna K
Beng Eu
Bo Lu
Bobbie Soedirgo
Chandana Anumula
Chase Granberry
Chris Copplestone
Dave Wilson
@@ -50,6 +51,7 @@ Qiao Han
Ramiro Nuñez Dosio
Rodrigo Martins Mansueli
Rory Wilding
Sreyas Udayavarman
Stanislav M
Steve Chavez
Stojan Dimitrovski
Binary file not shown.

After

Width:  |  Height:  |  Size: 888 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 764 KiB

@@ -0,0 +1 @@
<svg width="2215" height="2500" viewBox="0 0 256 289" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid"><path d="M0 224.742l29.972 35.125 2.695-3.201V32l-2.695-3.395L0 63.717v161.025" fill="#1A476F"/><path d="M29.976 259.867l57.27 28.633 2.382-3.833L89.667 3l-2.381-3-57.31 28.541v231.326" fill="#1F5B98"/><path d="M256 63.717l-29.98-35.112-3.353 1.062.666 227.333 2.687 2.867L256 224.746V63.717" fill="#2D72B8"/><path d="M168.75 288.5l57.27-28.633V28.541L168.71 0 166 3.667l.039 280.666 2.711 4.167" fill="#5294CF"/><path d="M87.286 0h81.424v288.504H87.286V0z" fill="#2D72B8"/></svg>

After

Width:  |  Height:  |  Size: 600 B

@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 2500 2500" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<path d="M174.672,1866.26L173.916,1866.7C191.548,1898.57 218.67,1925.69 254.607,1946.71C428.869,2047.74 1012.68,2382.03 1129.3,2451.19C1135.77,2454.98 1142.22,2458.47 1148.65,2461.66C1221.03,2498 1291.94,2496.48 1364.59,2453.9C1657.51,2284.39 1951.11,2116.23 2244.04,1947.39C2280.65,1926.37 2307.1,1899.92 2324.72,1867.38C2341.57,1836.39 2350.38,1800.72 2350.49,1760.36C2350.49,1759.87 2350.49,1759.38 2350.49,1758.89L2350.49,739.086C2350.49,697.725 2341.68,660.432 2323.37,629.239L2323.37,629.241L2323.37,629.239C2305.74,598.05 2279.29,572.284 2244.04,551.942C1951.11,383.104 1657.51,214.269 1364.59,45.431C1285.26,0 1209.32,1.357 1130.66,47.464C1014.03,115.95 429.546,450.91 255.963,551.942C184.087,593.303 149.507,657.042 149.507,739.765L149.507,1759.57C149.507,1799.77 158.113,1835.33 174.672,1866.26Z" style="fill:white;fill-rule:nonzero;"/>
<path d="M1566.65,1427.32C1504.27,1537.84 1385.61,1613.11 1249.32,1613.11C1113.71,1613.11 995.729,1539.2 933.347,1429.35C902.834,1375.79 885.203,1314.76 885.203,1248.99C885.203,1047.6 1047.94,884.869 1249.32,884.869C1383.58,884.869 1500.88,958.099 1563.94,1066.59L1881.95,883.512C1755.16,665.179 1519.19,518.039 1248.64,518.039C844.519,518.039 517.696,845.542 517.696,1248.99C517.696,1381.21 552.953,1505.97 614.658,1613.11C740.776,1832.12 978.098,1979.94 1249.32,1979.94C1521.23,1979.94 1758.55,1831.44 1884.66,1611.07L1566.65,1427.32ZM1968.74,1076.08L1896.19,1076.08L1896.19,1426.64L1968.74,1426.64L1968.74,1076.08ZM2129.44,1076.08L2056.89,1076.08L2056.89,1426.64L2129.44,1426.64L2129.44,1076.08Z" style="fill-rule:nonzero;"/>
<g>
<path d="M2188.43,1135.07L1837.88,1135.07L1837.88,1207.63L2188.43,1207.63L2188.43,1135.07ZM2188.43,1295.1L1837.88,1295.1L1837.88,1367.65L2188.43,1367.65L2188.43,1295.1Z" style="fill-rule:nonzero;"/>
</g>
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.24265 11.2995L2.2467 11.2971C2.1581 11.1317 2.11206 10.9414 2.11206 10.7263V5.27012C2.11206 4.82754 2.29707 4.48652 2.68163 4.26523C3.12626 4.00643 4.07482 3.46075 5.01133 2.922C6.03091 2.33546 7.03621 1.75714 7.36146 1.56615C7.78231 1.31947 8.18861 1.31221 8.61304 1.55527C9.40246 2.01029 10.1928 2.4653 10.9831 2.92032C11.7618 3.36862 12.5405 3.81692 13.3183 4.26523C13.5069 4.37406 13.6484 4.51192 13.7427 4.67878C13.8407 4.84567 13.8878 5.0452 13.8878 5.26649V10.7227V10.7306C13.8873 10.9465 13.8401 11.1373 13.75 11.3031C13.6557 11.4772 13.5142 11.6187 13.3183 11.7312C12.7234 12.0741 12.128 12.4164 11.5325 12.7589C10.5591 13.3186 9.58538 13.8785 8.61304 14.4412C8.22435 14.669 7.84496 14.6771 7.45771 14.4827C7.42331 14.4656 7.3888 14.4469 7.35419 14.4267C6.97211 14.2001 5.65273 13.4416 4.47316 12.7634C3.72646 12.3342 3.03579 11.9371 2.67437 11.7276C2.4821 11.6151 2.33699 11.47 2.24265 11.2995ZM9.69419 8.94871C9.36044 9.54002 8.72558 9.94273 7.99639 9.94273C7.27085 9.94273 6.63962 9.54729 6.30586 8.95957C6.14261 8.67301 6.04828 8.34649 6.04828 7.9946C6.04828 6.91712 6.91896 6.04647 7.99639 6.04647C8.71472 6.04647 9.3423 6.43826 9.67969 7.01872L11.3811 6.03921C10.7028 4.87107 9.44026 4.08384 7.99276 4.08384C5.83061 4.08384 4.08203 5.83606 4.08203 7.9946C4.08203 8.70201 4.27066 9.36951 4.6008 9.94273C5.27556 11.1145 6.54529 11.9054 7.99639 11.9054C9.45118 11.9054 10.7209 11.1108 11.3956 9.93182L9.69419 8.94871ZM11.8455 7.06949H11.4573V7.3851H11.1453V7.77331H11.4573V8.2413H11.1453V8.62946H11.4573V8.94507H11.8455V8.62946H12.3171V8.94507H12.7052V8.62946H13.0208V8.2413H12.7052V7.77331H13.0208V7.3851H12.7052V7.06949H12.3171V7.3851H11.8455V7.06949ZM11.8455 8.2413V7.77331H12.3171V8.2413H11.8455Z" fill="url(#paint0_linear_1002_71738)"/>
<defs>
<linearGradient id="paint0_linear_1002_71738" x1="-4.11388" y1="12.9341" x2="13.1956" y2="12.9341" gradientUnits="userSpaceOnUse">
<stop stop-color="#D8FFEC" stop-opacity="0.6"/>
<stop offset="1" stop-color="#F4FFFA"/>
</linearGradient>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

@@ -1,9 +1 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.3644 4.77374C14.3679 4.90203 14.3693 5.03012 14.3701 5.15827C14.371 5.30448 14.371 5.45074 14.371 5.59694L14.371 5.61482V10.3851L14.371 10.419C14.371 10.56 14.371 10.7008 14.3701 10.8418C14.3693 10.97 14.3679 11.098 14.3643 11.2261C14.3569 11.5053 14.3404 11.787 14.2908 12.063C14.2404 12.3433 14.1582 12.6042 14.0285 12.8589C13.9012 13.1091 13.7348 13.3379 13.5363 13.5363C13.3379 13.7349 13.109 13.9013 12.8587 14.0287C12.6042 14.1582 12.3435 14.2404 12.0633 14.2907C11.7871 14.3404 11.5055 14.357 11.2262 14.3644C11.0979 14.3678 10.9698 14.3694 10.8416 14.3701C10.7059 14.3711 10.5701 14.371 10.4344 14.371L10.3851 14.371H5.61479L5.56546 14.371C5.42967 14.371 5.294 14.3711 5.15832 14.3701C5.03009 14.3694 4.90183 14.3678 4.77379 14.3644C4.49456 14.357 4.21273 14.3404 3.93665 14.2907C3.65646 14.2404 3.39572 14.1583 3.1412 14.0287C2.89094 13.9013 2.66197 13.7349 2.46358 13.5363C2.26504 13.3379 2.09864 13.1091 1.97135 12.8589C1.84168 12.6042 1.75951 12.3433 1.70913 12.063C1.65955 11.787 1.6431 11.5053 1.63559 11.2261C1.63207 11.098 1.63059 10.9699 1.62975 10.8418C1.62888 10.7073 1.62889 10.5729 1.62891 10.4384C1.62891 10.4207 1.62891 10.4029 1.62891 10.3851V7.69203V5.61482C1.62891 5.5988 1.62891 5.58279 1.62891 5.56677C1.6289 5.43062 1.62889 5.29442 1.62975 5.15824C1.63059 5.0301 1.63207 4.90201 1.63559 4.77371C1.6431 4.49463 1.65957 4.21302 1.70913 3.93692C1.75951 3.65653 1.84168 3.39582 1.97135 3.14111C2.09864 2.89097 2.26504 2.66207 2.46358 2.46357C2.51319 2.41395 2.5647 2.36634 2.61797 2.32083C2.77779 2.18434 2.9535 2.06688 3.14118 1.97136C3.20482 1.93899 3.26884 1.90955 3.33344 1.88286C3.52726 1.80273 3.72649 1.74703 3.93659 1.70927C4.14367 1.67196 4.35399 1.6534 4.56399 1.64328C4.63399 1.63991 4.70396 1.63746 4.77377 1.63558C4.90181 1.6321 5.03007 1.63064 5.1583 1.62985C5.31041 1.62897 5.4625 1.62897 5.61477 1.62897H7.01212H10.3851C10.5372 1.62897 10.6895 1.62897 10.8417 1.62983C10.9698 1.63062 11.098 1.63208 11.2262 1.63555C11.5055 1.64311 11.7871 1.6595 12.0633 1.70925C12.3435 1.75958 12.6042 1.84184 12.8587 1.97136C13.109 2.09872 13.3379 2.2651 13.5363 2.46359C13.7348 2.66209 13.9012 2.89099 14.0285 3.14113C14.1582 3.39584 14.2405 3.65655 14.2908 3.93694C14.3404 4.21304 14.3569 4.49465 14.3644 4.77374ZM11.7247 9.49334L11.7256 9.49437C12.8204 10.8415 12.5226 12.2854 12.3825 12.013C11.8103 10.8996 10.7442 11.1838 10.2044 11.464C10.1597 11.4907 10.1139 11.5159 10.0678 11.5407C10.0653 11.5422 10.0626 11.5438 10.0598 11.5454C10.0567 11.5472 10.0535 11.549 10.0508 11.5508L10.0517 11.5495C8.92831 12.1464 7.42003 12.1906 5.9033 11.5388C4.63145 10.9922 3.58646 10.0558 2.90796 8.97051C3.25297 9.22522 3.62568 9.4494 4.02214 9.6352C5.62503 10.3859 7.23492 10.3317 8.37424 9.63447C6.75268 8.38742 5.39918 6.76342 4.36131 5.4472C4.16168 5.21114 3.98007 4.96593 3.82737 4.71129C5.07019 5.84879 7.03337 7.27717 7.73781 7.67251C6.24262 6.09283 4.92514 4.14748 4.98693 4.20977C7.34176 6.58253 9.51444 7.92402 9.51444 7.92402C9.59627 7.96914 9.6572 8.00521 9.70556 8.03698C9.75012 7.92263 9.79044 7.80497 9.82397 7.68238C10.2 6.30796 9.77677 4.73633 8.81962 3.43877C11.0038 4.7504 12.2945 7.24149 11.7657 9.34852C11.7554 9.38939 11.7436 9.42922 11.7319 9.46905C11.7295 9.47714 11.7271 9.48524 11.7247 9.49334Z" fill="url(#paint0_linear_1002_71731)"/>
<defs>
<linearGradient id="paint0_linear_1002_71731" x1="-5.10791" y1="12.7483" x2="13.6219" y2="12.7483" gradientUnits="userSpaceOnUse">
<stop stop-color="#D8FFEC" stop-opacity="0.6"/>
<stop offset="1" stop-color="#F4FFFA"/>
</linearGradient>
</defs>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14"><defs><linearGradient id="a" x1="-52.871%" x2="94.121%" y1="87.265%" y2="87.265%"><stop offset="0%"/><stop offset="100%" stop-color="#A2A2A2"/></linearGradient></defs><path fill="url(#a)" fill-rule="evenodd" d="M12.735 3.145c.004.128.005.256.006.384l.001.439v5.245c-.002.128-.003.256-.007.384-.007.28-.024.561-.073.837a2.84 2.84 0 0 1-.262.796 2.67 2.67 0 0 1-1.17 1.17 2.83 2.83 0 0 1-.796.262c-.276.05-.557.066-.837.073a16.39 16.39 0 0 1-.384.006l-.408.001H3.53c-.128-.002-.256-.003-.384-.007a5.558 5.558 0 0 1-.837-.073 2.82 2.82 0 0 1-.796-.262 2.671 2.671 0 0 1-1.17-1.17 2.825 2.825 0 0 1-.262-.796 5.585 5.585 0 0 1-.073-.837A18.376 18.376 0 0 1 0 9.213V3.53c.002-.128.003-.256.007-.384.007-.28.024-.561.073-.837.05-.28.133-.541.262-.796A2.673 2.673 0 0 1 1.705.254c.193-.08.393-.136.603-.174.207-.037.417-.056.627-.066.07-.003.14-.006.21-.007C3.273.003 3.4.002 3.529 0h5.684c.128.002.256.003.384.007.28.007.561.024.837.073.28.05.541.133.796.262.504.256.914.666 1.17 1.17.13.255.212.516.262.796.05.276.066.558.073.837Zm-2.64 4.72h.002c1.094 1.348.797 2.791.657 2.519-.573-1.113-1.639-.83-2.179-.549a3.493 3.493 0 0 1-.144.081l-.01.006.002-.001c-1.124.596-2.632.64-4.149-.011A6.673 6.673 0 0 1 1.28 7.342c.345.254.718.478 1.114.664 1.603.75 3.213.697 4.352 0C5.124 6.757 3.77 5.133 2.732 3.817a5.644 5.644 0 0 1-.534-.736c1.243 1.138 3.206 2.566 3.91 2.962-1.494-1.58-2.812-3.525-2.75-3.463 2.355 2.373 4.528 3.714 4.528 3.714.081.045.142.081.19.113a3.52 3.52 0 0 0 .12-.355C8.57 4.68 8.147 3.107 7.19 1.81c2.184 1.311 3.475 3.803 2.946 5.91-.01.04-.022.08-.034.12l-.007.024v.001Z" transform="translate(.629 .629)"/></svg>

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

@@ -1,9 +1 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.3644 4.77374C14.3679 4.90203 14.3693 5.03012 14.3701 5.15827C14.371 5.30448 14.371 5.45074 14.371 5.59694L14.371 5.61482V10.3851L14.371 10.419C14.371 10.56 14.371 10.7008 14.3701 10.8418C14.3693 10.97 14.3679 11.098 14.3643 11.2261C14.3569 11.5053 14.3404 11.787 14.2908 12.063C14.2404 12.3433 14.1582 12.6042 14.0285 12.8589C13.9012 13.1091 13.7348 13.3379 13.5363 13.5363C13.3379 13.7349 13.109 13.9013 12.8587 14.0287C12.6042 14.1582 12.3435 14.2404 12.0633 14.2907C11.7871 14.3404 11.5055 14.357 11.2262 14.3644C11.0979 14.3678 10.9698 14.3694 10.8416 14.3701C10.7059 14.3711 10.5701 14.371 10.4344 14.371L10.3851 14.371H5.61479L5.56546 14.371C5.42967 14.371 5.294 14.3711 5.15832 14.3701C5.03009 14.3694 4.90183 14.3678 4.77379 14.3644C4.49456 14.357 4.21273 14.3404 3.93665 14.2907C3.65646 14.2404 3.39572 14.1583 3.1412 14.0287C2.89094 13.9013 2.66197 13.7349 2.46358 13.5363C2.26504 13.3379 2.09864 13.1091 1.97135 12.8589C1.84168 12.6042 1.75951 12.3433 1.70913 12.063C1.65955 11.787 1.6431 11.5053 1.63559 11.2261C1.63207 11.098 1.63059 10.9699 1.62975 10.8418C1.62888 10.7073 1.62889 10.5729 1.62891 10.4384C1.62891 10.4207 1.62891 10.4029 1.62891 10.3851V7.69203V5.61482C1.62891 5.5988 1.62891 5.58279 1.62891 5.56677C1.6289 5.43062 1.62889 5.29442 1.62975 5.15824C1.63059 5.0301 1.63207 4.90201 1.63559 4.77371C1.6431 4.49463 1.65957 4.21302 1.70913 3.93692C1.75951 3.65653 1.84168 3.39582 1.97135 3.14111C2.09864 2.89097 2.26504 2.66207 2.46358 2.46357C2.51319 2.41395 2.5647 2.36634 2.61797 2.32083C2.77779 2.18434 2.9535 2.06688 3.14118 1.97136C3.20482 1.93899 3.26884 1.90955 3.33344 1.88286C3.52726 1.80273 3.72649 1.74703 3.93659 1.70927C4.14367 1.67196 4.35399 1.6534 4.56399 1.64328C4.63399 1.63991 4.70396 1.63746 4.77377 1.63558C4.90181 1.6321 5.03007 1.63064 5.1583 1.62985C5.31041 1.62897 5.4625 1.62897 5.61477 1.62897H7.01212H10.3851C10.5372 1.62897 10.6895 1.62897 10.8417 1.62983C10.9698 1.63062 11.098 1.63208 11.2262 1.63555C11.5055 1.64311 11.7871 1.6595 12.0633 1.70925C12.3435 1.75958 12.6042 1.84184 12.8587 1.97136C13.109 2.09872 13.3379 2.2651 13.5363 2.46359C13.7348 2.66209 13.9012 2.89099 14.0285 3.14113C14.1582 3.39584 14.2405 3.65655 14.2908 3.93694C14.3404 4.21304 14.3569 4.49465 14.3644 4.77374ZM11.7247 9.49334L11.7256 9.49437C12.8204 10.8415 12.5226 12.2854 12.3825 12.013C11.8103 10.8996 10.7442 11.1838 10.2044 11.464C10.1597 11.4907 10.1139 11.5159 10.0678 11.5407C10.0653 11.5422 10.0626 11.5438 10.0598 11.5454C10.0567 11.5472 10.0535 11.549 10.0508 11.5508L10.0517 11.5495C8.92831 12.1464 7.42003 12.1906 5.9033 11.5388C4.63145 10.9922 3.58646 10.0558 2.90796 8.97051C3.25297 9.22522 3.62568 9.4494 4.02214 9.6352C5.62503 10.3859 7.23492 10.3317 8.37424 9.63447C6.75268 8.38742 5.39918 6.76342 4.36131 5.4472C4.16168 5.21114 3.98007 4.96593 3.82737 4.71129C5.07019 5.84879 7.03337 7.27717 7.73781 7.67251C6.24262 6.09283 4.92514 4.14748 4.98693 4.20977C7.34176 6.58253 9.51444 7.92402 9.51444 7.92402C9.59627 7.96914 9.6572 8.00521 9.70556 8.03698C9.75012 7.92263 9.79044 7.80497 9.82397 7.68238C10.2 6.30796 9.77677 4.73633 8.81962 3.43877C11.0038 4.7504 12.2945 7.24149 11.7657 9.34852C11.7554 9.38939 11.7436 9.42922 11.7319 9.46905C11.7295 9.47714 11.7271 9.48524 11.7247 9.49334Z" fill="url(#paint0_linear_1002_71731)"/>
<defs>
<linearGradient id="paint0_linear_1002_71731" x1="-5.10791" y1="12.7483" x2="13.6219" y2="12.7483" gradientUnits="userSpaceOnUse">
<stop stop-color="#D8FFEC" stop-opacity="0.6"/>
<stop offset="1" stop-color="#F4FFFA"/>
</linearGradient>
</defs>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13"><defs><linearGradient id="a" x1="-52.871%" x2="94.121%" y1="87.265%" y2="87.265%"><stop offset="0%" stop-color="#949494"/><stop offset="100%" stop-color="#FFF"/></linearGradient></defs><path fill="url(#a)" fill-rule="evenodd" d="M12.735 3.145c.004.128.005.256.006.384l.001.439v5.245c-.002.128-.003.256-.007.384-.007.28-.024.561-.073.837a2.84 2.84 0 0 1-.262.796 2.67 2.67 0 0 1-1.17 1.17 2.83 2.83 0 0 1-.796.262c-.276.05-.557.066-.837.073a16.39 16.39 0 0 1-.384.006l-.408.001H3.53c-.128-.002-.256-.003-.384-.007a5.558 5.558 0 0 1-.837-.073 2.82 2.82 0 0 1-.796-.262 2.671 2.671 0 0 1-1.17-1.17 2.825 2.825 0 0 1-.262-.796 5.585 5.585 0 0 1-.073-.837A18.376 18.376 0 0 1 0 9.213V3.53c.002-.128.003-.256.007-.384.007-.28.024-.561.073-.837.05-.28.133-.541.262-.796A2.673 2.673 0 0 1 1.705.254c.193-.08.393-.136.603-.174.207-.037.417-.056.627-.066.07-.003.14-.006.21-.007C3.273.003 3.4.002 3.529 0h5.684c.128.002.256.003.384.007.28.007.561.024.837.073.28.05.541.133.796.262.504.256.914.666 1.17 1.17.13.255.212.516.262.796.05.276.066.558.073.837Zm-2.64 4.72h.002c1.094 1.348.797 2.791.657 2.519-.573-1.113-1.639-.83-2.179-.549a3.493 3.493 0 0 1-.144.081l-.01.006.002-.001c-1.124.596-2.632.64-4.149-.011A6.673 6.673 0 0 1 1.28 7.342c.345.254.718.478 1.114.664 1.603.75 3.213.697 4.352 0C5.124 6.757 3.77 5.133 2.732 3.817a5.644 5.644 0 0 1-.534-.736c1.243 1.138 3.206 2.566 3.91 2.962-1.494-1.58-2.812-3.525-2.75-3.463 2.355 2.373 4.528 3.714 4.528 3.714.081.045.142.081.19.113a3.52 3.52 0 0 0 .12-.355C8.57 4.68 8.147 3.107 7.19 1.81c2.184 1.311 3.475 3.803 2.946 5.91-.01.04-.022.08-.034.12l-.007.024v.001Z"/></svg>

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg fill="#000000" width="800px" height="800px" viewBox="0 0 24 24" role="img" xmlns="http://www.w3.org/2000/svg"><title>OpenAI icon</title><path d="M22.2819 9.8211a5.9847 5.9847 0 0 0-.5157-4.9108 6.0462 6.0462 0 0 0-6.5098-2.9A6.0651 6.0651 0 0 0 4.9807 4.1818a5.9847 5.9847 0 0 0-3.9977 2.9 6.0462 6.0462 0 0 0 .7427 7.0966 5.98 5.98 0 0 0 .511 4.9107 6.051 6.051 0 0 0 6.5146 2.9001A5.9847 5.9847 0 0 0 13.2599 24a6.0557 6.0557 0 0 0 5.7718-4.2058 5.9894 5.9894 0 0 0 3.9977-2.9001 6.0557 6.0557 0 0 0-.7475-7.0729zm-9.022 12.6081a4.4755 4.4755 0 0 1-2.8764-1.0408l.1419-.0804 4.7783-2.7582a.7948.7948 0 0 0 .3927-.6813v-6.7369l2.02 1.1686a.071.071 0 0 1 .038.052v5.5826a4.504 4.504 0 0 1-4.4945 4.4944zm-9.6607-4.1254a4.4708 4.4708 0 0 1-.5346-3.0137l.142.0852 4.783 2.7582a.7712.7712 0 0 0 .7806 0l5.8428-3.3685v2.3324a.0804.0804 0 0 1-.0332.0615L9.74 19.9502a4.4992 4.4992 0 0 1-6.1408-1.6464zM2.3408 7.8956a4.485 4.485 0 0 1 2.3655-1.9728V11.6a.7664.7664 0 0 0 .3879.6765l5.8144 3.3543-2.0201 1.1685a.0757.0757 0 0 1-.071 0l-4.8303-2.7865A4.504 4.504 0 0 1 2.3408 7.872zm16.5963 3.8558L13.1038 8.364 15.1192 7.2a.0757.0757 0 0 1 .071 0l4.8303 2.7913a4.4944 4.4944 0 0 1-.6765 8.1042v-5.6772a.79.79 0 0 0-.407-.667zm2.0107-3.0231l-.142-.0852-4.7735-2.7818a.7759.7759 0 0 0-.7854 0L9.409 9.2297V6.8974a.0662.0662 0 0 1 .0284-.0615l4.8303-2.7866a4.4992 4.4992 0 0 1 6.6802 4.66zM8.3065 12.863l-2.02-1.1638a.0804.0804 0 0 1-.038-.0567V6.0742a4.4992 4.4992 0 0 1 7.3757-3.4537l-.142.0805L8.704 5.459a.7948.7948 0 0 0-.3927.6813zm1.0976-2.3654l2.602-1.4998 2.6069 1.4998v2.9994l-2.5974 1.4997-2.6067-1.4997Z"/></svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg fill="#fff" width="800px" height="800px" viewBox="0 0 24 24" role="img" xmlns="http://www.w3.org/2000/svg"><title>OpenAI icon</title><path d="M22.2819 9.8211a5.9847 5.9847 0 0 0-.5157-4.9108 6.0462 6.0462 0 0 0-6.5098-2.9A6.0651 6.0651 0 0 0 4.9807 4.1818a5.9847 5.9847 0 0 0-3.9977 2.9 6.0462 6.0462 0 0 0 .7427 7.0966 5.98 5.98 0 0 0 .511 4.9107 6.051 6.051 0 0 0 6.5146 2.9001A5.9847 5.9847 0 0 0 13.2599 24a6.0557 6.0557 0 0 0 5.7718-4.2058 5.9894 5.9894 0 0 0 3.9977-2.9001 6.0557 6.0557 0 0 0-.7475-7.0729zm-9.022 12.6081a4.4755 4.4755 0 0 1-2.8764-1.0408l.1419-.0804 4.7783-2.7582a.7948.7948 0 0 0 .3927-.6813v-6.7369l2.02 1.1686a.071.071 0 0 1 .038.052v5.5826a4.504 4.504 0 0 1-4.4945 4.4944zm-9.6607-4.1254a4.4708 4.4708 0 0 1-.5346-3.0137l.142.0852 4.783 2.7582a.7712.7712 0 0 0 .7806 0l5.8428-3.3685v2.3324a.0804.0804 0 0 1-.0332.0615L9.74 19.9502a4.4992 4.4992 0 0 1-6.1408-1.6464zM2.3408 7.8956a4.485 4.485 0 0 1 2.3655-1.9728V11.6a.7664.7664 0 0 0 .3879.6765l5.8144 3.3543-2.0201 1.1685a.0757.0757 0 0 1-.071 0l-4.8303-2.7865A4.504 4.504 0 0 1 2.3408 7.872zm16.5963 3.8558L13.1038 8.364 15.1192 7.2a.0757.0757 0 0 1 .071 0l4.8303 2.7913a4.4944 4.4944 0 0 1-.6765 8.1042v-5.6772a.79.79 0 0 0-.407-.667zm2.0107-3.0231l-.142-.0852-4.7735-2.7818a.7759.7759 0 0 0-.7854 0L9.409 9.2297V6.8974a.0662.0662 0 0 1 .0284-.0615l4.8303-2.7866a4.4992 4.4992 0 0 1 6.6802 4.66zM8.3065 12.863l-2.02-1.1638a.0804.0804 0 0 1-.038-.0567V6.0742a4.4992 4.4992 0 0 1 7.3757-3.4537l-.142.0805L8.704 5.459a.7948.7948 0 0 0-.3927.6813zm1.0976-2.3654l2.602-1.4998 2.6069 1.4998v2.9994l-2.5974 1.4997-2.6067-1.4997Z"/></svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

+1 -1
View File
@@ -23,7 +23,7 @@
}
body {
@apply bg-scale-100 dark:bg-[#1c1c1c] #{!important};
@apply bg-scale-200 dark:bg-[#1c1c1c] #{!important};
scroll-behavior: smooth;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
Loaded 100 of 498 files, more files were not shown because too many files have changed in this diff. Show more