diff --git a/apps/temp-docs/components/AuthProviders.tsx b/apps/temp-docs/components/AuthProviders.tsx new file mode 100644 index 00000000000..49389e585f8 --- /dev/null +++ b/apps/temp-docs/components/AuthProviders.tsx @@ -0,0 +1,38 @@ +import authProviders from '../data/authProviders' +import { Card } from '@supabase/ui' +import Link from 'next/link' + +export default function AuthProviders() { + return ( +
+ {authProviders.map((x: any) => ( +
+ + +
+

{x.name}

+

+ {x.official ? ( + Official + ) : ( + Unofficial + )} +

+
+
+
+ Platform: + {x.platform.toString()} +
+
+ Self-Hosted: + {x.selfHosted.toString()} +
+
+
+ +
+ ))} +
+ ) +} diff --git a/apps/temp-docs/components/CodeBlock/CodeBlock.module.css b/apps/temp-docs/components/CodeBlock/CodeBlock.module.css new file mode 100644 index 00000000000..9dda8e0be0c --- /dev/null +++ b/apps/temp-docs/components/CodeBlock/CodeBlock.module.css @@ -0,0 +1,24 @@ +.code-block::before { + content: ''; + background: #1e1e1e; + height: 10px; + width: 48px; + display: block; +} + +.code-block::after { + content: ''; + background: #1e1e1e; + height: 12px; + width: 48px; + display: block; +} + +.code-block code .linenumber { + margin-right: 4px; +} + +.code-block code::after, +.code-block code::before { + content: none !important; +} diff --git a/apps/temp-docs/components/CodeBlock/CodeBlock.tsx b/apps/temp-docs/components/CodeBlock/CodeBlock.tsx new file mode 100644 index 00000000000..d5dcc6c44ef --- /dev/null +++ b/apps/temp-docs/components/CodeBlock/CodeBlock.tsx @@ -0,0 +1,79 @@ +import { Light as SyntaxHighlighter } from 'react-syntax-highlighter' +import monokaiCustomTheme from './CodeBlock.utils' +import CodeBlockStyles from './CodeBlock.module.css' +import { Button, IconCopy } from '@supabase/ui' +import CopyToClipboard from 'react-copy-to-clipboard' + +import js from 'react-syntax-highlighter/dist/cjs/languages/hljs/javascript' +import py from 'react-syntax-highlighter/dist/cjs/languages/hljs/python' +import sql from 'react-syntax-highlighter/dist/cjs/languages/hljs/sql' + +interface Props { + lang: 'js' | 'sql' | 'py' + startingLineNumber?: number + hideCopy?: boolean + className?: string + children?: string + size?: 'small' | 'medium' | 'large' +} + +function CodeBlock(props: Props) { + let lang = props.lang + ? props.lang + : props.className + ? props.className.replace('language-', '') + : 'js' + // force jsx to be js highlighted + if (lang === 'jsx') lang = 'js' + + SyntaxHighlighter.registerLanguage('js', js) + SyntaxHighlighter.registerLanguage('py', py) + SyntaxHighlighter.registerLanguage('sql', sql) + + // const large = props.size === 'large' ? true : false + const large = false + + return ( +
+ + {props.children} + + {!props.hideCopy && props.children ? ( +
+ + + +
+ ) : null} +
+ ) +} + +export default CodeBlock diff --git a/apps/temp-docs/components/CodeBlock/CodeBlock.utils.js b/apps/temp-docs/components/CodeBlock/CodeBlock.utils.js new file mode 100644 index 00000000000..4233bf1548a --- /dev/null +++ b/apps/temp-docs/components/CodeBlock/CodeBlock.utils.js @@ -0,0 +1,116 @@ +const monokaiCustomTheme = { + hljs: { + display: 'block', + overflowX: 'auto', + padding: '0.5em', + background: '#272822', + color: '#ddd', + }, + 'hljs-tag': { + color: '#569cd6', + }, + 'hljs-keyword': { + color: '#569cd6', + fontWeight: 'normal', + }, + 'hljs-selector-tag': { + color: '#569cd6', + fontWeight: 'normal', + }, + 'hljs-literal': { + color: '#569cd6', + fontWeight: 'normal', + }, + 'hljs-strong': { + color: '#569cd6', + }, + 'hljs-name': { + color: '#569cd6', + }, + 'hljs-code': { + color: '#66d9ef', + }, + 'hljs-class .hljs-title': { + color: 'gray', + }, + 'hljs-attribute': { + color: '#bf79db', + }, + 'hljs-symbol': { + color: '#bf79db', + }, + 'hljs-regexp': { + color: '#bf79db', + }, + 'hljs-link': { + color: '#bf79db', + }, + 'hljs-string': { + color: '#3ECF8E', + }, + 'hljs-bullet': { + color: '#3ECF8E', + }, + 'hljs-subst': { + color: '#3ECF8E', + }, + 'hljs-title': { + color: '#3ECF8E', + fontWeight: 'normal', + }, + 'hljs-section': { + color: '#3ECF8E', + fontWeight: 'normal', + }, + 'hljs-emphasis': { + color: '#3ECF8E', + }, + 'hljs-type': { + color: '#3ECF8E', + fontWeight: 'normal', + }, + 'hljs-built_in': { + color: '#3ECF8E', + }, + 'hljs-builtin-name': { + color: '#3ECF8E', + }, + 'hljs-selector-attr': { + color: '#3ECF8E', + }, + 'hljs-selector-pseudo': { + color: '#3ECF8E', + }, + 'hljs-addition': { + color: '#3ECF8E', + }, + 'hljs-variable': { + color: '#3ECF8E', + }, + 'hljs-template-tag': { + color: '#3ECF8E', + }, + 'hljs-template-variable': { + color: '#3ECF8E', + }, + 'hljs-comment': { + color: '#75715e', + }, + 'hljs-quote': { + color: '#75715e', + }, + 'hljs-deletion': { + color: '#75715e', + }, + 'hljs-meta': { + color: '#75715e', + }, + 'hljs-doctag': { + fontWeight: 'normal', + }, + 'hljs-selector-id': { + fontWeight: 'normal', + }, +} + +export default monokaiCustomTheme diff --git a/apps/temp-docs/components/Footer.tsx b/apps/temp-docs/components/Footer.tsx new file mode 100644 index 00000000000..66621bfb73a --- /dev/null +++ b/apps/temp-docs/components/Footer.tsx @@ -0,0 +1,116 @@ +import { Typography } from '@supabase/ui' +import Link from 'next/link' +import footer from '../data/footer.json' +import { useTheme } from './Providers' + +const Footer = () => { + const { isDarkMode } = useTheme() + + return ( + + ) +} + +export default Footer diff --git a/apps/temp-docs/components/LinkCard.tsx b/apps/temp-docs/components/LinkCard.tsx new file mode 100644 index 00000000000..42012461a5b --- /dev/null +++ b/apps/temp-docs/components/LinkCard.tsx @@ -0,0 +1,27 @@ +import { ReactElement } from 'react' + +export default function LinkCard({ + title, + description, + icon, +}: { + title: string + description: string + icon: ReactElement +}) { + return ( +
+ {description ? ( + <> +

{title}

+

{description}

+ + ) : ( +
+ {icon} +

{title}

+
+ )} +
+ ) +} diff --git a/apps/temp-docs/components/LinkCardsWrapper.tsx b/apps/temp-docs/components/LinkCardsWrapper.tsx new file mode 100644 index 00000000000..9b348e17216 --- /dev/null +++ b/apps/temp-docs/components/LinkCardsWrapper.tsx @@ -0,0 +1,5 @@ +import { ReactElement } from 'react' + +export default function LinkCardsWrapper({ children }: { children: ReactElement }) { + return
{children}
+} diff --git a/apps/temp-docs/components/Providers.tsx b/apps/temp-docs/components/Providers.tsx new file mode 100644 index 00000000000..e1150217ff9 --- /dev/null +++ b/apps/temp-docs/components/Providers.tsx @@ -0,0 +1,45 @@ + +import { createContext, useContext, useEffect, useState } from 'react' + +interface UseThemeProps { + isDarkMode?: boolean + toggleTheme: () => void +} + +interface ThemeProviderProps { + children?: any +} + +export const ThemeContext = createContext({ + isDarkMode: true, + toggleTheme: () => {}, +}) + +export const useTheme = () => useContext(ThemeContext) + +export const ThemeProvider = ({ children }: ThemeProviderProps) => { + const [isDarkMode, setIsDarkMode] = useState(false) + + useEffect(() => { + const key = localStorage.getItem('supabaseDarkMode') + // Default to dark mode if no preference config + setIsDarkMode(!key || key === 'true') + }, []) + + const toggleTheme = () => { + setIsDarkMode(!isDarkMode) + } + + return ( + <> + + {children} + + + ) +} \ No newline at end of file diff --git a/apps/temp-docs/components/Sponsor.tsx b/apps/temp-docs/components/Sponsor.tsx new file mode 100644 index 00000000000..67d2e8a326c --- /dev/null +++ b/apps/temp-docs/components/Sponsor.tsx @@ -0,0 +1,13 @@ +import Image from 'next/image' +export default function Sponsor({ imageUrl, handle }: { imageUrl: string; handle: string }) { + return ( +
+ {handle} +
{handle}
+
+ ) +} diff --git a/apps/temp-docs/components/SponsorsWrapper.tsx b/apps/temp-docs/components/SponsorsWrapper.tsx new file mode 100644 index 00000000000..1729d7cc3b2 --- /dev/null +++ b/apps/temp-docs/components/SponsorsWrapper.tsx @@ -0,0 +1,4 @@ +import { ReactElement } from 'react' +export default function SponsorsWrapper({ children }: { children: ReactElement }) { + return
{children}
+} diff --git a/apps/temp-docs/components/TabPanel.tsx b/apps/temp-docs/components/TabPanel.tsx new file mode 100644 index 00000000000..453668972f9 --- /dev/null +++ b/apps/temp-docs/components/TabPanel.tsx @@ -0,0 +1,10 @@ +import { ReactElement } from 'react' +import { Tabs } from '@supabase/ui' +export default function TabPanel(props) { + console.log({ props }) + return ( + + {props.children} + + ) +} diff --git a/apps/temp-docs/components/TabWrapper.tsx b/apps/temp-docs/components/TabWrapper.tsx new file mode 100644 index 00000000000..9412b506312 --- /dev/null +++ b/apps/temp-docs/components/TabWrapper.tsx @@ -0,0 +1,10 @@ +import { Tabs } from '@supabase/ui' + +const TabWrapper = (props) => { + console.log('Tab props: ', props) + const { children, ...otherProps } = props + + return {props.children} +} + +export default TabWrapper diff --git a/apps/temp-docs/components/ThemeToggle.tsx b/apps/temp-docs/components/ThemeToggle.tsx new file mode 100644 index 00000000000..39166b0afd8 --- /dev/null +++ b/apps/temp-docs/components/ThemeToggle.tsx @@ -0,0 +1,23 @@ +import { useTheme } from './Providers' +import { IconSun, IconMoon } from '@supabase/ui' + +function DarkModeToggle() { + const { isDarkMode, toggleTheme } = useTheme() + + const toggleDarkMode = () => { + localStorage.setItem('supabaseDarkMode', (!isDarkMode).toString()) + toggleTheme() + + const key = localStorage.getItem('supabaseDarkMode') + document.documentElement.className = key === 'true' ? 'dark' : '' + } + + return ( + + ) +} + +export default DarkModeToggle \ No newline at end of file diff --git a/apps/temp-docs/components/index.tsx b/apps/temp-docs/components/index.tsx new file mode 100644 index 00000000000..66a9bd5fe36 --- /dev/null +++ b/apps/temp-docs/components/index.tsx @@ -0,0 +1,22 @@ +import LinkCard from './LinkCard' +import LinkCardsWrapper from './LinkCardsWrapper' +import { Tabs } from '@supabase/ui' +import Sponsor from './Sponsor' +import SponsorsWrapper from './SponsorsWrapper' +import CodeBlock from './CodeBlock/CodeBlock' +import AuthProviders from './AuthProviders' + +const components = { + LinkCard, + LinkCardsWrapper, + SponsorsWrapper, + Sponsor, + AuthProviders, + Tabs: (props: any) => , + TabsPanel: (props: any) => { + return + }, + code: (props: any) => , +} + +export default components diff --git a/apps/temp-docs/components/layouts/Layout.tsx b/apps/temp-docs/components/layouts/Layout.tsx new file mode 100644 index 00000000000..84480d36289 --- /dev/null +++ b/apps/temp-docs/components/layouts/Layout.tsx @@ -0,0 +1,69 @@ +import { ReactElement, useState } from 'react' +import Head from 'next/head' +import NavBar from '../nav/NavBar' +import SideBar from '../nav/SideBar' +import Footer from '../Footer' + +const DocsLayout = ({ + meta, + children, + toc, + menuItems, + currentPage, +}: { + meta: { title: string; description: string } + children: string + toc: any + menuItems: any + currentPage: string +}) => { + const theme = 'okaidia' + + return ( + <> + + {meta?.title} | Supabase + + + + + + + + + + + +
+ +
+ +
+
+ {children} +
+
+
On this page
+ {toc + ? toc.json.map((item: any) => { + return ( +
  • + {item.content} +
  • + ) + }) + : 'Please note: No TOC on this page'} +
    +
    +
    +
    +
    + + ) +} + +export default DocsLayout diff --git a/apps/temp-docs/components/nav/NavBar.tsx b/apps/temp-docs/components/nav/NavBar.tsx new file mode 100644 index 00000000000..ff2f8c6fb8a --- /dev/null +++ b/apps/temp-docs/components/nav/NavBar.tsx @@ -0,0 +1,103 @@ +import { useState, useEffect } from 'react' +import { + IconMenu, + IconGitHub, + IconTwitter, + IconSearch, + Input, + IconCommand, + Button, +} from '@supabase/ui' +import Image from 'next/image' +import Link from 'next/link' +import styles from '../../styles/Home.module.css' +import { useTheme } from '../Providers' + +const NavBar = ({ currentPage }: { currentPage: string }) => { + const [mounted, setMounted] = useState(false) + const { isDarkMode } = useTheme() + + useEffect(() => { + setMounted(true) + }, [isDarkMode]) + + const pageLinks = [ + { text: 'Overview', active: currentPage == 'Docs', link: '/' }, + { text: 'Guides', active: currentPage == 'Guides', link: '/guides' }, + { + text: 'Reference', + active: currentPage == 'Reference', + link: '/reference/javascript/supabase-client', + }, + ] + + return ( + + ) +} +export default NavBar diff --git a/apps/temp-docs/components/nav/SideBar.tsx b/apps/temp-docs/components/nav/SideBar.tsx new file mode 100644 index 00000000000..dfe5c9897db --- /dev/null +++ b/apps/temp-docs/components/nav/SideBar.tsx @@ -0,0 +1,61 @@ +import { Menu } from '@supabase/ui' +import Link from 'next/link' +import { useRouter } from 'next/router' +import styles from '../../styles/Home.module.css' +import ThemeToggle from '../ThemeToggle' + +const SideBar = ({ menuItems }: { menuItems: any }) => { + const { asPath } = useRouter() + return ( +
    + +
    + {Object.keys(menuItems).map((key) => { + return ( +
    + + {menuItems[key].map((item: { link: string; text: string; sections: Array }) => ( + + {Array.isArray(item.sections) ? ( + <> + + {item.sections.map((section) => ( + + + {section.text} + + + ))} + + ) : ( + + + + {item.text} + + + + )} + + ))} +
    + ) + })} +
    +
    + + + +
    +
    +
    + ) +} + +export default SideBar diff --git a/apps/temp-docs/components/nav/menu-items.json b/apps/temp-docs/components/nav/menu-items.json new file mode 100644 index 00000000000..13ef56c2d86 --- /dev/null +++ b/apps/temp-docs/components/nav/menu-items.json @@ -0,0 +1,806 @@ +{ + "Docs": { + "Overview": [ + { "text": "Introduction", "link": "/" }, + { "text": "Architecture", "link": "/architecture" }, + { "text": "Database", "link": "/guides/database" }, + { "text": "Auth", "link": "/guides/auth" }, + { "text": "Storage", "link": "/guides/storage" }, + { "text": "APIs", "link": "/guides/apis" }, + { "text": "Examples and Resources", "link": "/guides/examples" } + ], + "Tutorials": [ + { "text": "Quickstart: Angular", "link": "/guides/with-angular" }, + { "text": "Quickstart: Next.js", "link": "/guides/with-nextjs" }, + { "text": "Quickstart: Flutter", "link": "/guides/with-flutter" }, + { "text": "Quickstart: React", "link": "/guides/with-react" }, + { "text": "Quickstart: RedwoodJS", "link": "/guides/with-redwoodjs" }, + { "text": "Quickstart: Svelte", "link": "/guides/with-svelte" }, + { "text": "Quickstart: Vue 3", "link": "/guides/with-vue-3" } + ], + "See Also": [ + { "text": "FAQs", "link": "/faqs" }, + { "text": "Going into Prod Checklist", "link": "/going-into-prod" }, + { "text": "Contributing", "link": "/handbook/contributing" }, + { "text": "SupaSquad", "link": "/handbook/supasquad" }, + { "text": "Terms of Service", "link": "/company/terms" }, + { "text": "Privacy Policy", "link": "/company/privacy" }, + { "text": "Acceptable Use Policy", "link": "/company/aup" } + ] + }, + "Guides": { + "Guides": [ + { "text": "Overview", "link": "/guides" }, + { "text": "Local Development", "link": "/guides/local-development" } + ], + "Database": [ + { "text": "Introduction", "link": "/guides/database/introduction" }, + { "text": "Tables", "link": "/guides/database/tables" }, + { "text": "Functions", "link": "/guides/database/functions" }, + { "text": "Full Text Search", "link": "/guides/database/full-text-search" }, + { + "text": "Extensions", + "sections": [ + { + "text": "Overview", + "link": "/guides/database/extensions" + }, + { + "text": "plv8: Javascript Language", + "link": "/guides/database/extensions/plv8" + }, + { + "text": "http: RESTful Client", + "link": "/guides/database/extensions/http" + }, + { + "text": "uuid-ossp: Unique Identifiers", + "link": "/guides/database/extensions/uuid-ossp" + } + ] + }, + { + "text": "Connecting to Postgres", + "sections": [ + { + "text": "Overview", + "link": "/guides/database/connecting/connecting-to-postgres" + }, + { + "text": "Direct Connections", + "link": "/guides/database/connecting/direct-connections" + }, + { + "text": "Connection Pooling", + "link": "/guides/database/connecting/connection-pooling" + } + ] + }, + { + "text": "Configuration", + "sections": [ + { + "text": "Timeouts", + "link": "/guides/database/timeouts" + }, + { + "text": "Direct Connections", + "link": "/guides/database/replication" + }, + { + "text": "Passwords", + "link": "/guides/database/managing-passwords" + }, + { + "text": "Timezones", + "link": "/guides/database/managing-timezones" + } + ] + } + ], + "Auth": [ + { + "text": "Introduction", + "link": "/guides/auth/intro" + }, + { + "text": "Authentication", + "sections": [ + { "text": "Login With Email", "link": "/guides/auth/auth-email" }, + { "text": "Login With Magic Link", "link": "/guides/auth/auth-magic-link" }, + { "text": "Login With Apple", "link": "/guides/auth/auth-apple" }, + { "text": "Login With Bitbucket", "link": "/guides/auth/auth-bitbucket" }, + { "text": "Login With Discord", "link": "/guides/auth/auth-discord" }, + { "text": "Login With Facebook", "link": "/guides/auth/auth-facebook" }, + { "text": "Login With GitHub", "link": "/guides/auth/auth-gitHub" }, + { "text": "Login With GitLab", "link": "/guides/auth/auth-gitLab" }, + { "text": "Login With Google", "link": "/guides/auth/auth-google" }, + { "text": "Login With Slack", "link": "/guides/auth/auth-slack" }, + { "text": "Login With Spotify", "link": "/guides/auth/auth-spotify" }, + { "text": "Login With Twitter", "link": "/guides/auth/auth-twitter" }, + { "text": "Login With Twitch", "link": "/guides/auth/auth-twitch" }, + { "text": "Phone Auth With Twilio", "link": "/guides/auth/auth-twilio" }, + { "text": "Phone Auth With MessageBird", "link": "/guides/auth/auth-messageBird" } + ] + }, + { + "text": "Authorization", + "sections": [ + { "text": "Row Level Security", "link": "/guides/auth/row-level-security" }, + { "text": "Managing User Data", "link": "/guides/auth/managing-user-data" } + ] + }, + { + "text": "Deep Dive", + "link": [ + { "text": "Part One: JWTs", "link": "/guides/auth-deep-dive/auth-deep-dive-jwts" }, + { + "text": "Part Two: Row Level Security", + "link": "/guides/auth-deep-dive/auth-row-level-security" + }, + { "text": "Part Three: Policies", "link": "/guides/auth-deep-dive/auth-policies" }, + { "text": "Part Four: Gotrue", "link": "/guides/auth-deep-dive/auth-gotrue" }, + { "text": "Part Five: Google Oauth", "link": "/guides/auth-deep-dive/auth-google-auth" } + ] + } + ], + "Integrations": [ + { + "text": "Auth0", + "link": "/guides/integrations/auth0" + }, + { + "text": "Draftbit", + "link": "/guides/integrations/draftbit" + }, + { + "text": "Prisma", + "link": "/guides/integrations/prisma" + }, + { + "text": "Vercel", + "link": "/guides/integrations/vercel" + } + ], + "Self Hosting": [ + { "text": "Overview", "link": "/guides/hosting/overview" }, + { "text": "Supabase Platform", "link": "/guides/hosting/platform" }, + { "text": "With Docker", "link": "/guides/hosting/docker" } + ] + }, + "Reference": { + "JAVASCRIPT": [ + { + "text": "Getting Started", + "sections": [ + { "text": "Getting Started", "link": "/reference/javascript/index" }, + { "text": "Installing", "link": "/reference/javascript/installing" }, + { "text": "Initializing", "link": "/reference/javascript/initializing" }, + { "text": "Generating Types", "link": "/reference/javascript/generating-types" } + ] + }, + { + "text": "Auth", + "sections": [ + { "text": "signUp()", "link": "/reference/javascript/auth-signup" }, + { "text": "signIn()", "link": "/reference/javascript/auth-signin" }, + { "text": "signOut()", "link": "/reference/javascript/auth-signout" }, + { "text": "session()", "link": "/reference/javascript/auth-session" }, + { "text": "user()", "link": "/reference/javascript/auth-user" }, + { "text": "update()", "link": "/reference/javascript/auth-update" }, + { "text": "setAuth()", "link": "/reference/javascript/auth-setauth" }, + { "text": "onAuthStateChange()", "link": "/reference/javascript/auth-onauthstatechange" }, + { "text": "getUser()", "link": "/reference/javascript/auth-api-getuser" }, + { "text": "Reset Password(Email)", "link": "/reference/javascript/reset-password-email" } + ] + }, + { + "text": "Auth (Server Only)", + "sections": [ + { "text": "createUser()", "link": "/reference/javascript/auth-api-createuser" }, + { "text": "deleteUser()", "link": "/reference/javascript/auth-api-deleteuser" }, + { "text": "generateLink()", "link": "/reference/javascript/auth-api-generatelink" }, + { + "text": "inviteUserByEmail()", + "link": "/reference/javascript/auth-api-inviteuserbyemail" + }, + { "text": "sendMobileOTP()", "link": "/reference/javascript/auth-api-sendmobileotp" }, + { + "text": "resetPasswordForEmail()", + "link": "/reference/javascript/auth-api-resetpasswordforemail" + } + ] + }, + { + "text": "Database", + "sections": [ + { + "text": "Fetch data: select()", + "link": "/reference/javascript/select" + }, + { + "text": "Create data: insert()", + "link": "/reference/javascript/insert" + }, + { + "text": "Modify data: update()", + "link": "/reference/javascript/update" + }, + { + "text": "Upsert data: upsert()", + "link": "/reference/javascript/upsert" + }, + { + "text": "Delete data: delete()", + "link": "/reference/javascript/delete" + }, + { + "text": "Postgres functions: rpc()", + "link": "/reference/javascript/rpc" + } + ] + }, + { + "text": "Realtime", + "sections": [ + { + "text": "on().subscribe()", + "link": "/reference/javascript/subscribe" + }, + { + "text": "removeSubscription()", + "link": "/reference/javascript/removesubscription" + }, + { + "text": "removeAllSubscriptions()", + "link": "/reference/javascript/removeallsubscriptions" + }, + { + "text": "getSubscriptions()", + "link": "/reference/javascript/getsubscriptions" + } + ] + }, + { + "text": "Storage", + "sections": [ + { + "text": "createBucket()", + "link": "/reference/javascript/storage-createbucket" + }, + { + "text": "getBucket()", + "link": "/reference/javascript/storage-getbucket" + }, + { + "text": "listBuckets()", + "link": "/reference/javascript/storage-listbuckets" + }, + { + "text": "updateBucket()", + "link": "/reference/javascript/storage-updatebucket" + }, + { + "text": "deleteBucket()", + "link": "/reference/javascript/storage-deletebucket" + }, + { + "text": "emptyBucket()", + "link": "/reference/javascript/storage-emptybucket" + }, + { + "text": "from.upload()", + "link": "/reference/javascript/storage-from-upload" + }, + { + "text": "from.download()", + "link": "/reference/javascript/storage-from-download" + }, + { + "text": "from.list()", + "link": "/reference/javascript/storage-from-list" + }, + { + "text": "from.update()", + "link": "/reference/javascript/storage-from-update" + }, + { + "text": "from.move()", + "link": "/reference/javascript/storage-from-move" + }, + { + "text": "from.remove()", + "link": "/reference/javascript/storage-from-remove" + }, + { + "text": "from.createSignedUrl()", + "link": "/reference/javascript/storage-from-createsignedurl" + }, + { + "text": "from.getPublicUrl()", + "link": "/reference/javascript/storage-from-getpublicurl" + } + ] + }, + { + "text": "Modifiers", + "sections": [ + { + "text": "Using Modifiers", + "link": "/reference/javascript/using-modifiers" + }, + { + "text": "limit()", + "link": "/reference/javascript/limit" + }, + { + "text": "order()", + "link": "/reference/javascript/order" + }, + { + "text": "range()", + "link": "/reference/javascript/range" + }, + { + "text": "single()", + "link": "/reference/javascript/single" + }, + { + "text": "maybeSingle()", + "link": "/reference/javascript/maybesingle" + } + ] + }, + { + "text": "Filters", + "sections": [ + { + "text": "Using Filters", + "link": "/reference/javascript/using-filters" + }, + { + "text": "or()", + "link": "/reference/javascript/or" + }, + { + "text": "not()", + "link": "/reference/javascript/not" + }, + { + "text": "match()", + "link": "/reference/javascript/match" + }, + { + "text": "eq()", + "link": "/reference/javascript/eq" + }, + { + "text": "neq()", + "link": "/reference/javascript/neq" + }, + { + "text": "gt()", + "link": "/reference/javascript/gt" + }, + { + "text": "gte()", + "link": "/reference/javascript/gte" + }, + { + "text": "lt()", + "link": "/reference/javascript/lt" + }, + { + "text": "lte()", + "link": "/reference/javascript/lte" + }, + { + "text": "like()", + "link": "/reference/javascript/like" + }, + { + "text": "ilike()", + "link": "/reference/javascript/ilike" + }, + { + "text": "is()", + "link": "/reference/javascript/is" + }, + { + "text": "in()", + "link": "/reference/javascript/in" + }, + { + "text": "contains()", + "link": "/reference/javascript/contains" + }, + { + "text": "containedBy()", + "link": "/reference/javascript/containedby" + }, + { + "text": "rangeLt()", + "link": "/reference/javascript/rangelt" + }, + { + "text": "rangeGt()", + "link": "/reference/javascript/rangegt" + }, + { + "text": "rangeGte()", + "link": "/reference/javascript/rangegte" + }, + { + "text": "rangeLte()", + "link": "/reference/javascript/rangelte" + }, + + { + "text": "rangeAdjacent()", + "link": "/reference/javascript/rangeadjacent" + }, + { + "text": "overlaps()", + "link": "/reference/javascript/overlaps" + }, + { + "text": "textSearch()", + "link": "/reference/javascript/textsearch" + }, + { + "text": "filter()", + "link": "/reference/javascript/filter" + } + ] + } + ], + "DART": [ + { + "text": "Getting Started", + "sections": [ + { "text": "Installing", "link": "/reference/dart/installing" }, + { "text": "Initializing", "link": "/reference/dart/initializing" } + ] + }, + { + "text": "Auth", + "sections": [ + { "text": "signUp()", "link": "/reference/dart/auth-signup" }, + { "text": "signIn()", "link": "/reference/dart/auth-signin" }, + { "text": "signOut()", "link": "/reference/dart/auth-signout" }, + { "text": "session()", "link": "/reference/dart/auth-session" }, + { "text": "user()", "link": "/reference/dart/auth-user" }, + { "text": "update()", "link": "/reference/dart/auth-update" }, + { "text": "setAuth()", "link": "/reference/dart/auth-setauth" }, + { "text": "onAuthStateChange()", "link": "/reference/dart/auth-onauthsatechange" }, + { "text": "Reset Password(Email)", "link": "/reference/dart/reset-password-email" } + ] + }, + + { + "text": "Database", + "sections": [ + { + "text": "Fetch data: select()", + "link": "/reference/dart/select" + }, + { + "text": "Create data: insert()", + "link": "/reference/dart/insert" + }, + { + "text": "Modify data: update()", + "link": "/reference/dart/update" + }, + { + "text": "Upsert data: upsert()", + "link": "/reference/dart/upsert" + }, + { + "text": "Delete data: delete()", + "link": "/reference/dart/delete" + }, + { + "text": "Postgres functions: rpc()", + "link": "/reference/dart/rpc" + } + ] + }, + { + "text": "Realtime", + "sections": [ + { + "text": "on().subscribe()", + "link": "/reference/dart/subscribe" + }, + { + "text": "removeSubscription()", + "link": "/reference/dart/removesubscription" + }, + { + "text": "getSubscriptions()", + "link": "/reference/dart/getsubscriptions" + } + ] + }, + { + "text": "Storage", + "sections": [ + { + "text": "createBucket()", + "link": "/reference/dart/storage-createbucket" + }, + { + "text": "getBucket()", + "link": "/reference/dart/storage-getbucket" + }, + { + "text": "listBuckets()", + "link": "/reference/dart/storage-listbuckets" + }, + { + "text": "updateBucket()", + "link": "/reference/dart/storage-updatebucket" + }, + { + "text": "deleteBucket()", + "link": "/reference/dart/storage-deletebucket" + }, + { + "text": "emptyBucket()", + "link": "/reference/dart/storage-emptybucket" + }, + { + "text": "from.upload()", + "link": "/reference/dart/storage-from-upload" + }, + { + "text": "from.download()", + "link": "/reference/dart/storage-from-download" + }, + { + "text": "from.list()", + "link": "/reference/dart/storage-from-list" + }, + { + "text": "from.update()", + "link": "/reference/dart/storage-from-update" + }, + { + "text": "from.move()", + "link": "/reference/dart/storage-from-move" + }, + { + "text": "from.remove()", + "link": "/reference/dart/storage-from-remove" + }, + { + "text": "from.createSignedUrl()", + "link": "/reference/dart/storage-from-createsignedurl" + }, + { + "text": "from.getPublicUrl()", + "link": "/reference/dart/storage-from-getpublicurl" + } + ] + }, + { + "text": "Modifiers", + "sections": [ + { + "text": "Using Modifiers", + "link": "/reference/dart/using-modifiers" + }, + { + "text": "limit()", + "link": "/reference/dart/limit" + }, + { + "text": "order()", + "link": "/reference/dart/order" + }, + { + "text": "range()", + "link": "/reference/dart/range" + }, + { + "text": "single()", + "link": "/reference/dart/single" + }, + { + "text": "maybeSingle()", + "link": "/reference/dart/maybesingle" + } + ] + }, + { + "text": "Filters", + "sections": [ + { + "text": "Using Filters", + "link": "/reference/dart/using-filters" + }, + { + "text": "or()", + "link": "/reference/dart/or" + }, + { + "text": "not()", + "link": "/reference/dart/not" + }, + { + "text": "match()", + "link": "/reference/dart/match" + }, + { + "text": "eq()", + "link": "/reference/dart/eq" + }, + { + "text": "neq()", + "link": "/reference/dart/neq" + }, + { + "text": "gt()", + "link": "/reference/dart/gt" + }, + { + "text": "gte()", + "link": "/reference/dart/gte" + }, + { + "text": "lt()", + "link": "/reference/dart/lt" + }, + { + "text": "lte()", + "link": "/reference/dart/lte" + }, + { + "text": "like()", + "link": "/reference/dart/like" + }, + { + "text": "ilike()", + "link": "/reference/dart/ilike" + }, + { + "text": "is_()", + "link": "/reference/dart/is_" + }, + { + "text": "in_()", + "link": "/reference/dart/in_" + }, + { + "text": "contains()", + "link": "/reference/dart/contains" + }, + { + "text": "containedBy()", + "link": "/reference/dart/containedby" + }, + { + "text": "rangeLt()", + "link": "/reference/dart/rangelt" + }, + { + "text": "rangeGt()", + "link": "/reference/dart/rangegt" + }, + { + "text": "rangeGte()", + "link": "/reference/dart/rangegte" + }, + { + "text": "rangeLte()", + "link": "/reference/dart/rangelte" + }, + + { + "text": "rangeAdjacent()", + "link": "/reference/dart/rangeadjacent" + }, + { + "text": "overlaps()", + "link": "/reference/dart/overlaps" + }, + { + "text": "textSearch()", + "link": "/reference/dart/textsearch" + }, + { + "text": "filter()", + "link": "/reference/dart/filter" + } + ] + } + ], + "CLI": [ + { + "text": "About", + "sections": [{ "text": "About", "link": "/reference/cli/about" }] + }, + { + "text": "Command reference", + "sections": [ + { + "text": "supabase help", + "link": "/reference/cli/supabase-help" + }, + + { + "text": "supabase init", + "link": "/reference/cli/supabase-init" + }, + { + "text": "supabase start", + "link": "/reference/cli/supabase-start" + }, + { + "text": "supabase stop", + "link": "/reference/cli/supabase-stop" + }, + { + "text": "supabase eject", + "link": "/reference/cli/supabase-eject" + }, + + { + "text": "supabase db branch list", + "link": "/reference/cli/supabase-db-branch-list" + }, + { + "text": "supabase db branch create", + "link": "/reference/cli/supabase-db-branch-create" + }, + { + "text": "supabase db branch delete", + "link": "/reference/cli/supabase-db-branch-delete" + }, + { + "text": "supabase db switch", + "link": "/reference/cli/supabase-db-switch" + }, + { + "text": "supabase db changes", + "link": "/reference/cli/supabase-db-changes" + }, + { + "text": "supabase db commit", + "link": "/reference/cli/supabase-db-commit" + }, + { + "text": "supabase db reset", + "link": "/reference/cli/supabase-db-reset" + }, + { + "text": "supabase db remote set", + "link": "/reference/cli/supabase-db-remote-set" + }, + { + "text": "supabase db remote commit", + "link": "/reference/cli/supabase-db-remote-commit" + }, + { + "text": "supabase db push", + "link": "/reference/cli/supabase-db-push" + }, + { + "text": "supabase migration new", + "link": "/reference/cli/supabase-migration-new" + } + ] + }, + { + "text": "Config reference", + "sections": [ + { + "text": "Config reference", + "link": "/reference/cli/config-reference" + } + ] + } + ] + } +} diff --git a/apps/temp-docs/data/authProviders.js b/apps/temp-docs/data/authProviders.js new file mode 100644 index 00000000000..13770e5a00d --- /dev/null +++ b/apps/temp-docs/data/authProviders.js @@ -0,0 +1,148 @@ +const authProviders = [ + // { + // name: 'Email', + // // logo: '/img/libraries/dart-icon.svg', + // href: '/docs/guides/auth/auth-apple', + // official: true, + // supporter: 'Supabase', + // platform: true, + // selfHosted: true, + // }, + // { + // name: 'Magic Links', + // // logo: '/img/libraries/dart-icon.svg', + // href: '/docs/guides/auth/auth-apple', + // official: true, + // supporter: 'Supabase', + // platform: true, + // selfHosted: true, + // }, + { + name: 'Apple', + // logo: '/img/libraries/dart-icon.svg', + href: '/docs/guides/auth/auth-apple', + official: true, + supporter: 'Supabase', + platform: true, + selfHosted: true, + }, + { + name: 'Azure', + // logo: '/img/libraries/dart-icon.svg', + href: '/docs/guides/auth/auth-azure', + official: false, + supporter: 'TBD', + platform: true, + selfHosted: true, + }, + { + name: 'Bitbucket', + // logo: '/img/libraries/dart-icon.svg', + href: '/docs/guides/auth/auth-bitbucket', + official: true, + supporter: 'Supabase', + platform: true, + selfHosted: true, + }, + { + name: 'Discord', + // logo: '/img/libraries/dart-icon.svg', + href: '/docs/guides/auth/auth-discord', + official: true, + supporter: 'Supabase', + platform: true, + selfHosted: true, + }, + { + name: 'Facebook', + // logo: '/img/libraries/dart-icon.svg', + href: '/docs/guides/auth/auth-facebook', + official: true, + supporter: 'Supabase', + platform: true, + selfHosted: true, + }, + { + name: 'GitHub', + // logo: '/img/libraries/dart-icon.svg', + href: '/docs/guides/auth/auth-github', + official: true, + supporter: 'Supabase', + platform: true, + selfHosted: true, + }, + { + name: 'GitLab', + // logo: '/img/libraries/dart-icon.svg', + href: '/docs/guides/auth/auth-gitlab', + official: true, + supporter: 'Supabase', + platform: true, + selfHosted: true, + }, + { + name: 'Google', + // logo: '/img/libraries/dart-icon.svg', + href: '/docs/guides/auth/auth-google', + official: true, + supporter: 'Supabase', + platform: true, + selfHosted: true, + }, + { + name: 'MessageBird', + // logo: '/img/libraries/dart-icon.svg', + href: '/docs/guides/auth/auth-messagebird', + official: false, + supporter: 'MessageBird', + platform: true, + selfHosted: true, + }, + { + name: 'Slack', + // logo: '/img/libraries/dart-icon.svg', + href: '/docs/guides/auth/auth-slack', + official: true, + supporter: 'Supabase', + platform: true, + selfHosted: true, + }, + { + name: 'Spotify', + // logo: '/img/libraries/dart-icon.svg', + href: '/docs/guides/auth/auth-spotify', + official: true, + supporter: 'Supabase', + platform: true, + selfHosted: true, + }, + { + name: 'Twitter', + // logo: '/img/libraries/dart-icon.svg', + href: '/docs/guides/auth/auth-twitter', + official: true, + supporter: 'Supabase', + platform: true, + selfHosted: true, + }, + { + name: 'Twitch', + // logo: '/img/libraries/dart-icon.svg', + href: '/docs/guides/auth/auth-twitch', + official: true, + supporter: 'Supabase', + platform: true, + selfHosted: true, + }, + { + name: 'Twilio', + // logo: '/img/libraries/dart-icon.svg', + href: '/docs/guides/auth/auth-twilio', + official: true, + supporter: 'Supabase', + platform: true, + selfHosted: true, + }, +] + +export default authProviders \ No newline at end of file diff --git a/apps/temp-docs/data/contributors/contributors.json b/apps/temp-docs/data/contributors/contributors.json new file mode 100644 index 00000000000..5fc5ffb9e80 --- /dev/null +++ b/apps/temp-docs/data/contributors/contributors.json @@ -0,0 +1,42 @@ +[ + { + "username": "Exploringtechnologies", + "avatar_url": "https://avatars0.githubusercontent.com/u/66567938?v=4" + }, + { + "username": "awalias", + "avatar_url": "https://avatars3.githubusercontent.com/u/458736?v=4" + }, + { + "username": "dependabot-preview[bot]", + "avatar_url": "https://avatars3.githubusercontent.com/in/2141?v=4" + }, + { + "username": "dependabot[bot]", + "avatar_url": "https://avatars0.githubusercontent.com/in/29110?v=4" + }, + { + "username": "dragarcia", + "avatar_url": "https://avatars3.githubusercontent.com/u/26374889?v=4" + }, + { + "username": "kiwicopple", + "avatar_url": "https://avatars0.githubusercontent.com/u/10214025?v=4" + }, + { + "username": "mcbyrne", + "avatar_url": "https://avatars0.githubusercontent.com/u/851914?v=4" + }, + { + "username": "s-pace", + "avatar_url": "https://avatars2.githubusercontent.com/u/32097720?v=4" + }, + { + "username": "soedirgo", + "avatar_url": "https://avatars3.githubusercontent.com/u/31685197?v=4" + }, + { + "username": "teymour-aldridge", + "avatar_url": "https://avatars3.githubusercontent.com/u/42674621?v=4" + } +] diff --git a/apps/temp-docs/data/contributors/issues.json b/apps/temp-docs/data/contributors/issues.json new file mode 100644 index 00000000000..9ccb0d0f042 --- /dev/null +++ b/apps/temp-docs/data/contributors/issues.json @@ -0,0 +1,10 @@ +[ + { + "username": "dependabot-preview[bot]", + "avatar_url": "https://avatars3.githubusercontent.com/in/2141?v=4" + }, + { + "username": "kiwicopple", + "avatar_url": "https://avatars0.githubusercontent.com/u/10214025?v=4" + } +] diff --git a/apps/temp-docs/data/extensions.json b/apps/temp-docs/data/extensions.json new file mode 100644 index 00000000000..4014e6eeabc --- /dev/null +++ b/apps/temp-docs/data/extensions.json @@ -0,0 +1,478 @@ +[ + { + "name": "address_standardizer", + "schema": null, + "default_version": "3.1.1", + "installed_version": null, + "comment": "Used to parse an address into constituent elements. Generally used to support geocoding address normalization step." + }, + { + "name": "address_standardizer-3", + "schema": null, + "default_version": "3.1.1", + "installed_version": null, + "comment": "Used to parse an address into constituent elements. Generally used to support geocoding address normalization step." + }, + { + "name": "address_standardizer_data_us", + "schema": null, + "default_version": "3.1.1", + "installed_version": null, + "comment": "Address Standardizer US dataset example" + }, + { + "name": "address_standardizer_data_us-3", + "schema": null, + "default_version": "3.1.1", + "installed_version": null, + "comment": "Address Standardizer US dataset example" + }, + { + "name": "adminpack", + "schema": null, + "default_version": "2.0", + "installed_version": null, + "comment": "administrative functions for PostgreSQL" + }, + { + "name": "amcheck", + "schema": null, + "default_version": "1.2", + "installed_version": null, + "comment": "functions for verifying relation integrity" + }, + { + "name": "autoinc", + "schema": null, + "default_version": "1.0", + "installed_version": null, + "comment": "functions for autoincrementing fields" + }, + { + "name": "bloom", + "schema": null, + "default_version": "1.0", + "installed_version": null, + "comment": "bloom access method - signature file based index" + }, + { + "name": "btree_gin", + "schema": null, + "default_version": "1.3", + "installed_version": null, + "comment": "support for indexing common datatypes in GIN" + }, + { + "name": "btree_gist", + "schema": null, + "default_version": "1.5", + "installed_version": null, + "comment": "support for indexing common datatypes in GiST" + }, + { + "name": "citext", + "schema": null, + "default_version": "1.6", + "installed_version": null, + "comment": "data type for case-insensitive character strings" + }, + { + "name": "cube", + "schema": null, + "default_version": "1.4", + "installed_version": null, + "comment": "data type for multidimensional cubes" + }, + { + "name": "dblink", + "schema": null, + "default_version": "1.2", + "installed_version": null, + "comment": "connect to other PostgreSQL databases from within a database" + }, + { + "name": "dict_int", + "schema": null, + "default_version": "1.0", + "installed_version": null, + "comment": "text search dictionary template for integers" + }, + { + "name": "dict_xsyn", + "schema": null, + "default_version": "1.0", + "installed_version": null, + "comment": "text search dictionary template for extended synonym processing" + }, + { + "name": "earthdistance", + "schema": null, + "default_version": "1.1", + "installed_version": null, + "comment": "calculate great-circle distances on the surface of the Earth" + }, + { + "name": "file_fdw", + "schema": null, + "default_version": "1.0", + "installed_version": null, + "comment": "foreign-data wrapper for flat file access" + }, + { + "name": "fuzzystrmatch", + "schema": null, + "default_version": "1.1", + "installed_version": null, + "comment": "determine similarities and distance between strings" + }, + { + "name": "hstore", + "schema": null, + "default_version": "1.6", + "installed_version": null, + "comment": "data type for storing sets of (key, value) pairs" + }, + { + "name": "http", + "schema": "extensions", + "default_version": "1.3", + "installed_version": "1.3", + "comment": "HTTP client for PostgreSQL, allows web page retrieval inside the database." + }, + { + "name": "insert_username", + "schema": null, + "default_version": "1.0", + "installed_version": null, + "comment": "functions for tracking who changed a table" + }, + { + "name": "intagg", + "schema": null, + "default_version": "1.1", + "installed_version": null, + "comment": "integer aggregator and enumerator (obsolete)" + }, + { + "name": "intarray", + "schema": null, + "default_version": "1.2", + "installed_version": null, + "comment": "functions, operators, and index support for 1-D arrays of integers" + }, + { + "name": "isn", + "schema": null, + "default_version": "1.2", + "installed_version": null, + "comment": "data types for international product numbering standards" + }, + { + "name": "lo", + "schema": null, + "default_version": "1.1", + "installed_version": null, + "comment": "Large Object maintenance" + }, + { + "name": "ltree", + "schema": null, + "default_version": "1.1", + "installed_version": null, + "comment": "data type for hierarchical tree-like structures" + }, + { + "name": "moddatetime", + "schema": null, + "default_version": "1.0", + "installed_version": null, + "comment": "functions for tracking last modification time" + }, + { + "name": "pageinspect", + "schema": null, + "default_version": "1.7", + "installed_version": null, + "comment": "inspect the contents of database pages at a low level" + }, + { + "name": "pg_buffercache", + "schema": null, + "default_version": "1.3", + "installed_version": null, + "comment": "examine the shared buffer cache" + }, + { + "name": "pg_cron", + "schema": "extensions", + "default_version": "1.3", + "installed_version": "1.3", + "comment": "Job scheduler for PostgreSQL" + }, + { + "name": "pg_freespacemap", + "schema": null, + "default_version": "1.2", + "installed_version": null, + "comment": "examine the free space map (FSM)" + }, + { + "name": "pg_prewarm", + "schema": null, + "default_version": "1.2", + "installed_version": null, + "comment": "prewarm relation data" + }, + { + "name": "pg_stat_statements", + "schema": null, + "default_version": "1.7", + "installed_version": null, + "comment": "track execution statistics of all SQL statements executed" + }, + { + "name": "pg_trgm", + "schema": null, + "default_version": "1.4", + "installed_version": null, + "comment": "text similarity measurement and index searching based on trigrams" + }, + { + "name": "pg_visibility", + "schema": null, + "default_version": "1.2", + "installed_version": null, + "comment": "examine the visibility map (VM) and page-level visibility info" + }, + { + "name": "pgaudit", + "schema": null, + "default_version": "1.4", + "installed_version": null, + "comment": "provides auditing functionality" + }, + { + "name": "pgcrypto", + "schema": "extensions", + "default_version": "1.3", + "installed_version": "1.3", + "comment": "cryptographic functions" + }, + { + "name": "pgjwt", + "schema": "extensions", + "default_version": "0.1.0", + "installed_version": "0.1.0", + "comment": "JSON Web Token API for Postgresql" + }, + { + "name": "pgrowlocks", + "schema": null, + "default_version": "1.2", + "installed_version": null, + "comment": "show row-level locking information" + }, + { + "name": "pgstattuple", + "schema": null, + "default_version": "1.5", + "installed_version": null, + "comment": "show tuple-level statistics" + }, + { + "name": "pgtap", + "schema": null, + "default_version": "1.1.0", + "installed_version": null, + "comment": "Unit testing for PostgreSQL" + }, + { + "name": "plcoffee", + "schema": null, + "default_version": "3.0alpha", + "installed_version": null, + "comment": "PL/CoffeeScript (v8) trusted procedural language" + }, + { + "name": "pljava", + "schema": null, + "default_version": "1.6.0", + "installed_version": null, + "comment": "PL/Java procedural language (https://tada.github.io/pljava/)" + }, + { + "name": "plls", + "schema": null, + "default_version": "3.0alpha", + "installed_version": null, + "comment": "PL/LiveScript (v8) trusted procedural language" + }, + { + "name": "plpgsql", + "schema": "pg_catalog", + "default_version": "1.0", + "installed_version": "1.0", + "comment": "PL/pgSQL procedural language" + }, + { + "name": "plpgsql_check", + "schema": null, + "default_version": "1.11", + "installed_version": null, + "comment": "extended check for plpgsql functions" + }, + { + "name": "plv8", + "schema": null, + "default_version": "3.0alpha", + "installed_version": null, + "comment": "PL/JavaScript (v8) trusted procedural language" + }, + { + "name": "postgis", + "schema": null, + "default_version": "3.1.1", + "installed_version": null, + "comment": "PostGIS geometry and geography spatial types and functions" + }, + { + "name": "postgis-3", + "schema": null, + "default_version": "3.1.1", + "installed_version": null, + "comment": "PostGIS geometry and geography spatial types and functions" + }, + { + "name": "postgis_raster", + "schema": null, + "default_version": "3.1.1", + "installed_version": null, + "comment": "PostGIS raster types and functions" + }, + { + "name": "postgis_raster-3", + "schema": null, + "default_version": "3.1.1", + "installed_version": null, + "comment": "PostGIS raster types and functions" + }, + { + "name": "postgis_sfcgal", + "schema": null, + "default_version": "3.1.1", + "installed_version": null, + "comment": "PostGIS SFCGAL functions" + }, + { + "name": "postgis_sfcgal-3", + "schema": null, + "default_version": "3.1.1", + "installed_version": null, + "comment": "PostGIS SFCGAL functions" + }, + { + "name": "postgis_tiger_geocoder", + "schema": null, + "default_version": "3.1.1", + "installed_version": null, + "comment": "PostGIS tiger geocoder and reverse geocoder" + }, + { + "name": "postgis_tiger_geocoder-3", + "schema": null, + "default_version": "3.1.1", + "installed_version": null, + "comment": "PostGIS tiger geocoder and reverse geocoder" + }, + { + "name": "postgis_topology", + "schema": null, + "default_version": "3.1.1", + "installed_version": null, + "comment": "PostGIS topology spatial types and functions" + }, + { + "name": "postgis_topology-3", + "schema": null, + "default_version": "3.1.1", + "installed_version": null, + "comment": "PostGIS topology spatial types and functions" + }, + { + "name": "postgres_fdw", + "schema": null, + "default_version": "1.0", + "installed_version": null, + "comment": "foreign-data wrapper for remote PostgreSQL servers" + }, + { + "name": "refint", + "schema": null, + "default_version": "1.0", + "installed_version": null, + "comment": "functions for implementing referential integrity (obsolete)" + }, + { + "name": "seg", + "schema": null, + "default_version": "1.3", + "installed_version": null, + "comment": "data type for representing line segments or floating-point intervals" + }, + { + "name": "sslinfo", + "schema": null, + "default_version": "1.2", + "installed_version": null, + "comment": "information about SSL certificates" + }, + { + "name": "tablefunc", + "schema": null, + "default_version": "1.0", + "installed_version": null, + "comment": "functions that manipulate whole tables, including crosstab" + }, + { + "name": "tcn", + "schema": null, + "default_version": "1.0", + "installed_version": null, + "comment": "Triggered change notifications" + }, + { + "name": "tsm_system_rows", + "schema": null, + "default_version": "1.0", + "installed_version": null, + "comment": "TABLESAMPLE method which accepts number of rows as a limit" + }, + { + "name": "tsm_system_time", + "schema": null, + "default_version": "1.0", + "installed_version": null, + "comment": "TABLESAMPLE method which accepts time in milliseconds as a limit" + }, + { + "name": "unaccent", + "schema": null, + "default_version": "1.1", + "installed_version": null, + "comment": "text search dictionary that removes accents" + }, + { + "name": "uuid-ossp", + "schema": "extensions", + "default_version": "1.1", + "installed_version": "1.1", + "comment": "generate universally unique identifiers (UUIDs)" + }, + { + "name": "xml2", + "schema": null, + "default_version": "1.1", + "installed_version": null, + "comment": "XPath querying and XSLT" + } +] diff --git a/apps/temp-docs/data/footer.json b/apps/temp-docs/data/footer.json new file mode 100644 index 00000000000..bc33f9be523 --- /dev/null +++ b/apps/temp-docs/data/footer.json @@ -0,0 +1,86 @@ +[ + { + "title": "Company", + "links": [ + { + "text": "Blog", + "url": "https://supabase.com/blog" + }, + { + "text": "Open Source", + "url": "/oss" + }, + { + "text": "Humans.txt", + "url": "/humans.txt" + }, + { + "text": "Lawyers.txt", + "url": "/lawyers.txt" + } + ] + }, + { + "title": "Resources", + "links": [ + { + "text": "Brand Assets", + "url": "https://supabase.com/brand-assets" + }, + { + "text": "Docs", + "url": "/docs/" + }, + { + "text": "Pricing", + "url": "https://supabase.com/pricing" + }, + { + "text": "Support", + "url": "/docs/support" + }, + { + "text": "System Status", + "url": "https://status.supabase.com/" + } + ] + }, + { + "title": "Community", + "links": [ + { + "text": "GitHub", + "url": "https://github.com/supabase/supabase" + }, + { + "text": "Twitter", + "url": "https://twitter.com/supabase" + }, + { + "text": "DevTo", + "url": "https://dev.to/supabase" + }, + { + "text": "RSS", + "url": "https://supabase.com/rss.xml" + }, + { + "text": "Discord", + "url": "https://discord.supabase.com/" + }, + { + "text": "Youtube", + "url": "https://youtube.com/c/supabase" + } + ] + }, + { + "title": "Beta", + "links": [ + { + "text": "Join our beta", + "url": "https://app.supabase.io/" + } + ] + } +] \ No newline at end of file diff --git a/apps/temp-docs/data/github.js b/apps/temp-docs/data/github.js new file mode 100644 index 00000000000..624f291bde7 --- /dev/null +++ b/apps/temp-docs/data/github.js @@ -0,0 +1,11 @@ +import supabase from './repos/supabase.json' +import realtime from './repos/realtime.json' +// import marketplace from './repos/marketplace.json' +import postgres from './repos/postgres.json' +import doctestJs from './repos/doctest-js.json' +import postgrestJs from './repos/postgrest-js.json' +import postgresApi from './repos/pg-api.json' + +const repos = [supabase, realtime, postgrestJs, postgres, doctestJs, postgresApi] + +export { repos, postgrestJs } diff --git a/apps/temp-docs/data/maintainers.json b/apps/temp-docs/data/maintainers.json new file mode 100644 index 00000000000..51523e20bd9 --- /dev/null +++ b/apps/temp-docs/data/maintainers.json @@ -0,0 +1,37 @@ +[ + { + "handle": "thorwebdev", + "description": "Steering committee", + "tags": ["Community", "JS/TS", "Documentation"] + }, + { + "handle": "lqmanh", + "description": "Python contributor", + "tags": ["Python"] + }, + { + "handle": "zlwaterfield", + "description": "Finding lots of bugs", + "tags": ["Community", "Documentation"] + }, + { + "handle": "aliharis", + "description": "Python contributor", + "tags": ["Python"] + }, + { + "handle": "logankilpatrick", + "description": "Community oversight", + "tags": ["Community", "JS/TS"] + }, + { + "handle": "0az", + "description": "Python contributor", + "tags": ["Python"] + }, + { + "handle": "acupofjose", + "description": "C# contributor", + "tags": ["C#"] + } +] diff --git a/apps/temp-docs/data/repos/.github.json b/apps/temp-docs/data/repos/.github.json new file mode 100644 index 00000000000..6330c128238 --- /dev/null +++ b/apps/temp-docs/data/repos/.github.json @@ -0,0 +1,117 @@ +{ + "id": 288653469, + "node_id": "MDEwOlJlcG9zaXRvcnkyODg2NTM0Njk=", + "name": ".github", + "full_name": "supabase/.github", + "private": false, + "owner": { + "login": "supabase", + "id": 54469796, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0NDY5Nzk2", + "avatar_url": "https://avatars.githubusercontent.com/u/54469796?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/supabase", + "html_url": "https://github.com/supabase", + "followers_url": "https://api.github.com/users/supabase/followers", + "following_url": "https://api.github.com/users/supabase/following{/other_user}", + "gists_url": "https://api.github.com/users/supabase/gists{/gist_id}", + "starred_url": "https://api.github.com/users/supabase/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/supabase/subscriptions", + "organizations_url": "https://api.github.com/users/supabase/orgs", + "repos_url": "https://api.github.com/users/supabase/repos", + "events_url": "https://api.github.com/users/supabase/events{/privacy}", + "received_events_url": "https://api.github.com/users/supabase/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/supabase/.github", + "description": "Org-wide default community health files & templates.", + "fork": false, + "url": "https://api.github.com/repos/supabase/.github", + "forks_url": "https://api.github.com/repos/supabase/.github/forks", + "keys_url": "https://api.github.com/repos/supabase/.github/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/supabase/.github/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/supabase/.github/teams", + "hooks_url": "https://api.github.com/repos/supabase/.github/hooks", + "issue_events_url": "https://api.github.com/repos/supabase/.github/issues/events{/number}", + "events_url": "https://api.github.com/repos/supabase/.github/events", + "assignees_url": "https://api.github.com/repos/supabase/.github/assignees{/user}", + "branches_url": "https://api.github.com/repos/supabase/.github/branches{/branch}", + "tags_url": "https://api.github.com/repos/supabase/.github/tags", + "blobs_url": "https://api.github.com/repos/supabase/.github/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/supabase/.github/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/supabase/.github/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/supabase/.github/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/supabase/.github/statuses/{sha}", + "languages_url": "https://api.github.com/repos/supabase/.github/languages", + "stargazers_url": "https://api.github.com/repos/supabase/.github/stargazers", + "contributors_url": "https://api.github.com/repos/supabase/.github/contributors", + "subscribers_url": "https://api.github.com/repos/supabase/.github/subscribers", + "subscription_url": "https://api.github.com/repos/supabase/.github/subscription", + "commits_url": "https://api.github.com/repos/supabase/.github/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/supabase/.github/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/supabase/.github/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/supabase/.github/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/supabase/.github/contents/{+path}", + "compare_url": "https://api.github.com/repos/supabase/.github/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/supabase/.github/merges", + "archive_url": "https://api.github.com/repos/supabase/.github/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/supabase/.github/downloads", + "issues_url": "https://api.github.com/repos/supabase/.github/issues{/number}", + "pulls_url": "https://api.github.com/repos/supabase/.github/pulls{/number}", + "milestones_url": "https://api.github.com/repos/supabase/.github/milestones{/number}", + "notifications_url": "https://api.github.com/repos/supabase/.github/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/supabase/.github/labels{/name}", + "releases_url": "https://api.github.com/repos/supabase/.github/releases{/id}", + "deployments_url": "https://api.github.com/repos/supabase/.github/deployments", + "created_at": "2020-08-19T06:35:23Z", + "updated_at": "2020-12-04T06:26:42Z", + "pushed_at": "2020-09-18T03:24:56Z", + "git_url": "git://github.com/supabase/.github.git", + "ssh_url": "git@github.com:supabase/.github.git", + "clone_url": "https://github.com/supabase/.github.git", + "svn_url": "https://github.com/supabase/.github", + "homepage": "https://supabase.com/", + "size": 10, + "stargazers_count": 2, + "watchers_count": 2, + "language": null, + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 0, + "license": null, + "forks": 0, + "open_issues": 0, + "watchers": 2, + "default_branch": "main", + "temp_clone_token": null, + "organization": { + "login": "supabase", + "id": 54469796, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0NDY5Nzk2", + "avatar_url": "https://avatars.githubusercontent.com/u/54469796?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/supabase", + "html_url": "https://github.com/supabase", + "followers_url": "https://api.github.com/users/supabase/followers", + "following_url": "https://api.github.com/users/supabase/following{/other_user}", + "gists_url": "https://api.github.com/users/supabase/gists{/gist_id}", + "starred_url": "https://api.github.com/users/supabase/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/supabase/subscriptions", + "organizations_url": "https://api.github.com/users/supabase/orgs", + "repos_url": "https://api.github.com/users/supabase/repos", + "events_url": "https://api.github.com/users/supabase/events{/privacy}", + "received_events_url": "https://api.github.com/users/supabase/received_events", + "type": "Organization", + "site_admin": false + }, + "network_count": 0, + "subscribers_count": 2 +} diff --git a/apps/temp-docs/data/repos/benchmarks.json b/apps/temp-docs/data/repos/benchmarks.json new file mode 100644 index 00000000000..e140613307c --- /dev/null +++ b/apps/temp-docs/data/repos/benchmarks.json @@ -0,0 +1,123 @@ +{ + "id": 298483351, + "node_id": "MDEwOlJlcG9zaXRvcnkyOTg0ODMzNTE=", + "name": "benchmarks", + "full_name": "supabase/benchmarks", + "private": false, + "owner": { + "login": "supabase", + "id": 54469796, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0NDY5Nzk2", + "avatar_url": "https://avatars.githubusercontent.com/u/54469796?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/supabase", + "html_url": "https://github.com/supabase", + "followers_url": "https://api.github.com/users/supabase/followers", + "following_url": "https://api.github.com/users/supabase/following{/other_user}", + "gists_url": "https://api.github.com/users/supabase/gists{/gist_id}", + "starred_url": "https://api.github.com/users/supabase/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/supabase/subscriptions", + "organizations_url": "https://api.github.com/users/supabase/orgs", + "repos_url": "https://api.github.com/users/supabase/repos", + "events_url": "https://api.github.com/users/supabase/events{/privacy}", + "received_events_url": "https://api.github.com/users/supabase/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/supabase/benchmarks", + "description": "Infrastucture benchmarks", + "fork": false, + "url": "https://api.github.com/repos/supabase/benchmarks", + "forks_url": "https://api.github.com/repos/supabase/benchmarks/forks", + "keys_url": "https://api.github.com/repos/supabase/benchmarks/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/supabase/benchmarks/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/supabase/benchmarks/teams", + "hooks_url": "https://api.github.com/repos/supabase/benchmarks/hooks", + "issue_events_url": "https://api.github.com/repos/supabase/benchmarks/issues/events{/number}", + "events_url": "https://api.github.com/repos/supabase/benchmarks/events", + "assignees_url": "https://api.github.com/repos/supabase/benchmarks/assignees{/user}", + "branches_url": "https://api.github.com/repos/supabase/benchmarks/branches{/branch}", + "tags_url": "https://api.github.com/repos/supabase/benchmarks/tags", + "blobs_url": "https://api.github.com/repos/supabase/benchmarks/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/supabase/benchmarks/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/supabase/benchmarks/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/supabase/benchmarks/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/supabase/benchmarks/statuses/{sha}", + "languages_url": "https://api.github.com/repos/supabase/benchmarks/languages", + "stargazers_url": "https://api.github.com/repos/supabase/benchmarks/stargazers", + "contributors_url": "https://api.github.com/repos/supabase/benchmarks/contributors", + "subscribers_url": "https://api.github.com/repos/supabase/benchmarks/subscribers", + "subscription_url": "https://api.github.com/repos/supabase/benchmarks/subscription", + "commits_url": "https://api.github.com/repos/supabase/benchmarks/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/supabase/benchmarks/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/supabase/benchmarks/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/supabase/benchmarks/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/supabase/benchmarks/contents/{+path}", + "compare_url": "https://api.github.com/repos/supabase/benchmarks/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/supabase/benchmarks/merges", + "archive_url": "https://api.github.com/repos/supabase/benchmarks/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/supabase/benchmarks/downloads", + "issues_url": "https://api.github.com/repos/supabase/benchmarks/issues{/number}", + "pulls_url": "https://api.github.com/repos/supabase/benchmarks/pulls{/number}", + "milestones_url": "https://api.github.com/repos/supabase/benchmarks/milestones{/number}", + "notifications_url": "https://api.github.com/repos/supabase/benchmarks/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/supabase/benchmarks/labels{/name}", + "releases_url": "https://api.github.com/repos/supabase/benchmarks/releases{/id}", + "deployments_url": "https://api.github.com/repos/supabase/benchmarks/deployments", + "created_at": "2020-09-25T06:09:13Z", + "updated_at": "2021-02-06T11:51:48Z", + "pushed_at": "2021-02-06T11:51:44Z", + "git_url": "git://github.com/supabase/benchmarks.git", + "ssh_url": "git@github.com:supabase/benchmarks.git", + "clone_url": "https://github.com/supabase/benchmarks.git", + "svn_url": "https://github.com/supabase/benchmarks", + "homepage": "https://supabase.com", + "size": 9251, + "stargazers_count": 13, + "watchers_count": 13, + "language": "JavaScript", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "forks_count": 1, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 6, + "license": { + "key": "mit", + "name": "MIT License", + "spdx_id": "MIT", + "url": "https://api.github.com/licenses/mit", + "node_id": "MDc6TGljZW5zZTEz" + }, + "forks": 1, + "open_issues": 6, + "watchers": 13, + "default_branch": "master", + "temp_clone_token": null, + "organization": { + "login": "supabase", + "id": 54469796, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0NDY5Nzk2", + "avatar_url": "https://avatars.githubusercontent.com/u/54469796?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/supabase", + "html_url": "https://github.com/supabase", + "followers_url": "https://api.github.com/users/supabase/followers", + "following_url": "https://api.github.com/users/supabase/following{/other_user}", + "gists_url": "https://api.github.com/users/supabase/gists{/gist_id}", + "starred_url": "https://api.github.com/users/supabase/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/supabase/subscriptions", + "organizations_url": "https://api.github.com/users/supabase/orgs", + "repos_url": "https://api.github.com/users/supabase/repos", + "events_url": "https://api.github.com/users/supabase/events{/privacy}", + "received_events_url": "https://api.github.com/users/supabase/received_events", + "type": "Organization", + "site_admin": false + }, + "network_count": 1, + "subscribers_count": 6 +} diff --git a/apps/temp-docs/data/repos/cli.json b/apps/temp-docs/data/repos/cli.json new file mode 100644 index 00000000000..cf0db8475a0 --- /dev/null +++ b/apps/temp-docs/data/repos/cli.json @@ -0,0 +1,123 @@ +{ + "id": 314160187, + "node_id": "MDEwOlJlcG9zaXRvcnkzMTQxNjAxODc=", + "name": "cli", + "full_name": "supabase/cli", + "private": false, + "owner": { + "login": "supabase", + "id": 54469796, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0NDY5Nzk2", + "avatar_url": "https://avatars.githubusercontent.com/u/54469796?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/supabase", + "html_url": "https://github.com/supabase", + "followers_url": "https://api.github.com/users/supabase/followers", + "following_url": "https://api.github.com/users/supabase/following{/other_user}", + "gists_url": "https://api.github.com/users/supabase/gists{/gist_id}", + "starred_url": "https://api.github.com/users/supabase/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/supabase/subscriptions", + "organizations_url": "https://api.github.com/users/supabase/orgs", + "repos_url": "https://api.github.com/users/supabase/repos", + "events_url": "https://api.github.com/users/supabase/events{/privacy}", + "received_events_url": "https://api.github.com/users/supabase/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/supabase/cli", + "description": "Developer tools and helpers.", + "fork": false, + "url": "https://api.github.com/repos/supabase/cli", + "forks_url": "https://api.github.com/repos/supabase/cli/forks", + "keys_url": "https://api.github.com/repos/supabase/cli/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/supabase/cli/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/supabase/cli/teams", + "hooks_url": "https://api.github.com/repos/supabase/cli/hooks", + "issue_events_url": "https://api.github.com/repos/supabase/cli/issues/events{/number}", + "events_url": "https://api.github.com/repos/supabase/cli/events", + "assignees_url": "https://api.github.com/repos/supabase/cli/assignees{/user}", + "branches_url": "https://api.github.com/repos/supabase/cli/branches{/branch}", + "tags_url": "https://api.github.com/repos/supabase/cli/tags", + "blobs_url": "https://api.github.com/repos/supabase/cli/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/supabase/cli/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/supabase/cli/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/supabase/cli/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/supabase/cli/statuses/{sha}", + "languages_url": "https://api.github.com/repos/supabase/cli/languages", + "stargazers_url": "https://api.github.com/repos/supabase/cli/stargazers", + "contributors_url": "https://api.github.com/repos/supabase/cli/contributors", + "subscribers_url": "https://api.github.com/repos/supabase/cli/subscribers", + "subscription_url": "https://api.github.com/repos/supabase/cli/subscription", + "commits_url": "https://api.github.com/repos/supabase/cli/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/supabase/cli/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/supabase/cli/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/supabase/cli/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/supabase/cli/contents/{+path}", + "compare_url": "https://api.github.com/repos/supabase/cli/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/supabase/cli/merges", + "archive_url": "https://api.github.com/repos/supabase/cli/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/supabase/cli/downloads", + "issues_url": "https://api.github.com/repos/supabase/cli/issues{/number}", + "pulls_url": "https://api.github.com/repos/supabase/cli/pulls{/number}", + "milestones_url": "https://api.github.com/repos/supabase/cli/milestones{/number}", + "notifications_url": "https://api.github.com/repos/supabase/cli/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/supabase/cli/labels{/name}", + "releases_url": "https://api.github.com/repos/supabase/cli/releases{/id}", + "deployments_url": "https://api.github.com/repos/supabase/cli/deployments", + "created_at": "2020-11-19T06:46:55Z", + "updated_at": "2021-02-14T08:01:54Z", + "pushed_at": "2021-02-14T08:04:07Z", + "git_url": "git://github.com/supabase/cli.git", + "ssh_url": "git@github.com:supabase/cli.git", + "clone_url": "https://github.com/supabase/cli.git", + "svn_url": "https://github.com/supabase/cli", + "homepage": "https://supabase.com", + "size": 131, + "stargazers_count": 7, + "watchers_count": 7, + "language": "TypeScript", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "forks_count": 1, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 2, + "license": { + "key": "mit", + "name": "MIT License", + "spdx_id": "MIT", + "url": "https://api.github.com/licenses/mit", + "node_id": "MDc6TGljZW5zZTEz" + }, + "forks": 1, + "open_issues": 2, + "watchers": 7, + "default_branch": "main", + "temp_clone_token": null, + "organization": { + "login": "supabase", + "id": 54469796, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0NDY5Nzk2", + "avatar_url": "https://avatars.githubusercontent.com/u/54469796?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/supabase", + "html_url": "https://github.com/supabase", + "followers_url": "https://api.github.com/users/supabase/followers", + "following_url": "https://api.github.com/users/supabase/following{/other_user}", + "gists_url": "https://api.github.com/users/supabase/gists{/gist_id}", + "starred_url": "https://api.github.com/users/supabase/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/supabase/subscriptions", + "organizations_url": "https://api.github.com/users/supabase/orgs", + "repos_url": "https://api.github.com/users/supabase/repos", + "events_url": "https://api.github.com/users/supabase/events{/privacy}", + "received_events_url": "https://api.github.com/users/supabase/received_events", + "type": "Organization", + "site_admin": false + }, + "network_count": 1, + "subscribers_count": 3 +} diff --git a/apps/temp-docs/data/repos/doctest-js.json b/apps/temp-docs/data/repos/doctest-js.json new file mode 100644 index 00000000000..4c46b992162 --- /dev/null +++ b/apps/temp-docs/data/repos/doctest-js.json @@ -0,0 +1,123 @@ +{ + "id": 236905403, + "node_id": "MDEwOlJlcG9zaXRvcnkyMzY5MDU0MDM=", + "name": "doctest-js", + "full_name": "supabase/doctest-js", + "private": false, + "owner": { + "login": "supabase", + "id": 54469796, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0NDY5Nzk2", + "avatar_url": "https://avatars.githubusercontent.com/u/54469796?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/supabase", + "html_url": "https://github.com/supabase", + "followers_url": "https://api.github.com/users/supabase/followers", + "following_url": "https://api.github.com/users/supabase/following{/other_user}", + "gists_url": "https://api.github.com/users/supabase/gists{/gist_id}", + "starred_url": "https://api.github.com/users/supabase/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/supabase/subscriptions", + "organizations_url": "https://api.github.com/users/supabase/orgs", + "repos_url": "https://api.github.com/users/supabase/repos", + "events_url": "https://api.github.com/users/supabase/events{/privacy}", + "received_events_url": "https://api.github.com/users/supabase/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/supabase/doctest-js", + "description": "Run JSDoc style doc examples as tests within your test suite", + "fork": false, + "url": "https://api.github.com/repos/supabase/doctest-js", + "forks_url": "https://api.github.com/repos/supabase/doctest-js/forks", + "keys_url": "https://api.github.com/repos/supabase/doctest-js/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/supabase/doctest-js/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/supabase/doctest-js/teams", + "hooks_url": "https://api.github.com/repos/supabase/doctest-js/hooks", + "issue_events_url": "https://api.github.com/repos/supabase/doctest-js/issues/events{/number}", + "events_url": "https://api.github.com/repos/supabase/doctest-js/events", + "assignees_url": "https://api.github.com/repos/supabase/doctest-js/assignees{/user}", + "branches_url": "https://api.github.com/repos/supabase/doctest-js/branches{/branch}", + "tags_url": "https://api.github.com/repos/supabase/doctest-js/tags", + "blobs_url": "https://api.github.com/repos/supabase/doctest-js/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/supabase/doctest-js/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/supabase/doctest-js/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/supabase/doctest-js/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/supabase/doctest-js/statuses/{sha}", + "languages_url": "https://api.github.com/repos/supabase/doctest-js/languages", + "stargazers_url": "https://api.github.com/repos/supabase/doctest-js/stargazers", + "contributors_url": "https://api.github.com/repos/supabase/doctest-js/contributors", + "subscribers_url": "https://api.github.com/repos/supabase/doctest-js/subscribers", + "subscription_url": "https://api.github.com/repos/supabase/doctest-js/subscription", + "commits_url": "https://api.github.com/repos/supabase/doctest-js/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/supabase/doctest-js/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/supabase/doctest-js/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/supabase/doctest-js/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/supabase/doctest-js/contents/{+path}", + "compare_url": "https://api.github.com/repos/supabase/doctest-js/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/supabase/doctest-js/merges", + "archive_url": "https://api.github.com/repos/supabase/doctest-js/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/supabase/doctest-js/downloads", + "issues_url": "https://api.github.com/repos/supabase/doctest-js/issues{/number}", + "pulls_url": "https://api.github.com/repos/supabase/doctest-js/pulls{/number}", + "milestones_url": "https://api.github.com/repos/supabase/doctest-js/milestones{/number}", + "notifications_url": "https://api.github.com/repos/supabase/doctest-js/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/supabase/doctest-js/labels{/name}", + "releases_url": "https://api.github.com/repos/supabase/doctest-js/releases{/id}", + "deployments_url": "https://api.github.com/repos/supabase/doctest-js/deployments", + "created_at": "2020-01-29T04:51:25Z", + "updated_at": "2021-02-14T08:46:07Z", + "pushed_at": "2020-12-22T16:32:15Z", + "git_url": "git://github.com/supabase/doctest-js.git", + "ssh_url": "git@github.com:supabase/doctest-js.git", + "clone_url": "https://github.com/supabase/doctest-js.git", + "svn_url": "https://github.com/supabase/doctest-js", + "homepage": "", + "size": 1623, + "stargazers_count": 52, + "watchers_count": 52, + "language": "JavaScript", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": false, + "has_pages": false, + "forks_count": 2, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 2, + "license": { + "key": "mit", + "name": "MIT License", + "spdx_id": "MIT", + "url": "https://api.github.com/licenses/mit", + "node_id": "MDc6TGljZW5zZTEz" + }, + "forks": 2, + "open_issues": 2, + "watchers": 52, + "default_branch": "master", + "temp_clone_token": null, + "organization": { + "login": "supabase", + "id": 54469796, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0NDY5Nzk2", + "avatar_url": "https://avatars.githubusercontent.com/u/54469796?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/supabase", + "html_url": "https://github.com/supabase", + "followers_url": "https://api.github.com/users/supabase/followers", + "following_url": "https://api.github.com/users/supabase/following{/other_user}", + "gists_url": "https://api.github.com/users/supabase/gists{/gist_id}", + "starred_url": "https://api.github.com/users/supabase/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/supabase/subscriptions", + "organizations_url": "https://api.github.com/users/supabase/orgs", + "repos_url": "https://api.github.com/users/supabase/repos", + "events_url": "https://api.github.com/users/supabase/events{/privacy}", + "received_events_url": "https://api.github.com/users/supabase/received_events", + "type": "Organization", + "site_admin": false + }, + "network_count": 2, + "subscribers_count": 3 +} diff --git a/apps/temp-docs/data/repos/gotrue-csharp.json b/apps/temp-docs/data/repos/gotrue-csharp.json new file mode 100644 index 00000000000..d11fcbaea83 --- /dev/null +++ b/apps/temp-docs/data/repos/gotrue-csharp.json @@ -0,0 +1,123 @@ +{ + "id": 334638542, + "node_id": "MDEwOlJlcG9zaXRvcnkzMzQ2Mzg1NDI=", + "name": "gotrue-csharp", + "full_name": "supabase/gotrue-csharp", + "private": false, + "owner": { + "login": "supabase", + "id": 54469796, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0NDY5Nzk2", + "avatar_url": "https://avatars.githubusercontent.com/u/54469796?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/supabase", + "html_url": "https://github.com/supabase", + "followers_url": "https://api.github.com/users/supabase/followers", + "following_url": "https://api.github.com/users/supabase/following{/other_user}", + "gists_url": "https://api.github.com/users/supabase/gists{/gist_id}", + "starred_url": "https://api.github.com/users/supabase/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/supabase/subscriptions", + "organizations_url": "https://api.github.com/users/supabase/orgs", + "repos_url": "https://api.github.com/users/supabase/repos", + "events_url": "https://api.github.com/users/supabase/events{/privacy}", + "received_events_url": "https://api.github.com/users/supabase/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/supabase/gotrue-csharp", + "description": "A C# interface for gotrue", + "fork": false, + "url": "https://api.github.com/repos/supabase/gotrue-csharp", + "forks_url": "https://api.github.com/repos/supabase/gotrue-csharp/forks", + "keys_url": "https://api.github.com/repos/supabase/gotrue-csharp/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/supabase/gotrue-csharp/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/supabase/gotrue-csharp/teams", + "hooks_url": "https://api.github.com/repos/supabase/gotrue-csharp/hooks", + "issue_events_url": "https://api.github.com/repos/supabase/gotrue-csharp/issues/events{/number}", + "events_url": "https://api.github.com/repos/supabase/gotrue-csharp/events", + "assignees_url": "https://api.github.com/repos/supabase/gotrue-csharp/assignees{/user}", + "branches_url": "https://api.github.com/repos/supabase/gotrue-csharp/branches{/branch}", + "tags_url": "https://api.github.com/repos/supabase/gotrue-csharp/tags", + "blobs_url": "https://api.github.com/repos/supabase/gotrue-csharp/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/supabase/gotrue-csharp/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/supabase/gotrue-csharp/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/supabase/gotrue-csharp/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/supabase/gotrue-csharp/statuses/{sha}", + "languages_url": "https://api.github.com/repos/supabase/gotrue-csharp/languages", + "stargazers_url": "https://api.github.com/repos/supabase/gotrue-csharp/stargazers", + "contributors_url": "https://api.github.com/repos/supabase/gotrue-csharp/contributors", + "subscribers_url": "https://api.github.com/repos/supabase/gotrue-csharp/subscribers", + "subscription_url": "https://api.github.com/repos/supabase/gotrue-csharp/subscription", + "commits_url": "https://api.github.com/repos/supabase/gotrue-csharp/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/supabase/gotrue-csharp/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/supabase/gotrue-csharp/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/supabase/gotrue-csharp/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/supabase/gotrue-csharp/contents/{+path}", + "compare_url": "https://api.github.com/repos/supabase/gotrue-csharp/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/supabase/gotrue-csharp/merges", + "archive_url": "https://api.github.com/repos/supabase/gotrue-csharp/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/supabase/gotrue-csharp/downloads", + "issues_url": "https://api.github.com/repos/supabase/gotrue-csharp/issues{/number}", + "pulls_url": "https://api.github.com/repos/supabase/gotrue-csharp/pulls{/number}", + "milestones_url": "https://api.github.com/repos/supabase/gotrue-csharp/milestones{/number}", + "notifications_url": "https://api.github.com/repos/supabase/gotrue-csharp/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/supabase/gotrue-csharp/labels{/name}", + "releases_url": "https://api.github.com/repos/supabase/gotrue-csharp/releases{/id}", + "deployments_url": "https://api.github.com/repos/supabase/gotrue-csharp/deployments", + "created_at": "2021-01-31T11:27:09Z", + "updated_at": "2021-02-15T12:53:37Z", + "pushed_at": "2021-02-15T12:54:48Z", + "git_url": "git://github.com/supabase/gotrue-csharp.git", + "ssh_url": "git@github.com:supabase/gotrue-csharp.git", + "clone_url": "https://github.com/supabase/gotrue-csharp.git", + "svn_url": "https://github.com/supabase/gotrue-csharp", + "homepage": "https://supabase.github.io/gotrue-csharp/api/Supabase.Gotrue.Client.html", + "size": 610, + "stargazers_count": 1, + "watchers_count": 1, + "language": "C#", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 1, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 0, + "license": { + "key": "mit", + "name": "MIT License", + "spdx_id": "MIT", + "url": "https://api.github.com/licenses/mit", + "node_id": "MDc6TGljZW5zZTEz" + }, + "forks": 1, + "open_issues": 0, + "watchers": 1, + "default_branch": "master", + "temp_clone_token": null, + "organization": { + "login": "supabase", + "id": 54469796, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0NDY5Nzk2", + "avatar_url": "https://avatars.githubusercontent.com/u/54469796?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/supabase", + "html_url": "https://github.com/supabase", + "followers_url": "https://api.github.com/users/supabase/followers", + "following_url": "https://api.github.com/users/supabase/following{/other_user}", + "gists_url": "https://api.github.com/users/supabase/gists{/gist_id}", + "starred_url": "https://api.github.com/users/supabase/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/supabase/subscriptions", + "organizations_url": "https://api.github.com/users/supabase/orgs", + "repos_url": "https://api.github.com/users/supabase/repos", + "events_url": "https://api.github.com/users/supabase/events{/privacy}", + "received_events_url": "https://api.github.com/users/supabase/received_events", + "type": "Organization", + "site_admin": false + }, + "network_count": 1, + "subscribers_count": 3 +} diff --git a/apps/temp-docs/data/repos/gotrue.json b/apps/temp-docs/data/repos/gotrue.json new file mode 100644 index 00000000000..97f613b6a29 --- /dev/null +++ b/apps/temp-docs/data/repos/gotrue.json @@ -0,0 +1,323 @@ +{ + "id": 279488921, + "node_id": "MDEwOlJlcG9zaXRvcnkyNzk0ODg5MjE=", + "name": "gotrue", + "full_name": "supabase/gotrue", + "private": false, + "owner": { + "login": "supabase", + "id": 54469796, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0NDY5Nzk2", + "avatar_url": "https://avatars.githubusercontent.com/u/54469796?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/supabase", + "html_url": "https://github.com/supabase", + "followers_url": "https://api.github.com/users/supabase/followers", + "following_url": "https://api.github.com/users/supabase/following{/other_user}", + "gists_url": "https://api.github.com/users/supabase/gists{/gist_id}", + "starred_url": "https://api.github.com/users/supabase/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/supabase/subscriptions", + "organizations_url": "https://api.github.com/users/supabase/orgs", + "repos_url": "https://api.github.com/users/supabase/repos", + "events_url": "https://api.github.com/users/supabase/events{/privacy}", + "received_events_url": "https://api.github.com/users/supabase/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/supabase/gotrue", + "description": "A JWT based API for managing users and issuing JWT tokens", + "fork": true, + "url": "https://api.github.com/repos/supabase/gotrue", + "forks_url": "https://api.github.com/repos/supabase/gotrue/forks", + "keys_url": "https://api.github.com/repos/supabase/gotrue/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/supabase/gotrue/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/supabase/gotrue/teams", + "hooks_url": "https://api.github.com/repos/supabase/gotrue/hooks", + "issue_events_url": "https://api.github.com/repos/supabase/gotrue/issues/events{/number}", + "events_url": "https://api.github.com/repos/supabase/gotrue/events", + "assignees_url": "https://api.github.com/repos/supabase/gotrue/assignees{/user}", + "branches_url": "https://api.github.com/repos/supabase/gotrue/branches{/branch}", + "tags_url": "https://api.github.com/repos/supabase/gotrue/tags", + "blobs_url": "https://api.github.com/repos/supabase/gotrue/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/supabase/gotrue/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/supabase/gotrue/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/supabase/gotrue/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/supabase/gotrue/statuses/{sha}", + "languages_url": "https://api.github.com/repos/supabase/gotrue/languages", + "stargazers_url": "https://api.github.com/repos/supabase/gotrue/stargazers", + "contributors_url": "https://api.github.com/repos/supabase/gotrue/contributors", + "subscribers_url": "https://api.github.com/repos/supabase/gotrue/subscribers", + "subscription_url": "https://api.github.com/repos/supabase/gotrue/subscription", + "commits_url": "https://api.github.com/repos/supabase/gotrue/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/supabase/gotrue/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/supabase/gotrue/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/supabase/gotrue/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/supabase/gotrue/contents/{+path}", + "compare_url": "https://api.github.com/repos/supabase/gotrue/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/supabase/gotrue/merges", + "archive_url": "https://api.github.com/repos/supabase/gotrue/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/supabase/gotrue/downloads", + "issues_url": "https://api.github.com/repos/supabase/gotrue/issues{/number}", + "pulls_url": "https://api.github.com/repos/supabase/gotrue/pulls{/number}", + "milestones_url": "https://api.github.com/repos/supabase/gotrue/milestones{/number}", + "notifications_url": "https://api.github.com/repos/supabase/gotrue/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/supabase/gotrue/labels{/name}", + "releases_url": "https://api.github.com/repos/supabase/gotrue/releases{/id}", + "deployments_url": "https://api.github.com/repos/supabase/gotrue/deployments", + "created_at": "2020-07-14T05:14:31Z", + "updated_at": "2021-02-15T06:58:06Z", + "pushed_at": "2021-02-16T03:37:05Z", + "git_url": "git://github.com/supabase/gotrue.git", + "ssh_url": "git@github.com:supabase/gotrue.git", + "clone_url": "https://github.com/supabase/gotrue.git", + "svn_url": "https://github.com/supabase/gotrue", + "homepage": "https://supabase.com/docs/guides/auth", + "size": 7183, + "stargazers_count": 9, + "watchers_count": 9, + "language": "Go", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "forks_count": 7, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 17, + "license": { + "key": "mit", + "name": "MIT License", + "spdx_id": "MIT", + "url": "https://api.github.com/licenses/mit", + "node_id": "MDc6TGljZW5zZTEz" + }, + "forks": 7, + "open_issues": 17, + "watchers": 9, + "default_branch": "master", + "temp_clone_token": null, + "organization": { + "login": "supabase", + "id": 54469796, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0NDY5Nzk2", + "avatar_url": "https://avatars.githubusercontent.com/u/54469796?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/supabase", + "html_url": "https://github.com/supabase", + "followers_url": "https://api.github.com/users/supabase/followers", + "following_url": "https://api.github.com/users/supabase/following{/other_user}", + "gists_url": "https://api.github.com/users/supabase/gists{/gist_id}", + "starred_url": "https://api.github.com/users/supabase/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/supabase/subscriptions", + "organizations_url": "https://api.github.com/users/supabase/orgs", + "repos_url": "https://api.github.com/users/supabase/repos", + "events_url": "https://api.github.com/users/supabase/events{/privacy}", + "received_events_url": "https://api.github.com/users/supabase/received_events", + "type": "Organization", + "site_admin": false + }, + "parent": { + "id": 58974323, + "node_id": "MDEwOlJlcG9zaXRvcnk1ODk3NDMyMw==", + "name": "gotrue", + "full_name": "netlify/gotrue", + "private": false, + "owner": { + "login": "netlify", + "id": 7892489, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjc4OTI0ODk=", + "avatar_url": "https://avatars.githubusercontent.com/u/7892489?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/netlify", + "html_url": "https://github.com/netlify", + "followers_url": "https://api.github.com/users/netlify/followers", + "following_url": "https://api.github.com/users/netlify/following{/other_user}", + "gists_url": "https://api.github.com/users/netlify/gists{/gist_id}", + "starred_url": "https://api.github.com/users/netlify/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/netlify/subscriptions", + "organizations_url": "https://api.github.com/users/netlify/orgs", + "repos_url": "https://api.github.com/users/netlify/repos", + "events_url": "https://api.github.com/users/netlify/events{/privacy}", + "received_events_url": "https://api.github.com/users/netlify/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/netlify/gotrue", + "description": "An SWT based API for managing users and issuing SWT tokens", + "fork": false, + "url": "https://api.github.com/repos/netlify/gotrue", + "forks_url": "https://api.github.com/repos/netlify/gotrue/forks", + "keys_url": "https://api.github.com/repos/netlify/gotrue/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/netlify/gotrue/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/netlify/gotrue/teams", + "hooks_url": "https://api.github.com/repos/netlify/gotrue/hooks", + "issue_events_url": "https://api.github.com/repos/netlify/gotrue/issues/events{/number}", + "events_url": "https://api.github.com/repos/netlify/gotrue/events", + "assignees_url": "https://api.github.com/repos/netlify/gotrue/assignees{/user}", + "branches_url": "https://api.github.com/repos/netlify/gotrue/branches{/branch}", + "tags_url": "https://api.github.com/repos/netlify/gotrue/tags", + "blobs_url": "https://api.github.com/repos/netlify/gotrue/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/netlify/gotrue/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/netlify/gotrue/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/netlify/gotrue/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/netlify/gotrue/statuses/{sha}", + "languages_url": "https://api.github.com/repos/netlify/gotrue/languages", + "stargazers_url": "https://api.github.com/repos/netlify/gotrue/stargazers", + "contributors_url": "https://api.github.com/repos/netlify/gotrue/contributors", + "subscribers_url": "https://api.github.com/repos/netlify/gotrue/subscribers", + "subscription_url": "https://api.github.com/repos/netlify/gotrue/subscription", + "commits_url": "https://api.github.com/repos/netlify/gotrue/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/netlify/gotrue/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/netlify/gotrue/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/netlify/gotrue/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/netlify/gotrue/contents/{+path}", + "compare_url": "https://api.github.com/repos/netlify/gotrue/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/netlify/gotrue/merges", + "archive_url": "https://api.github.com/repos/netlify/gotrue/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/netlify/gotrue/downloads", + "issues_url": "https://api.github.com/repos/netlify/gotrue/issues{/number}", + "pulls_url": "https://api.github.com/repos/netlify/gotrue/pulls{/number}", + "milestones_url": "https://api.github.com/repos/netlify/gotrue/milestones{/number}", + "notifications_url": "https://api.github.com/repos/netlify/gotrue/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/netlify/gotrue/labels{/name}", + "releases_url": "https://api.github.com/repos/netlify/gotrue/releases{/id}", + "deployments_url": "https://api.github.com/repos/netlify/gotrue/deployments", + "created_at": "2016-05-16T23:14:24Z", + "updated_at": "2021-02-15T06:07:23Z", + "pushed_at": "2020-12-19T07:50:47Z", + "git_url": "git://github.com/netlify/gotrue.git", + "ssh_url": "git@github.com:netlify/gotrue.git", + "clone_url": "https://github.com/netlify/gotrue.git", + "svn_url": "https://github.com/netlify/gotrue", + "homepage": "https://www.gotrueapi.org", + "size": 6937, + "stargazers_count": 1643, + "watchers_count": 1643, + "language": "Go", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "forks_count": 155, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 54, + "license": { + "key": "mit", + "name": "MIT License", + "spdx_id": "MIT", + "url": "https://api.github.com/licenses/mit", + "node_id": "MDc6TGljZW5zZTEz" + }, + "forks": 155, + "open_issues": 54, + "watchers": 1643, + "default_branch": "master" + }, + "source": { + "id": 58974323, + "node_id": "MDEwOlJlcG9zaXRvcnk1ODk3NDMyMw==", + "name": "gotrue", + "full_name": "netlify/gotrue", + "private": false, + "owner": { + "login": "netlify", + "id": 7892489, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjc4OTI0ODk=", + "avatar_url": "https://avatars.githubusercontent.com/u/7892489?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/netlify", + "html_url": "https://github.com/netlify", + "followers_url": "https://api.github.com/users/netlify/followers", + "following_url": "https://api.github.com/users/netlify/following{/other_user}", + "gists_url": "https://api.github.com/users/netlify/gists{/gist_id}", + "starred_url": "https://api.github.com/users/netlify/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/netlify/subscriptions", + "organizations_url": "https://api.github.com/users/netlify/orgs", + "repos_url": "https://api.github.com/users/netlify/repos", + "events_url": "https://api.github.com/users/netlify/events{/privacy}", + "received_events_url": "https://api.github.com/users/netlify/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/netlify/gotrue", + "description": "An SWT based API for managing users and issuing SWT tokens", + "fork": false, + "url": "https://api.github.com/repos/netlify/gotrue", + "forks_url": "https://api.github.com/repos/netlify/gotrue/forks", + "keys_url": "https://api.github.com/repos/netlify/gotrue/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/netlify/gotrue/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/netlify/gotrue/teams", + "hooks_url": "https://api.github.com/repos/netlify/gotrue/hooks", + "issue_events_url": "https://api.github.com/repos/netlify/gotrue/issues/events{/number}", + "events_url": "https://api.github.com/repos/netlify/gotrue/events", + "assignees_url": "https://api.github.com/repos/netlify/gotrue/assignees{/user}", + "branches_url": "https://api.github.com/repos/netlify/gotrue/branches{/branch}", + "tags_url": "https://api.github.com/repos/netlify/gotrue/tags", + "blobs_url": "https://api.github.com/repos/netlify/gotrue/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/netlify/gotrue/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/netlify/gotrue/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/netlify/gotrue/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/netlify/gotrue/statuses/{sha}", + "languages_url": "https://api.github.com/repos/netlify/gotrue/languages", + "stargazers_url": "https://api.github.com/repos/netlify/gotrue/stargazers", + "contributors_url": "https://api.github.com/repos/netlify/gotrue/contributors", + "subscribers_url": "https://api.github.com/repos/netlify/gotrue/subscribers", + "subscription_url": "https://api.github.com/repos/netlify/gotrue/subscription", + "commits_url": "https://api.github.com/repos/netlify/gotrue/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/netlify/gotrue/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/netlify/gotrue/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/netlify/gotrue/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/netlify/gotrue/contents/{+path}", + "compare_url": "https://api.github.com/repos/netlify/gotrue/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/netlify/gotrue/merges", + "archive_url": "https://api.github.com/repos/netlify/gotrue/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/netlify/gotrue/downloads", + "issues_url": "https://api.github.com/repos/netlify/gotrue/issues{/number}", + "pulls_url": "https://api.github.com/repos/netlify/gotrue/pulls{/number}", + "milestones_url": "https://api.github.com/repos/netlify/gotrue/milestones{/number}", + "notifications_url": "https://api.github.com/repos/netlify/gotrue/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/netlify/gotrue/labels{/name}", + "releases_url": "https://api.github.com/repos/netlify/gotrue/releases{/id}", + "deployments_url": "https://api.github.com/repos/netlify/gotrue/deployments", + "created_at": "2016-05-16T23:14:24Z", + "updated_at": "2021-02-15T06:07:23Z", + "pushed_at": "2020-12-19T07:50:47Z", + "git_url": "git://github.com/netlify/gotrue.git", + "ssh_url": "git@github.com:netlify/gotrue.git", + "clone_url": "https://github.com/netlify/gotrue.git", + "svn_url": "https://github.com/netlify/gotrue", + "homepage": "https://www.gotrueapi.org", + "size": 6937, + "stargazers_count": 1643, + "watchers_count": 1643, + "language": "Go", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "forks_count": 155, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 54, + "license": { + "key": "mit", + "name": "MIT License", + "spdx_id": "MIT", + "url": "https://api.github.com/licenses/mit", + "node_id": "MDc6TGljZW5zZTEz" + }, + "forks": 155, + "open_issues": 54, + "watchers": 1643, + "default_branch": "master" + }, + "network_count": 155, + "subscribers_count": 1 +} diff --git a/apps/temp-docs/data/repos/jsdoc-template.json b/apps/temp-docs/data/repos/jsdoc-template.json new file mode 100644 index 00000000000..3b129f41f3e --- /dev/null +++ b/apps/temp-docs/data/repos/jsdoc-template.json @@ -0,0 +1,323 @@ +{ + "id": 236916940, + "node_id": "MDEwOlJlcG9zaXRvcnkyMzY5MTY5NDA=", + "name": "jsdoc-template", + "full_name": "supabase/jsdoc-template", + "private": false, + "owner": { + "login": "supabase", + "id": 54469796, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0NDY5Nzk2", + "avatar_url": "https://avatars3.githubusercontent.com/u/54469796?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/supabase", + "html_url": "https://github.com/supabase", + "followers_url": "https://api.github.com/users/supabase/followers", + "following_url": "https://api.github.com/users/supabase/following{/other_user}", + "gists_url": "https://api.github.com/users/supabase/gists{/gist_id}", + "starred_url": "https://api.github.com/users/supabase/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/supabase/subscriptions", + "organizations_url": "https://api.github.com/users/supabase/orgs", + "repos_url": "https://api.github.com/users/supabase/repos", + "events_url": "https://api.github.com/users/supabase/events{/privacy}", + "received_events_url": "https://api.github.com/users/supabase/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/supabase/jsdoc-template", + "description": "A clean, responsive documentation template with search and navigation highlighting for JSDoc 3", + "fork": true, + "url": "https://api.github.com/repos/supabase/jsdoc-template", + "forks_url": "https://api.github.com/repos/supabase/jsdoc-template/forks", + "keys_url": "https://api.github.com/repos/supabase/jsdoc-template/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/supabase/jsdoc-template/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/supabase/jsdoc-template/teams", + "hooks_url": "https://api.github.com/repos/supabase/jsdoc-template/hooks", + "issue_events_url": "https://api.github.com/repos/supabase/jsdoc-template/issues/events{/number}", + "events_url": "https://api.github.com/repos/supabase/jsdoc-template/events", + "assignees_url": "https://api.github.com/repos/supabase/jsdoc-template/assignees{/user}", + "branches_url": "https://api.github.com/repos/supabase/jsdoc-template/branches{/branch}", + "tags_url": "https://api.github.com/repos/supabase/jsdoc-template/tags", + "blobs_url": "https://api.github.com/repos/supabase/jsdoc-template/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/supabase/jsdoc-template/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/supabase/jsdoc-template/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/supabase/jsdoc-template/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/supabase/jsdoc-template/statuses/{sha}", + "languages_url": "https://api.github.com/repos/supabase/jsdoc-template/languages", + "stargazers_url": "https://api.github.com/repos/supabase/jsdoc-template/stargazers", + "contributors_url": "https://api.github.com/repos/supabase/jsdoc-template/contributors", + "subscribers_url": "https://api.github.com/repos/supabase/jsdoc-template/subscribers", + "subscription_url": "https://api.github.com/repos/supabase/jsdoc-template/subscription", + "commits_url": "https://api.github.com/repos/supabase/jsdoc-template/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/supabase/jsdoc-template/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/supabase/jsdoc-template/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/supabase/jsdoc-template/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/supabase/jsdoc-template/contents/{+path}", + "compare_url": "https://api.github.com/repos/supabase/jsdoc-template/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/supabase/jsdoc-template/merges", + "archive_url": "https://api.github.com/repos/supabase/jsdoc-template/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/supabase/jsdoc-template/downloads", + "issues_url": "https://api.github.com/repos/supabase/jsdoc-template/issues{/number}", + "pulls_url": "https://api.github.com/repos/supabase/jsdoc-template/pulls{/number}", + "milestones_url": "https://api.github.com/repos/supabase/jsdoc-template/milestones{/number}", + "notifications_url": "https://api.github.com/repos/supabase/jsdoc-template/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/supabase/jsdoc-template/labels{/name}", + "releases_url": "https://api.github.com/repos/supabase/jsdoc-template/releases{/id}", + "deployments_url": "https://api.github.com/repos/supabase/jsdoc-template/deployments", + "created_at": "2020-01-29T06:16:50Z", + "updated_at": "2020-04-22T04:24:52Z", + "pushed_at": "2020-06-12T07:35:55Z", + "git_url": "git://github.com/supabase/jsdoc-template.git", + "ssh_url": "git@github.com:supabase/jsdoc-template.git", + "clone_url": "https://github.com/supabase/jsdoc-template.git", + "svn_url": "https://github.com/supabase/jsdoc-template", + "homepage": "", + "size": 654, + "stargazers_count": 2, + "watchers_count": 2, + "language": "CSS", + "has_issues": false, + "has_projects": true, + "has_downloads": true, + "has_wiki": false, + "has_pages": false, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 2, + "license": { + "key": "other", + "name": "Other", + "spdx_id": "NOASSERTION", + "url": null, + "node_id": "MDc6TGljZW5zZTA=" + }, + "forks": 0, + "open_issues": 2, + "watchers": 2, + "default_branch": "master", + "temp_clone_token": null, + "organization": { + "login": "supabase", + "id": 54469796, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0NDY5Nzk2", + "avatar_url": "https://avatars3.githubusercontent.com/u/54469796?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/supabase", + "html_url": "https://github.com/supabase", + "followers_url": "https://api.github.com/users/supabase/followers", + "following_url": "https://api.github.com/users/supabase/following{/other_user}", + "gists_url": "https://api.github.com/users/supabase/gists{/gist_id}", + "starred_url": "https://api.github.com/users/supabase/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/supabase/subscriptions", + "organizations_url": "https://api.github.com/users/supabase/orgs", + "repos_url": "https://api.github.com/users/supabase/repos", + "events_url": "https://api.github.com/users/supabase/events{/privacy}", + "received_events_url": "https://api.github.com/users/supabase/received_events", + "type": "Organization", + "site_admin": false + }, + "parent": { + "id": 59770336, + "node_id": "MDEwOlJlcG9zaXRvcnk1OTc3MDMzNg==", + "name": "jsdoc-template", + "full_name": "braintree/jsdoc-template", + "private": false, + "owner": { + "login": "braintree", + "id": 3453, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjM0NTM=", + "avatar_url": "https://avatars2.githubusercontent.com/u/3453?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/braintree", + "html_url": "https://github.com/braintree", + "followers_url": "https://api.github.com/users/braintree/followers", + "following_url": "https://api.github.com/users/braintree/following{/other_user}", + "gists_url": "https://api.github.com/users/braintree/gists{/gist_id}", + "starred_url": "https://api.github.com/users/braintree/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/braintree/subscriptions", + "organizations_url": "https://api.github.com/users/braintree/orgs", + "repos_url": "https://api.github.com/users/braintree/repos", + "events_url": "https://api.github.com/users/braintree/events{/privacy}", + "received_events_url": "https://api.github.com/users/braintree/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/braintree/jsdoc-template", + "description": "A clean, responsive documentation template with search and navigation highlighting for JSDoc 3", + "fork": false, + "url": "https://api.github.com/repos/braintree/jsdoc-template", + "forks_url": "https://api.github.com/repos/braintree/jsdoc-template/forks", + "keys_url": "https://api.github.com/repos/braintree/jsdoc-template/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/braintree/jsdoc-template/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/braintree/jsdoc-template/teams", + "hooks_url": "https://api.github.com/repos/braintree/jsdoc-template/hooks", + "issue_events_url": "https://api.github.com/repos/braintree/jsdoc-template/issues/events{/number}", + "events_url": "https://api.github.com/repos/braintree/jsdoc-template/events", + "assignees_url": "https://api.github.com/repos/braintree/jsdoc-template/assignees{/user}", + "branches_url": "https://api.github.com/repos/braintree/jsdoc-template/branches{/branch}", + "tags_url": "https://api.github.com/repos/braintree/jsdoc-template/tags", + "blobs_url": "https://api.github.com/repos/braintree/jsdoc-template/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/braintree/jsdoc-template/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/braintree/jsdoc-template/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/braintree/jsdoc-template/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/braintree/jsdoc-template/statuses/{sha}", + "languages_url": "https://api.github.com/repos/braintree/jsdoc-template/languages", + "stargazers_url": "https://api.github.com/repos/braintree/jsdoc-template/stargazers", + "contributors_url": "https://api.github.com/repos/braintree/jsdoc-template/contributors", + "subscribers_url": "https://api.github.com/repos/braintree/jsdoc-template/subscribers", + "subscription_url": "https://api.github.com/repos/braintree/jsdoc-template/subscription", + "commits_url": "https://api.github.com/repos/braintree/jsdoc-template/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/braintree/jsdoc-template/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/braintree/jsdoc-template/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/braintree/jsdoc-template/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/braintree/jsdoc-template/contents/{+path}", + "compare_url": "https://api.github.com/repos/braintree/jsdoc-template/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/braintree/jsdoc-template/merges", + "archive_url": "https://api.github.com/repos/braintree/jsdoc-template/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/braintree/jsdoc-template/downloads", + "issues_url": "https://api.github.com/repos/braintree/jsdoc-template/issues{/number}", + "pulls_url": "https://api.github.com/repos/braintree/jsdoc-template/pulls{/number}", + "milestones_url": "https://api.github.com/repos/braintree/jsdoc-template/milestones{/number}", + "notifications_url": "https://api.github.com/repos/braintree/jsdoc-template/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/braintree/jsdoc-template/labels{/name}", + "releases_url": "https://api.github.com/repos/braintree/jsdoc-template/releases{/id}", + "deployments_url": "https://api.github.com/repos/braintree/jsdoc-template/deployments", + "created_at": "2016-05-26T17:37:00Z", + "updated_at": "2020-06-23T01:52:09Z", + "pushed_at": "2020-03-24T18:02:57Z", + "git_url": "git://github.com/braintree/jsdoc-template.git", + "ssh_url": "git@github.com:braintree/jsdoc-template.git", + "clone_url": "https://github.com/braintree/jsdoc-template.git", + "svn_url": "https://github.com/braintree/jsdoc-template", + "homepage": "", + "size": 643, + "stargazers_count": 126, + "watchers_count": 126, + "language": "CSS", + "has_issues": false, + "has_projects": true, + "has_downloads": true, + "has_wiki": false, + "has_pages": false, + "forks_count": 50, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 0, + "license": { + "key": "other", + "name": "Other", + "spdx_id": "NOASSERTION", + "url": null, + "node_id": "MDc6TGljZW5zZTA=" + }, + "forks": 50, + "open_issues": 0, + "watchers": 126, + "default_branch": "master" + }, + "source": { + "id": 59770336, + "node_id": "MDEwOlJlcG9zaXRvcnk1OTc3MDMzNg==", + "name": "jsdoc-template", + "full_name": "braintree/jsdoc-template", + "private": false, + "owner": { + "login": "braintree", + "id": 3453, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjM0NTM=", + "avatar_url": "https://avatars2.githubusercontent.com/u/3453?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/braintree", + "html_url": "https://github.com/braintree", + "followers_url": "https://api.github.com/users/braintree/followers", + "following_url": "https://api.github.com/users/braintree/following{/other_user}", + "gists_url": "https://api.github.com/users/braintree/gists{/gist_id}", + "starred_url": "https://api.github.com/users/braintree/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/braintree/subscriptions", + "organizations_url": "https://api.github.com/users/braintree/orgs", + "repos_url": "https://api.github.com/users/braintree/repos", + "events_url": "https://api.github.com/users/braintree/events{/privacy}", + "received_events_url": "https://api.github.com/users/braintree/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/braintree/jsdoc-template", + "description": "A clean, responsive documentation template with search and navigation highlighting for JSDoc 3", + "fork": false, + "url": "https://api.github.com/repos/braintree/jsdoc-template", + "forks_url": "https://api.github.com/repos/braintree/jsdoc-template/forks", + "keys_url": "https://api.github.com/repos/braintree/jsdoc-template/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/braintree/jsdoc-template/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/braintree/jsdoc-template/teams", + "hooks_url": "https://api.github.com/repos/braintree/jsdoc-template/hooks", + "issue_events_url": "https://api.github.com/repos/braintree/jsdoc-template/issues/events{/number}", + "events_url": "https://api.github.com/repos/braintree/jsdoc-template/events", + "assignees_url": "https://api.github.com/repos/braintree/jsdoc-template/assignees{/user}", + "branches_url": "https://api.github.com/repos/braintree/jsdoc-template/branches{/branch}", + "tags_url": "https://api.github.com/repos/braintree/jsdoc-template/tags", + "blobs_url": "https://api.github.com/repos/braintree/jsdoc-template/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/braintree/jsdoc-template/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/braintree/jsdoc-template/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/braintree/jsdoc-template/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/braintree/jsdoc-template/statuses/{sha}", + "languages_url": "https://api.github.com/repos/braintree/jsdoc-template/languages", + "stargazers_url": "https://api.github.com/repos/braintree/jsdoc-template/stargazers", + "contributors_url": "https://api.github.com/repos/braintree/jsdoc-template/contributors", + "subscribers_url": "https://api.github.com/repos/braintree/jsdoc-template/subscribers", + "subscription_url": "https://api.github.com/repos/braintree/jsdoc-template/subscription", + "commits_url": "https://api.github.com/repos/braintree/jsdoc-template/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/braintree/jsdoc-template/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/braintree/jsdoc-template/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/braintree/jsdoc-template/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/braintree/jsdoc-template/contents/{+path}", + "compare_url": "https://api.github.com/repos/braintree/jsdoc-template/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/braintree/jsdoc-template/merges", + "archive_url": "https://api.github.com/repos/braintree/jsdoc-template/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/braintree/jsdoc-template/downloads", + "issues_url": "https://api.github.com/repos/braintree/jsdoc-template/issues{/number}", + "pulls_url": "https://api.github.com/repos/braintree/jsdoc-template/pulls{/number}", + "milestones_url": "https://api.github.com/repos/braintree/jsdoc-template/milestones{/number}", + "notifications_url": "https://api.github.com/repos/braintree/jsdoc-template/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/braintree/jsdoc-template/labels{/name}", + "releases_url": "https://api.github.com/repos/braintree/jsdoc-template/releases{/id}", + "deployments_url": "https://api.github.com/repos/braintree/jsdoc-template/deployments", + "created_at": "2016-05-26T17:37:00Z", + "updated_at": "2020-06-23T01:52:09Z", + "pushed_at": "2020-03-24T18:02:57Z", + "git_url": "git://github.com/braintree/jsdoc-template.git", + "ssh_url": "git@github.com:braintree/jsdoc-template.git", + "clone_url": "https://github.com/braintree/jsdoc-template.git", + "svn_url": "https://github.com/braintree/jsdoc-template", + "homepage": "", + "size": 643, + "stargazers_count": 126, + "watchers_count": 126, + "language": "CSS", + "has_issues": false, + "has_projects": true, + "has_downloads": true, + "has_wiki": false, + "has_pages": false, + "forks_count": 50, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 0, + "license": { + "key": "other", + "name": "Other", + "spdx_id": "NOASSERTION", + "url": null, + "node_id": "MDc6TGljZW5zZTA=" + }, + "forks": 50, + "open_issues": 0, + "watchers": 126, + "default_branch": "master" + }, + "network_count": 50, + "subscribers_count": 0 +} diff --git a/apps/temp-docs/data/repos/marketplace.json b/apps/temp-docs/data/repos/marketplace.json new file mode 100644 index 00000000000..9deb90e1c2f --- /dev/null +++ b/apps/temp-docs/data/repos/marketplace.json @@ -0,0 +1,123 @@ +{ + "id": 231560476, + "node_id": "MDEwOlJlcG9zaXRvcnkyMzE1NjA0NzY=", + "name": "marketplace", + "full_name": "supabase/marketplace", + "private": false, + "owner": { + "login": "supabase", + "id": 54469796, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0NDY5Nzk2", + "avatar_url": "https://avatars3.githubusercontent.com/u/54469796?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/supabase", + "html_url": "https://github.com/supabase", + "followers_url": "https://api.github.com/users/supabase/followers", + "following_url": "https://api.github.com/users/supabase/following{/other_user}", + "gists_url": "https://api.github.com/users/supabase/gists{/gist_id}", + "starred_url": "https://api.github.com/users/supabase/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/supabase/subscriptions", + "organizations_url": "https://api.github.com/users/supabase/orgs", + "repos_url": "https://api.github.com/users/supabase/repos", + "events_url": "https://api.github.com/users/supabase/events{/privacy}", + "received_events_url": "https://api.github.com/users/supabase/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/supabase/marketplace", + "description": "An opensource repository of (PostgreSQL) SQL", + "fork": false, + "url": "https://api.github.com/repos/supabase/marketplace", + "forks_url": "https://api.github.com/repos/supabase/marketplace/forks", + "keys_url": "https://api.github.com/repos/supabase/marketplace/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/supabase/marketplace/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/supabase/marketplace/teams", + "hooks_url": "https://api.github.com/repos/supabase/marketplace/hooks", + "issue_events_url": "https://api.github.com/repos/supabase/marketplace/issues/events{/number}", + "events_url": "https://api.github.com/repos/supabase/marketplace/events", + "assignees_url": "https://api.github.com/repos/supabase/marketplace/assignees{/user}", + "branches_url": "https://api.github.com/repos/supabase/marketplace/branches{/branch}", + "tags_url": "https://api.github.com/repos/supabase/marketplace/tags", + "blobs_url": "https://api.github.com/repos/supabase/marketplace/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/supabase/marketplace/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/supabase/marketplace/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/supabase/marketplace/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/supabase/marketplace/statuses/{sha}", + "languages_url": "https://api.github.com/repos/supabase/marketplace/languages", + "stargazers_url": "https://api.github.com/repos/supabase/marketplace/stargazers", + "contributors_url": "https://api.github.com/repos/supabase/marketplace/contributors", + "subscribers_url": "https://api.github.com/repos/supabase/marketplace/subscribers", + "subscription_url": "https://api.github.com/repos/supabase/marketplace/subscription", + "commits_url": "https://api.github.com/repos/supabase/marketplace/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/supabase/marketplace/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/supabase/marketplace/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/supabase/marketplace/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/supabase/marketplace/contents/{+path}", + "compare_url": "https://api.github.com/repos/supabase/marketplace/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/supabase/marketplace/merges", + "archive_url": "https://api.github.com/repos/supabase/marketplace/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/supabase/marketplace/downloads", + "issues_url": "https://api.github.com/repos/supabase/marketplace/issues{/number}", + "pulls_url": "https://api.github.com/repos/supabase/marketplace/pulls{/number}", + "milestones_url": "https://api.github.com/repos/supabase/marketplace/milestones{/number}", + "notifications_url": "https://api.github.com/repos/supabase/marketplace/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/supabase/marketplace/labels{/name}", + "releases_url": "https://api.github.com/repos/supabase/marketplace/releases{/id}", + "deployments_url": "https://api.github.com/repos/supabase/marketplace/deployments", + "created_at": "2020-01-03T09:59:40Z", + "updated_at": "2020-06-29T02:36:36Z", + "pushed_at": "2020-04-27T06:28:08Z", + "git_url": "git://github.com/supabase/marketplace.git", + "ssh_url": "git@github.com:supabase/marketplace.git", + "clone_url": "https://github.com/supabase/marketplace.git", + "svn_url": "https://github.com/supabase/marketplace", + "homepage": "https://supabase.com", + "size": 112, + "stargazers_count": 9, + "watchers_count": 9, + "language": "TSQL", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "forks_count": 2, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 0, + "license": { + "key": "mit", + "name": "MIT License", + "spdx_id": "MIT", + "url": "https://api.github.com/licenses/mit", + "node_id": "MDc6TGljZW5zZTEz" + }, + "forks": 2, + "open_issues": 0, + "watchers": 9, + "default_branch": "master", + "temp_clone_token": null, + "organization": { + "login": "supabase", + "id": 54469796, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0NDY5Nzk2", + "avatar_url": "https://avatars3.githubusercontent.com/u/54469796?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/supabase", + "html_url": "https://github.com/supabase", + "followers_url": "https://api.github.com/users/supabase/followers", + "following_url": "https://api.github.com/users/supabase/following{/other_user}", + "gists_url": "https://api.github.com/users/supabase/gists{/gist_id}", + "starred_url": "https://api.github.com/users/supabase/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/supabase/subscriptions", + "organizations_url": "https://api.github.com/users/supabase/orgs", + "repos_url": "https://api.github.com/users/supabase/repos", + "events_url": "https://api.github.com/users/supabase/events{/privacy}", + "received_events_url": "https://api.github.com/users/supabase/received_events", + "type": "Organization", + "site_admin": false + }, + "network_count": 2, + "subscribers_count": 3 +} diff --git a/apps/temp-docs/data/repos/pg-api.json b/apps/temp-docs/data/repos/pg-api.json new file mode 100644 index 00000000000..c9efd236928 --- /dev/null +++ b/apps/temp-docs/data/repos/pg-api.json @@ -0,0 +1,123 @@ +{ + "id": 265560320, + "node_id": "MDEwOlJlcG9zaXRvcnkyNjU1NjAzMjA=", + "name": "pg-api", + "full_name": "supabase/pg-api", + "private": false, + "owner": { + "login": "supabase", + "id": 54469796, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0NDY5Nzk2", + "avatar_url": "https://avatars3.githubusercontent.com/u/54469796?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/supabase", + "html_url": "https://github.com/supabase", + "followers_url": "https://api.github.com/users/supabase/followers", + "following_url": "https://api.github.com/users/supabase/following{/other_user}", + "gists_url": "https://api.github.com/users/supabase/gists{/gist_id}", + "starred_url": "https://api.github.com/users/supabase/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/supabase/subscriptions", + "organizations_url": "https://api.github.com/users/supabase/orgs", + "repos_url": "https://api.github.com/users/supabase/repos", + "events_url": "https://api.github.com/users/supabase/events{/privacy}", + "received_events_url": "https://api.github.com/users/supabase/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/supabase/pg-api", + "description": "A RESTful API for managing your Postgres. Fetch tables, add roles, and run queries", + "fork": false, + "url": "https://api.github.com/repos/supabase/pg-api", + "forks_url": "https://api.github.com/repos/supabase/pg-api/forks", + "keys_url": "https://api.github.com/repos/supabase/pg-api/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/supabase/pg-api/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/supabase/pg-api/teams", + "hooks_url": "https://api.github.com/repos/supabase/pg-api/hooks", + "issue_events_url": "https://api.github.com/repos/supabase/pg-api/issues/events{/number}", + "events_url": "https://api.github.com/repos/supabase/pg-api/events", + "assignees_url": "https://api.github.com/repos/supabase/pg-api/assignees{/user}", + "branches_url": "https://api.github.com/repos/supabase/pg-api/branches{/branch}", + "tags_url": "https://api.github.com/repos/supabase/pg-api/tags", + "blobs_url": "https://api.github.com/repos/supabase/pg-api/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/supabase/pg-api/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/supabase/pg-api/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/supabase/pg-api/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/supabase/pg-api/statuses/{sha}", + "languages_url": "https://api.github.com/repos/supabase/pg-api/languages", + "stargazers_url": "https://api.github.com/repos/supabase/pg-api/stargazers", + "contributors_url": "https://api.github.com/repos/supabase/pg-api/contributors", + "subscribers_url": "https://api.github.com/repos/supabase/pg-api/subscribers", + "subscription_url": "https://api.github.com/repos/supabase/pg-api/subscription", + "commits_url": "https://api.github.com/repos/supabase/pg-api/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/supabase/pg-api/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/supabase/pg-api/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/supabase/pg-api/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/supabase/pg-api/contents/{+path}", + "compare_url": "https://api.github.com/repos/supabase/pg-api/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/supabase/pg-api/merges", + "archive_url": "https://api.github.com/repos/supabase/pg-api/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/supabase/pg-api/downloads", + "issues_url": "https://api.github.com/repos/supabase/pg-api/issues{/number}", + "pulls_url": "https://api.github.com/repos/supabase/pg-api/pulls{/number}", + "milestones_url": "https://api.github.com/repos/supabase/pg-api/milestones{/number}", + "notifications_url": "https://api.github.com/repos/supabase/pg-api/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/supabase/pg-api/labels{/name}", + "releases_url": "https://api.github.com/repos/supabase/pg-api/releases{/id}", + "deployments_url": "https://api.github.com/repos/supabase/pg-api/deployments", + "created_at": "2020-05-20T12:36:37Z", + "updated_at": "2020-10-30T08:25:43Z", + "pushed_at": "2020-10-26T16:26:10Z", + "git_url": "git://github.com/supabase/pg-api.git", + "ssh_url": "git@github.com:supabase/pg-api.git", + "clone_url": "https://github.com/supabase/pg-api.git", + "svn_url": "https://github.com/supabase/pg-api", + "homepage": "https://supabase.com", + "size": 87982, + "stargazers_count": 72, + "watchers_count": 72, + "language": "TypeScript", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 5, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 6, + "license": { + "key": "apache-2.0", + "name": "Apache License 2.0", + "spdx_id": "Apache-2.0", + "url": "https://api.github.com/licenses/apache-2.0", + "node_id": "MDc6TGljZW5zZTI=" + }, + "forks": 5, + "open_issues": 6, + "watchers": 72, + "default_branch": "develop", + "temp_clone_token": null, + "organization": { + "login": "supabase", + "id": 54469796, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0NDY5Nzk2", + "avatar_url": "https://avatars3.githubusercontent.com/u/54469796?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/supabase", + "html_url": "https://github.com/supabase", + "followers_url": "https://api.github.com/users/supabase/followers", + "following_url": "https://api.github.com/users/supabase/following{/other_user}", + "gists_url": "https://api.github.com/users/supabase/gists{/gist_id}", + "starred_url": "https://api.github.com/users/supabase/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/supabase/subscriptions", + "organizations_url": "https://api.github.com/users/supabase/orgs", + "repos_url": "https://api.github.com/users/supabase/repos", + "events_url": "https://api.github.com/users/supabase/events{/privacy}", + "received_events_url": "https://api.github.com/users/supabase/received_events", + "type": "Organization", + "site_admin": false + }, + "network_count": 5, + "subscribers_count": 6 +} diff --git a/apps/temp-docs/data/repos/pg_listen.json b/apps/temp-docs/data/repos/pg_listen.json new file mode 100644 index 00000000000..9cc417ae95e --- /dev/null +++ b/apps/temp-docs/data/repos/pg_listen.json @@ -0,0 +1,323 @@ +{ + "id": 258239197, + "node_id": "MDEwOlJlcG9zaXRvcnkyNTgyMzkxOTc=", + "name": "pg_listen", + "full_name": "supabase/pg_listen", + "private": false, + "owner": { + "login": "supabase", + "id": 54469796, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0NDY5Nzk2", + "avatar_url": "https://avatars3.githubusercontent.com/u/54469796?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/supabase", + "html_url": "https://github.com/supabase", + "followers_url": "https://api.github.com/users/supabase/followers", + "following_url": "https://api.github.com/users/supabase/following{/other_user}", + "gists_url": "https://api.github.com/users/supabase/gists{/gist_id}", + "starred_url": "https://api.github.com/users/supabase/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/supabase/subscriptions", + "organizations_url": "https://api.github.com/users/supabase/orgs", + "repos_url": "https://api.github.com/users/supabase/repos", + "events_url": "https://api.github.com/users/supabase/events{/privacy}", + "received_events_url": "https://api.github.com/users/supabase/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/supabase/pg_listen", + "description": "Trigger shell command from NOTIFY", + "fork": true, + "url": "https://api.github.com/repos/supabase/pg_listen", + "forks_url": "https://api.github.com/repos/supabase/pg_listen/forks", + "keys_url": "https://api.github.com/repos/supabase/pg_listen/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/supabase/pg_listen/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/supabase/pg_listen/teams", + "hooks_url": "https://api.github.com/repos/supabase/pg_listen/hooks", + "issue_events_url": "https://api.github.com/repos/supabase/pg_listen/issues/events{/number}", + "events_url": "https://api.github.com/repos/supabase/pg_listen/events", + "assignees_url": "https://api.github.com/repos/supabase/pg_listen/assignees{/user}", + "branches_url": "https://api.github.com/repos/supabase/pg_listen/branches{/branch}", + "tags_url": "https://api.github.com/repos/supabase/pg_listen/tags", + "blobs_url": "https://api.github.com/repos/supabase/pg_listen/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/supabase/pg_listen/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/supabase/pg_listen/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/supabase/pg_listen/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/supabase/pg_listen/statuses/{sha}", + "languages_url": "https://api.github.com/repos/supabase/pg_listen/languages", + "stargazers_url": "https://api.github.com/repos/supabase/pg_listen/stargazers", + "contributors_url": "https://api.github.com/repos/supabase/pg_listen/contributors", + "subscribers_url": "https://api.github.com/repos/supabase/pg_listen/subscribers", + "subscription_url": "https://api.github.com/repos/supabase/pg_listen/subscription", + "commits_url": "https://api.github.com/repos/supabase/pg_listen/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/supabase/pg_listen/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/supabase/pg_listen/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/supabase/pg_listen/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/supabase/pg_listen/contents/{+path}", + "compare_url": "https://api.github.com/repos/supabase/pg_listen/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/supabase/pg_listen/merges", + "archive_url": "https://api.github.com/repos/supabase/pg_listen/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/supabase/pg_listen/downloads", + "issues_url": "https://api.github.com/repos/supabase/pg_listen/issues{/number}", + "pulls_url": "https://api.github.com/repos/supabase/pg_listen/pulls{/number}", + "milestones_url": "https://api.github.com/repos/supabase/pg_listen/milestones{/number}", + "notifications_url": "https://api.github.com/repos/supabase/pg_listen/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/supabase/pg_listen/labels{/name}", + "releases_url": "https://api.github.com/repos/supabase/pg_listen/releases{/id}", + "deployments_url": "https://api.github.com/repos/supabase/pg_listen/deployments", + "created_at": "2020-04-23T14:54:20Z", + "updated_at": "2020-06-19T01:12:20Z", + "pushed_at": "2020-04-23T15:16:06Z", + "git_url": "git://github.com/supabase/pg_listen.git", + "ssh_url": "git@github.com:supabase/pg_listen.git", + "clone_url": "https://github.com/supabase/pg_listen.git", + "svn_url": "https://github.com/supabase/pg_listen", + "homepage": null, + "size": 20, + "stargazers_count": 0, + "watchers_count": 0, + "language": "C", + "has_issues": false, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 0, + "license": { + "key": "mit", + "name": "MIT License", + "spdx_id": "MIT", + "url": "https://api.github.com/licenses/mit", + "node_id": "MDc6TGljZW5zZTEz" + }, + "forks": 0, + "open_issues": 0, + "watchers": 0, + "default_branch": "master", + "temp_clone_token": null, + "organization": { + "login": "supabase", + "id": 54469796, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0NDY5Nzk2", + "avatar_url": "https://avatars3.githubusercontent.com/u/54469796?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/supabase", + "html_url": "https://github.com/supabase", + "followers_url": "https://api.github.com/users/supabase/followers", + "following_url": "https://api.github.com/users/supabase/following{/other_user}", + "gists_url": "https://api.github.com/users/supabase/gists{/gist_id}", + "starred_url": "https://api.github.com/users/supabase/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/supabase/subscriptions", + "organizations_url": "https://api.github.com/users/supabase/orgs", + "repos_url": "https://api.github.com/users/supabase/repos", + "events_url": "https://api.github.com/users/supabase/events{/privacy}", + "received_events_url": "https://api.github.com/users/supabase/received_events", + "type": "Organization", + "site_admin": false + }, + "parent": { + "id": 124506929, + "node_id": "MDEwOlJlcG9zaXRvcnkxMjQ1MDY5Mjk=", + "name": "pg_listen", + "full_name": "begriffs/pg_listen", + "private": false, + "owner": { + "login": "begriffs", + "id": 911911, + "node_id": "MDQ6VXNlcjkxMTkxMQ==", + "avatar_url": "https://avatars2.githubusercontent.com/u/911911?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/begriffs", + "html_url": "https://github.com/begriffs", + "followers_url": "https://api.github.com/users/begriffs/followers", + "following_url": "https://api.github.com/users/begriffs/following{/other_user}", + "gists_url": "https://api.github.com/users/begriffs/gists{/gist_id}", + "starred_url": "https://api.github.com/users/begriffs/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/begriffs/subscriptions", + "organizations_url": "https://api.github.com/users/begriffs/orgs", + "repos_url": "https://api.github.com/users/begriffs/repos", + "events_url": "https://api.github.com/users/begriffs/events{/privacy}", + "received_events_url": "https://api.github.com/users/begriffs/received_events", + "type": "User", + "site_admin": false + }, + "html_url": "https://github.com/begriffs/pg_listen", + "description": "Trigger shell command from NOTIFY", + "fork": false, + "url": "https://api.github.com/repos/begriffs/pg_listen", + "forks_url": "https://api.github.com/repos/begriffs/pg_listen/forks", + "keys_url": "https://api.github.com/repos/begriffs/pg_listen/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/begriffs/pg_listen/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/begriffs/pg_listen/teams", + "hooks_url": "https://api.github.com/repos/begriffs/pg_listen/hooks", + "issue_events_url": "https://api.github.com/repos/begriffs/pg_listen/issues/events{/number}", + "events_url": "https://api.github.com/repos/begriffs/pg_listen/events", + "assignees_url": "https://api.github.com/repos/begriffs/pg_listen/assignees{/user}", + "branches_url": "https://api.github.com/repos/begriffs/pg_listen/branches{/branch}", + "tags_url": "https://api.github.com/repos/begriffs/pg_listen/tags", + "blobs_url": "https://api.github.com/repos/begriffs/pg_listen/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/begriffs/pg_listen/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/begriffs/pg_listen/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/begriffs/pg_listen/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/begriffs/pg_listen/statuses/{sha}", + "languages_url": "https://api.github.com/repos/begriffs/pg_listen/languages", + "stargazers_url": "https://api.github.com/repos/begriffs/pg_listen/stargazers", + "contributors_url": "https://api.github.com/repos/begriffs/pg_listen/contributors", + "subscribers_url": "https://api.github.com/repos/begriffs/pg_listen/subscribers", + "subscription_url": "https://api.github.com/repos/begriffs/pg_listen/subscription", + "commits_url": "https://api.github.com/repos/begriffs/pg_listen/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/begriffs/pg_listen/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/begriffs/pg_listen/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/begriffs/pg_listen/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/begriffs/pg_listen/contents/{+path}", + "compare_url": "https://api.github.com/repos/begriffs/pg_listen/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/begriffs/pg_listen/merges", + "archive_url": "https://api.github.com/repos/begriffs/pg_listen/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/begriffs/pg_listen/downloads", + "issues_url": "https://api.github.com/repos/begriffs/pg_listen/issues{/number}", + "pulls_url": "https://api.github.com/repos/begriffs/pg_listen/pulls{/number}", + "milestones_url": "https://api.github.com/repos/begriffs/pg_listen/milestones{/number}", + "notifications_url": "https://api.github.com/repos/begriffs/pg_listen/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/begriffs/pg_listen/labels{/name}", + "releases_url": "https://api.github.com/repos/begriffs/pg_listen/releases{/id}", + "deployments_url": "https://api.github.com/repos/begriffs/pg_listen/deployments", + "created_at": "2018-03-09T07:51:43Z", + "updated_at": "2020-06-19T01:12:49Z", + "pushed_at": "2020-02-27T02:45:01Z", + "git_url": "git://github.com/begriffs/pg_listen.git", + "ssh_url": "git@github.com:begriffs/pg_listen.git", + "clone_url": "https://github.com/begriffs/pg_listen.git", + "svn_url": "https://github.com/begriffs/pg_listen", + "homepage": null, + "size": 19, + "stargazers_count": 69, + "watchers_count": 69, + "language": "C", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "forks_count": 9, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 1, + "license": { + "key": "mit", + "name": "MIT License", + "spdx_id": "MIT", + "url": "https://api.github.com/licenses/mit", + "node_id": "MDc6TGljZW5zZTEz" + }, + "forks": 9, + "open_issues": 1, + "watchers": 69, + "default_branch": "master" + }, + "source": { + "id": 124506929, + "node_id": "MDEwOlJlcG9zaXRvcnkxMjQ1MDY5Mjk=", + "name": "pg_listen", + "full_name": "begriffs/pg_listen", + "private": false, + "owner": { + "login": "begriffs", + "id": 911911, + "node_id": "MDQ6VXNlcjkxMTkxMQ==", + "avatar_url": "https://avatars2.githubusercontent.com/u/911911?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/begriffs", + "html_url": "https://github.com/begriffs", + "followers_url": "https://api.github.com/users/begriffs/followers", + "following_url": "https://api.github.com/users/begriffs/following{/other_user}", + "gists_url": "https://api.github.com/users/begriffs/gists{/gist_id}", + "starred_url": "https://api.github.com/users/begriffs/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/begriffs/subscriptions", + "organizations_url": "https://api.github.com/users/begriffs/orgs", + "repos_url": "https://api.github.com/users/begriffs/repos", + "events_url": "https://api.github.com/users/begriffs/events{/privacy}", + "received_events_url": "https://api.github.com/users/begriffs/received_events", + "type": "User", + "site_admin": false + }, + "html_url": "https://github.com/begriffs/pg_listen", + "description": "Trigger shell command from NOTIFY", + "fork": false, + "url": "https://api.github.com/repos/begriffs/pg_listen", + "forks_url": "https://api.github.com/repos/begriffs/pg_listen/forks", + "keys_url": "https://api.github.com/repos/begriffs/pg_listen/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/begriffs/pg_listen/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/begriffs/pg_listen/teams", + "hooks_url": "https://api.github.com/repos/begriffs/pg_listen/hooks", + "issue_events_url": "https://api.github.com/repos/begriffs/pg_listen/issues/events{/number}", + "events_url": "https://api.github.com/repos/begriffs/pg_listen/events", + "assignees_url": "https://api.github.com/repos/begriffs/pg_listen/assignees{/user}", + "branches_url": "https://api.github.com/repos/begriffs/pg_listen/branches{/branch}", + "tags_url": "https://api.github.com/repos/begriffs/pg_listen/tags", + "blobs_url": "https://api.github.com/repos/begriffs/pg_listen/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/begriffs/pg_listen/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/begriffs/pg_listen/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/begriffs/pg_listen/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/begriffs/pg_listen/statuses/{sha}", + "languages_url": "https://api.github.com/repos/begriffs/pg_listen/languages", + "stargazers_url": "https://api.github.com/repos/begriffs/pg_listen/stargazers", + "contributors_url": "https://api.github.com/repos/begriffs/pg_listen/contributors", + "subscribers_url": "https://api.github.com/repos/begriffs/pg_listen/subscribers", + "subscription_url": "https://api.github.com/repos/begriffs/pg_listen/subscription", + "commits_url": "https://api.github.com/repos/begriffs/pg_listen/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/begriffs/pg_listen/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/begriffs/pg_listen/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/begriffs/pg_listen/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/begriffs/pg_listen/contents/{+path}", + "compare_url": "https://api.github.com/repos/begriffs/pg_listen/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/begriffs/pg_listen/merges", + "archive_url": "https://api.github.com/repos/begriffs/pg_listen/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/begriffs/pg_listen/downloads", + "issues_url": "https://api.github.com/repos/begriffs/pg_listen/issues{/number}", + "pulls_url": "https://api.github.com/repos/begriffs/pg_listen/pulls{/number}", + "milestones_url": "https://api.github.com/repos/begriffs/pg_listen/milestones{/number}", + "notifications_url": "https://api.github.com/repos/begriffs/pg_listen/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/begriffs/pg_listen/labels{/name}", + "releases_url": "https://api.github.com/repos/begriffs/pg_listen/releases{/id}", + "deployments_url": "https://api.github.com/repos/begriffs/pg_listen/deployments", + "created_at": "2018-03-09T07:51:43Z", + "updated_at": "2020-06-19T01:12:49Z", + "pushed_at": "2020-02-27T02:45:01Z", + "git_url": "git://github.com/begriffs/pg_listen.git", + "ssh_url": "git@github.com:begriffs/pg_listen.git", + "clone_url": "https://github.com/begriffs/pg_listen.git", + "svn_url": "https://github.com/begriffs/pg_listen", + "homepage": null, + "size": 19, + "stargazers_count": 69, + "watchers_count": 69, + "language": "C", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "forks_count": 9, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 1, + "license": { + "key": "mit", + "name": "MIT License", + "spdx_id": "MIT", + "url": "https://api.github.com/licenses/mit", + "node_id": "MDc6TGljZW5zZTEz" + }, + "forks": 9, + "open_issues": 1, + "watchers": 69, + "default_branch": "master" + }, + "network_count": 9, + "subscribers_count": 0 +} diff --git a/apps/temp-docs/data/repos/postgres.json b/apps/temp-docs/data/repos/postgres.json new file mode 100644 index 00000000000..c2a8e4250cf --- /dev/null +++ b/apps/temp-docs/data/repos/postgres.json @@ -0,0 +1,123 @@ +{ + "id": 254578428, + "node_id": "MDEwOlJlcG9zaXRvcnkyNTQ1Nzg0Mjg=", + "name": "postgres", + "full_name": "supabase/postgres", + "private": false, + "owner": { + "login": "supabase", + "id": 54469796, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0NDY5Nzk2", + "avatar_url": "https://avatars3.githubusercontent.com/u/54469796?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/supabase", + "html_url": "https://github.com/supabase", + "followers_url": "https://api.github.com/users/supabase/followers", + "following_url": "https://api.github.com/users/supabase/following{/other_user}", + "gists_url": "https://api.github.com/users/supabase/gists{/gist_id}", + "starred_url": "https://api.github.com/users/supabase/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/supabase/subscriptions", + "organizations_url": "https://api.github.com/users/supabase/orgs", + "repos_url": "https://api.github.com/users/supabase/repos", + "events_url": "https://api.github.com/users/supabase/events{/privacy}", + "received_events_url": "https://api.github.com/users/supabase/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/supabase/postgres", + "description": "Unmodified Postgres with some useful plugins", + "fork": false, + "url": "https://api.github.com/repos/supabase/postgres", + "forks_url": "https://api.github.com/repos/supabase/postgres/forks", + "keys_url": "https://api.github.com/repos/supabase/postgres/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/supabase/postgres/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/supabase/postgres/teams", + "hooks_url": "https://api.github.com/repos/supabase/postgres/hooks", + "issue_events_url": "https://api.github.com/repos/supabase/postgres/issues/events{/number}", + "events_url": "https://api.github.com/repos/supabase/postgres/events", + "assignees_url": "https://api.github.com/repos/supabase/postgres/assignees{/user}", + "branches_url": "https://api.github.com/repos/supabase/postgres/branches{/branch}", + "tags_url": "https://api.github.com/repos/supabase/postgres/tags", + "blobs_url": "https://api.github.com/repos/supabase/postgres/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/supabase/postgres/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/supabase/postgres/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/supabase/postgres/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/supabase/postgres/statuses/{sha}", + "languages_url": "https://api.github.com/repos/supabase/postgres/languages", + "stargazers_url": "https://api.github.com/repos/supabase/postgres/stargazers", + "contributors_url": "https://api.github.com/repos/supabase/postgres/contributors", + "subscribers_url": "https://api.github.com/repos/supabase/postgres/subscribers", + "subscription_url": "https://api.github.com/repos/supabase/postgres/subscription", + "commits_url": "https://api.github.com/repos/supabase/postgres/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/supabase/postgres/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/supabase/postgres/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/supabase/postgres/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/supabase/postgres/contents/{+path}", + "compare_url": "https://api.github.com/repos/supabase/postgres/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/supabase/postgres/merges", + "archive_url": "https://api.github.com/repos/supabase/postgres/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/supabase/postgres/downloads", + "issues_url": "https://api.github.com/repos/supabase/postgres/issues{/number}", + "pulls_url": "https://api.github.com/repos/supabase/postgres/pulls{/number}", + "milestones_url": "https://api.github.com/repos/supabase/postgres/milestones{/number}", + "notifications_url": "https://api.github.com/repos/supabase/postgres/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/supabase/postgres/labels{/name}", + "releases_url": "https://api.github.com/repos/supabase/postgres/releases{/id}", + "deployments_url": "https://api.github.com/repos/supabase/postgres/deployments", + "created_at": "2020-04-10T08:02:57Z", + "updated_at": "2020-10-30T08:25:37Z", + "pushed_at": "2020-10-02T08:31:17Z", + "git_url": "git://github.com/supabase/postgres.git", + "ssh_url": "git@github.com:supabase/postgres.git", + "clone_url": "https://github.com/supabase/postgres.git", + "svn_url": "https://github.com/supabase/postgres", + "homepage": "https://supabase.com", + "size": 117, + "stargazers_count": 151, + "watchers_count": 151, + "language": "Shell", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "forks_count": 4, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 4, + "license": { + "key": "postgresql", + "name": "PostgreSQL License", + "spdx_id": "PostgreSQL", + "url": "https://api.github.com/licenses/postgresql", + "node_id": "MDc6TGljZW5zZTMx" + }, + "forks": 4, + "open_issues": 4, + "watchers": 151, + "default_branch": "develop", + "temp_clone_token": null, + "organization": { + "login": "supabase", + "id": 54469796, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0NDY5Nzk2", + "avatar_url": "https://avatars3.githubusercontent.com/u/54469796?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/supabase", + "html_url": "https://github.com/supabase", + "followers_url": "https://api.github.com/users/supabase/followers", + "following_url": "https://api.github.com/users/supabase/following{/other_user}", + "gists_url": "https://api.github.com/users/supabase/gists{/gist_id}", + "starred_url": "https://api.github.com/users/supabase/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/supabase/subscriptions", + "organizations_url": "https://api.github.com/users/supabase/orgs", + "repos_url": "https://api.github.com/users/supabase/repos", + "events_url": "https://api.github.com/users/supabase/events{/privacy}", + "received_events_url": "https://api.github.com/users/supabase/received_events", + "type": "Organization", + "site_admin": false + }, + "network_count": 4, + "subscribers_count": 8 +} diff --git a/apps/temp-docs/data/repos/postgrest-js.json b/apps/temp-docs/data/repos/postgrest-js.json new file mode 100644 index 00000000000..5719e6cf64d --- /dev/null +++ b/apps/temp-docs/data/repos/postgrest-js.json @@ -0,0 +1,123 @@ +{ + "id": 236425882, + "node_id": "MDEwOlJlcG9zaXRvcnkyMzY0MjU4ODI=", + "name": "postgrest-js", + "full_name": "supabase/postgrest-js", + "private": false, + "owner": { + "login": "supabase", + "id": 54469796, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0NDY5Nzk2", + "avatar_url": "https://avatars3.githubusercontent.com/u/54469796?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/supabase", + "html_url": "https://github.com/supabase", + "followers_url": "https://api.github.com/users/supabase/followers", + "following_url": "https://api.github.com/users/supabase/following{/other_user}", + "gists_url": "https://api.github.com/users/supabase/gists{/gist_id}", + "starred_url": "https://api.github.com/users/supabase/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/supabase/subscriptions", + "organizations_url": "https://api.github.com/users/supabase/orgs", + "repos_url": "https://api.github.com/users/supabase/repos", + "events_url": "https://api.github.com/users/supabase/events{/privacy}", + "received_events_url": "https://api.github.com/users/supabase/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/supabase/postgrest-js", + "description": "Isomorphic JavaScript client for PostgREST", + "fork": false, + "url": "https://api.github.com/repos/supabase/postgrest-js", + "forks_url": "https://api.github.com/repos/supabase/postgrest-js/forks", + "keys_url": "https://api.github.com/repos/supabase/postgrest-js/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/supabase/postgrest-js/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/supabase/postgrest-js/teams", + "hooks_url": "https://api.github.com/repos/supabase/postgrest-js/hooks", + "issue_events_url": "https://api.github.com/repos/supabase/postgrest-js/issues/events{/number}", + "events_url": "https://api.github.com/repos/supabase/postgrest-js/events", + "assignees_url": "https://api.github.com/repos/supabase/postgrest-js/assignees{/user}", + "branches_url": "https://api.github.com/repos/supabase/postgrest-js/branches{/branch}", + "tags_url": "https://api.github.com/repos/supabase/postgrest-js/tags", + "blobs_url": "https://api.github.com/repos/supabase/postgrest-js/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/supabase/postgrest-js/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/supabase/postgrest-js/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/supabase/postgrest-js/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/supabase/postgrest-js/statuses/{sha}", + "languages_url": "https://api.github.com/repos/supabase/postgrest-js/languages", + "stargazers_url": "https://api.github.com/repos/supabase/postgrest-js/stargazers", + "contributors_url": "https://api.github.com/repos/supabase/postgrest-js/contributors", + "subscribers_url": "https://api.github.com/repos/supabase/postgrest-js/subscribers", + "subscription_url": "https://api.github.com/repos/supabase/postgrest-js/subscription", + "commits_url": "https://api.github.com/repos/supabase/postgrest-js/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/supabase/postgrest-js/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/supabase/postgrest-js/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/supabase/postgrest-js/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/supabase/postgrest-js/contents/{+path}", + "compare_url": "https://api.github.com/repos/supabase/postgrest-js/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/supabase/postgrest-js/merges", + "archive_url": "https://api.github.com/repos/supabase/postgrest-js/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/supabase/postgrest-js/downloads", + "issues_url": "https://api.github.com/repos/supabase/postgrest-js/issues{/number}", + "pulls_url": "https://api.github.com/repos/supabase/postgrest-js/pulls{/number}", + "milestones_url": "https://api.github.com/repos/supabase/postgrest-js/milestones{/number}", + "notifications_url": "https://api.github.com/repos/supabase/postgrest-js/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/supabase/postgrest-js/labels{/name}", + "releases_url": "https://api.github.com/repos/supabase/postgrest-js/releases{/id}", + "deployments_url": "https://api.github.com/repos/supabase/postgrest-js/deployments", + "created_at": "2020-01-27T05:32:19Z", + "updated_at": "2020-08-23T03:34:50Z", + "pushed_at": "2020-08-23T03:34:51Z", + "git_url": "git://github.com/supabase/postgrest-js.git", + "ssh_url": "git@github.com:supabase/postgrest-js.git", + "clone_url": "https://github.com/supabase/postgrest-js.git", + "svn_url": "https://github.com/supabase/postgrest-js", + "homepage": "https://supabase.com", + "size": 3225, + "stargazers_count": 79, + "watchers_count": 79, + "language": "JavaScript", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "forks_count": 3, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 2, + "license": { + "key": "mit", + "name": "MIT License", + "spdx_id": "MIT", + "url": "https://api.github.com/licenses/mit", + "node_id": "MDc6TGljZW5zZTEz" + }, + "forks": 3, + "open_issues": 2, + "watchers": 79, + "default_branch": "master", + "temp_clone_token": null, + "organization": { + "login": "supabase", + "id": 54469796, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0NDY5Nzk2", + "avatar_url": "https://avatars3.githubusercontent.com/u/54469796?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/supabase", + "html_url": "https://github.com/supabase", + "followers_url": "https://api.github.com/users/supabase/followers", + "following_url": "https://api.github.com/users/supabase/following{/other_user}", + "gists_url": "https://api.github.com/users/supabase/gists{/gist_id}", + "starred_url": "https://api.github.com/users/supabase/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/supabase/subscriptions", + "organizations_url": "https://api.github.com/users/supabase/orgs", + "repos_url": "https://api.github.com/users/supabase/repos", + "events_url": "https://api.github.com/users/supabase/events{/privacy}", + "received_events_url": "https://api.github.com/users/supabase/received_events", + "type": "Organization", + "site_admin": false + }, + "network_count": 3, + "subscribers_count": 9 +} diff --git a/apps/temp-docs/data/repos/postgrest-py.json b/apps/temp-docs/data/repos/postgrest-py.json new file mode 100644 index 00000000000..0242cc79bd7 --- /dev/null +++ b/apps/temp-docs/data/repos/postgrest-py.json @@ -0,0 +1,117 @@ +{ + "id": 263793262, + "node_id": "MDEwOlJlcG9zaXRvcnkyNjM3OTMyNjI=", + "name": "postgrest-py", + "full_name": "supabase/postgrest-py", + "private": false, + "owner": { + "login": "supabase", + "id": 54469796, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0NDY5Nzk2", + "avatar_url": "https://avatars3.githubusercontent.com/u/54469796?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/supabase", + "html_url": "https://github.com/supabase", + "followers_url": "https://api.github.com/users/supabase/followers", + "following_url": "https://api.github.com/users/supabase/following{/other_user}", + "gists_url": "https://api.github.com/users/supabase/gists{/gist_id}", + "starred_url": "https://api.github.com/users/supabase/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/supabase/subscriptions", + "organizations_url": "https://api.github.com/users/supabase/orgs", + "repos_url": "https://api.github.com/users/supabase/repos", + "events_url": "https://api.github.com/users/supabase/events{/privacy}", + "received_events_url": "https://api.github.com/users/supabase/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/supabase/postgrest-py", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/supabase/postgrest-py", + "forks_url": "https://api.github.com/repos/supabase/postgrest-py/forks", + "keys_url": "https://api.github.com/repos/supabase/postgrest-py/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/supabase/postgrest-py/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/supabase/postgrest-py/teams", + "hooks_url": "https://api.github.com/repos/supabase/postgrest-py/hooks", + "issue_events_url": "https://api.github.com/repos/supabase/postgrest-py/issues/events{/number}", + "events_url": "https://api.github.com/repos/supabase/postgrest-py/events", + "assignees_url": "https://api.github.com/repos/supabase/postgrest-py/assignees{/user}", + "branches_url": "https://api.github.com/repos/supabase/postgrest-py/branches{/branch}", + "tags_url": "https://api.github.com/repos/supabase/postgrest-py/tags", + "blobs_url": "https://api.github.com/repos/supabase/postgrest-py/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/supabase/postgrest-py/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/supabase/postgrest-py/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/supabase/postgrest-py/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/supabase/postgrest-py/statuses/{sha}", + "languages_url": "https://api.github.com/repos/supabase/postgrest-py/languages", + "stargazers_url": "https://api.github.com/repos/supabase/postgrest-py/stargazers", + "contributors_url": "https://api.github.com/repos/supabase/postgrest-py/contributors", + "subscribers_url": "https://api.github.com/repos/supabase/postgrest-py/subscribers", + "subscription_url": "https://api.github.com/repos/supabase/postgrest-py/subscription", + "commits_url": "https://api.github.com/repos/supabase/postgrest-py/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/supabase/postgrest-py/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/supabase/postgrest-py/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/supabase/postgrest-py/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/supabase/postgrest-py/contents/{+path}", + "compare_url": "https://api.github.com/repos/supabase/postgrest-py/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/supabase/postgrest-py/merges", + "archive_url": "https://api.github.com/repos/supabase/postgrest-py/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/supabase/postgrest-py/downloads", + "issues_url": "https://api.github.com/repos/supabase/postgrest-py/issues{/number}", + "pulls_url": "https://api.github.com/repos/supabase/postgrest-py/pulls{/number}", + "milestones_url": "https://api.github.com/repos/supabase/postgrest-py/milestones{/number}", + "notifications_url": "https://api.github.com/repos/supabase/postgrest-py/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/supabase/postgrest-py/labels{/name}", + "releases_url": "https://api.github.com/repos/supabase/postgrest-py/releases{/id}", + "deployments_url": "https://api.github.com/repos/supabase/postgrest-py/deployments", + "created_at": "2020-05-14T02:18:24Z", + "updated_at": "2020-06-04T05:41:43Z", + "pushed_at": "2020-05-14T02:18:26Z", + "git_url": "git://github.com/supabase/postgrest-py.git", + "ssh_url": "git@github.com:supabase/postgrest-py.git", + "clone_url": "https://github.com/supabase/postgrest-py.git", + "svn_url": "https://github.com/supabase/postgrest-py", + "homepage": null, + "size": 0, + "stargazers_count": 2, + "watchers_count": 2, + "language": null, + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 0, + "license": null, + "forks": 0, + "open_issues": 0, + "watchers": 2, + "default_branch": "master", + "temp_clone_token": null, + "organization": { + "login": "supabase", + "id": 54469796, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0NDY5Nzk2", + "avatar_url": "https://avatars3.githubusercontent.com/u/54469796?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/supabase", + "html_url": "https://github.com/supabase", + "followers_url": "https://api.github.com/users/supabase/followers", + "following_url": "https://api.github.com/users/supabase/following{/other_user}", + "gists_url": "https://api.github.com/users/supabase/gists{/gist_id}", + "starred_url": "https://api.github.com/users/supabase/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/supabase/subscriptions", + "organizations_url": "https://api.github.com/users/supabase/orgs", + "repos_url": "https://api.github.com/users/supabase/repos", + "events_url": "https://api.github.com/users/supabase/events{/privacy}", + "received_events_url": "https://api.github.com/users/supabase/received_events", + "type": "Organization", + "site_admin": false + }, + "network_count": 0, + "subscribers_count": 3 +} diff --git a/apps/temp-docs/data/repos/postgrest-rs.json b/apps/temp-docs/data/repos/postgrest-rs.json new file mode 100644 index 00000000000..bcf99e6a798 --- /dev/null +++ b/apps/temp-docs/data/repos/postgrest-rs.json @@ -0,0 +1,123 @@ +{ + "id": 263793466, + "node_id": "MDEwOlJlcG9zaXRvcnkyNjM3OTM0NjY=", + "name": "postgrest-rs", + "full_name": "supabase/postgrest-rs", + "private": false, + "owner": { + "login": "supabase", + "id": 54469796, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0NDY5Nzk2", + "avatar_url": "https://avatars3.githubusercontent.com/u/54469796?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/supabase", + "html_url": "https://github.com/supabase", + "followers_url": "https://api.github.com/users/supabase/followers", + "following_url": "https://api.github.com/users/supabase/following{/other_user}", + "gists_url": "https://api.github.com/users/supabase/gists{/gist_id}", + "starred_url": "https://api.github.com/users/supabase/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/supabase/subscriptions", + "organizations_url": "https://api.github.com/users/supabase/orgs", + "repos_url": "https://api.github.com/users/supabase/repos", + "events_url": "https://api.github.com/users/supabase/events{/privacy}", + "received_events_url": "https://api.github.com/users/supabase/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/supabase/postgrest-rs", + "description": "Rust client for PostgREST", + "fork": false, + "url": "https://api.github.com/repos/supabase/postgrest-rs", + "forks_url": "https://api.github.com/repos/supabase/postgrest-rs/forks", + "keys_url": "https://api.github.com/repos/supabase/postgrest-rs/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/supabase/postgrest-rs/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/supabase/postgrest-rs/teams", + "hooks_url": "https://api.github.com/repos/supabase/postgrest-rs/hooks", + "issue_events_url": "https://api.github.com/repos/supabase/postgrest-rs/issues/events{/number}", + "events_url": "https://api.github.com/repos/supabase/postgrest-rs/events", + "assignees_url": "https://api.github.com/repos/supabase/postgrest-rs/assignees{/user}", + "branches_url": "https://api.github.com/repos/supabase/postgrest-rs/branches{/branch}", + "tags_url": "https://api.github.com/repos/supabase/postgrest-rs/tags", + "blobs_url": "https://api.github.com/repos/supabase/postgrest-rs/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/supabase/postgrest-rs/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/supabase/postgrest-rs/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/supabase/postgrest-rs/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/supabase/postgrest-rs/statuses/{sha}", + "languages_url": "https://api.github.com/repos/supabase/postgrest-rs/languages", + "stargazers_url": "https://api.github.com/repos/supabase/postgrest-rs/stargazers", + "contributors_url": "https://api.github.com/repos/supabase/postgrest-rs/contributors", + "subscribers_url": "https://api.github.com/repos/supabase/postgrest-rs/subscribers", + "subscription_url": "https://api.github.com/repos/supabase/postgrest-rs/subscription", + "commits_url": "https://api.github.com/repos/supabase/postgrest-rs/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/supabase/postgrest-rs/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/supabase/postgrest-rs/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/supabase/postgrest-rs/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/supabase/postgrest-rs/contents/{+path}", + "compare_url": "https://api.github.com/repos/supabase/postgrest-rs/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/supabase/postgrest-rs/merges", + "archive_url": "https://api.github.com/repos/supabase/postgrest-rs/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/supabase/postgrest-rs/downloads", + "issues_url": "https://api.github.com/repos/supabase/postgrest-rs/issues{/number}", + "pulls_url": "https://api.github.com/repos/supabase/postgrest-rs/pulls{/number}", + "milestones_url": "https://api.github.com/repos/supabase/postgrest-rs/milestones{/number}", + "notifications_url": "https://api.github.com/repos/supabase/postgrest-rs/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/supabase/postgrest-rs/labels{/name}", + "releases_url": "https://api.github.com/repos/supabase/postgrest-rs/releases{/id}", + "deployments_url": "https://api.github.com/repos/supabase/postgrest-rs/deployments", + "created_at": "2020-05-14T02:19:41Z", + "updated_at": "2020-06-23T09:29:03Z", + "pushed_at": "2020-06-10T14:01:27Z", + "git_url": "git://github.com/supabase/postgrest-rs.git", + "ssh_url": "git@github.com:supabase/postgrest-rs.git", + "clone_url": "https://github.com/supabase/postgrest-rs.git", + "svn_url": "https://github.com/supabase/postgrest-rs", + "homepage": "https://supabase.com", + "size": 49, + "stargazers_count": 28, + "watchers_count": 28, + "language": "Rust", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "forks_count": 1, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 1, + "license": { + "key": "other", + "name": "Other", + "spdx_id": "NOASSERTION", + "url": null, + "node_id": "MDc6TGljZW5zZTA=" + }, + "forks": 1, + "open_issues": 1, + "watchers": 28, + "default_branch": "master", + "temp_clone_token": null, + "organization": { + "login": "supabase", + "id": 54469796, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0NDY5Nzk2", + "avatar_url": "https://avatars3.githubusercontent.com/u/54469796?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/supabase", + "html_url": "https://github.com/supabase", + "followers_url": "https://api.github.com/users/supabase/followers", + "following_url": "https://api.github.com/users/supabase/following{/other_user}", + "gists_url": "https://api.github.com/users/supabase/gists{/gist_id}", + "starred_url": "https://api.github.com/users/supabase/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/supabase/subscriptions", + "organizations_url": "https://api.github.com/users/supabase/orgs", + "repos_url": "https://api.github.com/users/supabase/repos", + "events_url": "https://api.github.com/users/supabase/events{/privacy}", + "received_events_url": "https://api.github.com/users/supabase/received_events", + "type": "Organization", + "site_admin": false + }, + "network_count": 1, + "subscribers_count": 4 +} diff --git a/apps/temp-docs/data/repos/realtime-js.json b/apps/temp-docs/data/repos/realtime-js.json new file mode 100644 index 00000000000..a961160c4bc --- /dev/null +++ b/apps/temp-docs/data/repos/realtime-js.json @@ -0,0 +1,123 @@ +{ + "id": 264389263, + "node_id": "MDEwOlJlcG9zaXRvcnkyNjQzODkyNjM=", + "name": "realtime-js", + "full_name": "supabase/realtime-js", + "private": false, + "owner": { + "login": "supabase", + "id": 54469796, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0NDY5Nzk2", + "avatar_url": "https://avatars3.githubusercontent.com/u/54469796?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/supabase", + "html_url": "https://github.com/supabase", + "followers_url": "https://api.github.com/users/supabase/followers", + "following_url": "https://api.github.com/users/supabase/following{/other_user}", + "gists_url": "https://api.github.com/users/supabase/gists{/gist_id}", + "starred_url": "https://api.github.com/users/supabase/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/supabase/subscriptions", + "organizations_url": "https://api.github.com/users/supabase/orgs", + "repos_url": "https://api.github.com/users/supabase/repos", + "events_url": "https://api.github.com/users/supabase/events{/privacy}", + "received_events_url": "https://api.github.com/users/supabase/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/supabase/realtime-js", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/supabase/realtime-js", + "forks_url": "https://api.github.com/repos/supabase/realtime-js/forks", + "keys_url": "https://api.github.com/repos/supabase/realtime-js/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/supabase/realtime-js/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/supabase/realtime-js/teams", + "hooks_url": "https://api.github.com/repos/supabase/realtime-js/hooks", + "issue_events_url": "https://api.github.com/repos/supabase/realtime-js/issues/events{/number}", + "events_url": "https://api.github.com/repos/supabase/realtime-js/events", + "assignees_url": "https://api.github.com/repos/supabase/realtime-js/assignees{/user}", + "branches_url": "https://api.github.com/repos/supabase/realtime-js/branches{/branch}", + "tags_url": "https://api.github.com/repos/supabase/realtime-js/tags", + "blobs_url": "https://api.github.com/repos/supabase/realtime-js/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/supabase/realtime-js/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/supabase/realtime-js/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/supabase/realtime-js/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/supabase/realtime-js/statuses/{sha}", + "languages_url": "https://api.github.com/repos/supabase/realtime-js/languages", + "stargazers_url": "https://api.github.com/repos/supabase/realtime-js/stargazers", + "contributors_url": "https://api.github.com/repos/supabase/realtime-js/contributors", + "subscribers_url": "https://api.github.com/repos/supabase/realtime-js/subscribers", + "subscription_url": "https://api.github.com/repos/supabase/realtime-js/subscription", + "commits_url": "https://api.github.com/repos/supabase/realtime-js/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/supabase/realtime-js/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/supabase/realtime-js/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/supabase/realtime-js/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/supabase/realtime-js/contents/{+path}", + "compare_url": "https://api.github.com/repos/supabase/realtime-js/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/supabase/realtime-js/merges", + "archive_url": "https://api.github.com/repos/supabase/realtime-js/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/supabase/realtime-js/downloads", + "issues_url": "https://api.github.com/repos/supabase/realtime-js/issues{/number}", + "pulls_url": "https://api.github.com/repos/supabase/realtime-js/pulls{/number}", + "milestones_url": "https://api.github.com/repos/supabase/realtime-js/milestones{/number}", + "notifications_url": "https://api.github.com/repos/supabase/realtime-js/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/supabase/realtime-js/labels{/name}", + "releases_url": "https://api.github.com/repos/supabase/realtime-js/releases{/id}", + "deployments_url": "https://api.github.com/repos/supabase/realtime-js/deployments", + "created_at": "2020-05-16T08:08:00Z", + "updated_at": "2020-06-23T08:51:03Z", + "pushed_at": "2020-06-23T08:51:04Z", + "git_url": "git://github.com/supabase/realtime-js.git", + "ssh_url": "git@github.com:supabase/realtime-js.git", + "clone_url": "https://github.com/supabase/realtime-js.git", + "svn_url": "https://github.com/supabase/realtime-js", + "homepage": null, + "size": 936, + "stargazers_count": 5, + "watchers_count": 5, + "language": "JavaScript", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "forks_count": 1, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 1, + "license": { + "key": "mit", + "name": "MIT License", + "spdx_id": "MIT", + "url": "https://api.github.com/licenses/mit", + "node_id": "MDc6TGljZW5zZTEz" + }, + "forks": 1, + "open_issues": 1, + "watchers": 5, + "default_branch": "master", + "temp_clone_token": null, + "organization": { + "login": "supabase", + "id": 54469796, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0NDY5Nzk2", + "avatar_url": "https://avatars3.githubusercontent.com/u/54469796?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/supabase", + "html_url": "https://github.com/supabase", + "followers_url": "https://api.github.com/users/supabase/followers", + "following_url": "https://api.github.com/users/supabase/following{/other_user}", + "gists_url": "https://api.github.com/users/supabase/gists{/gist_id}", + "starred_url": "https://api.github.com/users/supabase/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/supabase/subscriptions", + "organizations_url": "https://api.github.com/users/supabase/orgs", + "repos_url": "https://api.github.com/users/supabase/repos", + "events_url": "https://api.github.com/users/supabase/events{/privacy}", + "received_events_url": "https://api.github.com/users/supabase/received_events", + "type": "Organization", + "site_admin": false + }, + "network_count": 1, + "subscribers_count": 2 +} diff --git a/apps/temp-docs/data/repos/realtime.json b/apps/temp-docs/data/repos/realtime.json new file mode 100644 index 00000000000..7b356105892 --- /dev/null +++ b/apps/temp-docs/data/repos/realtime.json @@ -0,0 +1,123 @@ +{ + "id": 210347143, + "node_id": "MDEwOlJlcG9zaXRvcnkyMTAzNDcxNDM=", + "name": "realtime", + "full_name": "supabase/realtime", + "private": false, + "owner": { + "login": "supabase", + "id": 54469796, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0NDY5Nzk2", + "avatar_url": "https://avatars3.githubusercontent.com/u/54469796?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/supabase", + "html_url": "https://github.com/supabase", + "followers_url": "https://api.github.com/users/supabase/followers", + "following_url": "https://api.github.com/users/supabase/following{/other_user}", + "gists_url": "https://api.github.com/users/supabase/gists{/gist_id}", + "starred_url": "https://api.github.com/users/supabase/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/supabase/subscriptions", + "organizations_url": "https://api.github.com/users/supabase/orgs", + "repos_url": "https://api.github.com/users/supabase/repos", + "events_url": "https://api.github.com/users/supabase/events{/privacy}", + "received_events_url": "https://api.github.com/users/supabase/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/supabase/realtime", + "description": "Listen to your to PostgreSQL database in realtime via websockets. Built with Elixir.", + "fork": false, + "url": "https://api.github.com/repos/supabase/realtime", + "forks_url": "https://api.github.com/repos/supabase/realtime/forks", + "keys_url": "https://api.github.com/repos/supabase/realtime/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/supabase/realtime/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/supabase/realtime/teams", + "hooks_url": "https://api.github.com/repos/supabase/realtime/hooks", + "issue_events_url": "https://api.github.com/repos/supabase/realtime/issues/events{/number}", + "events_url": "https://api.github.com/repos/supabase/realtime/events", + "assignees_url": "https://api.github.com/repos/supabase/realtime/assignees{/user}", + "branches_url": "https://api.github.com/repos/supabase/realtime/branches{/branch}", + "tags_url": "https://api.github.com/repos/supabase/realtime/tags", + "blobs_url": "https://api.github.com/repos/supabase/realtime/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/supabase/realtime/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/supabase/realtime/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/supabase/realtime/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/supabase/realtime/statuses/{sha}", + "languages_url": "https://api.github.com/repos/supabase/realtime/languages", + "stargazers_url": "https://api.github.com/repos/supabase/realtime/stargazers", + "contributors_url": "https://api.github.com/repos/supabase/realtime/contributors", + "subscribers_url": "https://api.github.com/repos/supabase/realtime/subscribers", + "subscription_url": "https://api.github.com/repos/supabase/realtime/subscription", + "commits_url": "https://api.github.com/repos/supabase/realtime/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/supabase/realtime/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/supabase/realtime/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/supabase/realtime/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/supabase/realtime/contents/{+path}", + "compare_url": "https://api.github.com/repos/supabase/realtime/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/supabase/realtime/merges", + "archive_url": "https://api.github.com/repos/supabase/realtime/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/supabase/realtime/downloads", + "issues_url": "https://api.github.com/repos/supabase/realtime/issues{/number}", + "pulls_url": "https://api.github.com/repos/supabase/realtime/pulls{/number}", + "milestones_url": "https://api.github.com/repos/supabase/realtime/milestones{/number}", + "notifications_url": "https://api.github.com/repos/supabase/realtime/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/supabase/realtime/labels{/name}", + "releases_url": "https://api.github.com/repos/supabase/realtime/releases{/id}", + "deployments_url": "https://api.github.com/repos/supabase/realtime/deployments", + "created_at": "2019-09-23T12:15:45Z", + "updated_at": "2020-10-31T18:41:16Z", + "pushed_at": "2020-09-14T14:38:34Z", + "git_url": "git://github.com/supabase/realtime.git", + "ssh_url": "git@github.com:supabase/realtime.git", + "clone_url": "https://github.com/supabase/realtime.git", + "svn_url": "https://github.com/supabase/realtime", + "homepage": "https://supabase.com", + "size": 2322, + "stargazers_count": 1804, + "watchers_count": 1804, + "language": "Elixir", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "forks_count": 75, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 9, + "license": { + "key": "apache-2.0", + "name": "Apache License 2.0", + "spdx_id": "Apache-2.0", + "url": "https://api.github.com/licenses/apache-2.0", + "node_id": "MDc6TGljZW5zZTI=" + }, + "forks": 75, + "open_issues": 9, + "watchers": 1804, + "default_branch": "master", + "temp_clone_token": null, + "organization": { + "login": "supabase", + "id": 54469796, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0NDY5Nzk2", + "avatar_url": "https://avatars3.githubusercontent.com/u/54469796?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/supabase", + "html_url": "https://github.com/supabase", + "followers_url": "https://api.github.com/users/supabase/followers", + "following_url": "https://api.github.com/users/supabase/following{/other_user}", + "gists_url": "https://api.github.com/users/supabase/gists{/gist_id}", + "starred_url": "https://api.github.com/users/supabase/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/supabase/subscriptions", + "organizations_url": "https://api.github.com/users/supabase/orgs", + "repos_url": "https://api.github.com/users/supabase/repos", + "events_url": "https://api.github.com/users/supabase/events{/privacy}", + "received_events_url": "https://api.github.com/users/supabase/received_events", + "type": "Organization", + "site_admin": false + }, + "network_count": 75, + "subscribers_count": 53 +} diff --git a/apps/temp-docs/data/repos/schemas.json b/apps/temp-docs/data/repos/schemas.json new file mode 100644 index 00000000000..ad700b16090 --- /dev/null +++ b/apps/temp-docs/data/repos/schemas.json @@ -0,0 +1,5 @@ +{ + "message": "Moved Permanently", + "url": "https://api.github.com/repositories/231560476", + "documentation_url": "https://developer.github.com/v3/#http-redirects" +} diff --git a/apps/temp-docs/data/repos/supabase-js.json b/apps/temp-docs/data/repos/supabase-js.json new file mode 100644 index 00000000000..319b839f8d7 --- /dev/null +++ b/apps/temp-docs/data/repos/supabase-js.json @@ -0,0 +1,123 @@ +{ + "id": 264192686, + "node_id": "MDEwOlJlcG9zaXRvcnkyNjQxOTI2ODY=", + "name": "supabase-js", + "full_name": "supabase/supabase-js", + "private": false, + "owner": { + "login": "supabase", + "id": 54469796, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0NDY5Nzk2", + "avatar_url": "https://avatars3.githubusercontent.com/u/54469796?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/supabase", + "html_url": "https://github.com/supabase", + "followers_url": "https://api.github.com/users/supabase/followers", + "following_url": "https://api.github.com/users/supabase/following{/other_user}", + "gists_url": "https://api.github.com/users/supabase/gists{/gist_id}", + "starred_url": "https://api.github.com/users/supabase/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/supabase/subscriptions", + "organizations_url": "https://api.github.com/users/supabase/orgs", + "repos_url": "https://api.github.com/users/supabase/repos", + "events_url": "https://api.github.com/users/supabase/events{/privacy}", + "received_events_url": "https://api.github.com/users/supabase/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/supabase/supabase-js", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/supabase/supabase-js", + "forks_url": "https://api.github.com/repos/supabase/supabase-js/forks", + "keys_url": "https://api.github.com/repos/supabase/supabase-js/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/supabase/supabase-js/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/supabase/supabase-js/teams", + "hooks_url": "https://api.github.com/repos/supabase/supabase-js/hooks", + "issue_events_url": "https://api.github.com/repos/supabase/supabase-js/issues/events{/number}", + "events_url": "https://api.github.com/repos/supabase/supabase-js/events", + "assignees_url": "https://api.github.com/repos/supabase/supabase-js/assignees{/user}", + "branches_url": "https://api.github.com/repos/supabase/supabase-js/branches{/branch}", + "tags_url": "https://api.github.com/repos/supabase/supabase-js/tags", + "blobs_url": "https://api.github.com/repos/supabase/supabase-js/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/supabase/supabase-js/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/supabase/supabase-js/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/supabase/supabase-js/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/supabase/supabase-js/statuses/{sha}", + "languages_url": "https://api.github.com/repos/supabase/supabase-js/languages", + "stargazers_url": "https://api.github.com/repos/supabase/supabase-js/stargazers", + "contributors_url": "https://api.github.com/repos/supabase/supabase-js/contributors", + "subscribers_url": "https://api.github.com/repos/supabase/supabase-js/subscribers", + "subscription_url": "https://api.github.com/repos/supabase/supabase-js/subscription", + "commits_url": "https://api.github.com/repos/supabase/supabase-js/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/supabase/supabase-js/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/supabase/supabase-js/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/supabase/supabase-js/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/supabase/supabase-js/contents/{+path}", + "compare_url": "https://api.github.com/repos/supabase/supabase-js/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/supabase/supabase-js/merges", + "archive_url": "https://api.github.com/repos/supabase/supabase-js/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/supabase/supabase-js/downloads", + "issues_url": "https://api.github.com/repos/supabase/supabase-js/issues{/number}", + "pulls_url": "https://api.github.com/repos/supabase/supabase-js/pulls{/number}", + "milestones_url": "https://api.github.com/repos/supabase/supabase-js/milestones{/number}", + "notifications_url": "https://api.github.com/repos/supabase/supabase-js/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/supabase/supabase-js/labels{/name}", + "releases_url": "https://api.github.com/repos/supabase/supabase-js/releases{/id}", + "deployments_url": "https://api.github.com/repos/supabase/supabase-js/deployments", + "created_at": "2020-05-15T12:52:16Z", + "updated_at": "2020-06-11T08:30:37Z", + "pushed_at": "2020-06-12T14:52:51Z", + "git_url": "git://github.com/supabase/supabase-js.git", + "ssh_url": "git@github.com:supabase/supabase-js.git", + "clone_url": "https://github.com/supabase/supabase-js.git", + "svn_url": "https://github.com/supabase/supabase-js", + "homepage": null, + "size": 15, + "stargazers_count": 7, + "watchers_count": 7, + "language": "JavaScript", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "forks_count": 1, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 0, + "license": { + "key": "mit", + "name": "MIT License", + "spdx_id": "MIT", + "url": "https://api.github.com/licenses/mit", + "node_id": "MDc6TGljZW5zZTEz" + }, + "forks": 1, + "open_issues": 0, + "watchers": 7, + "default_branch": "master", + "temp_clone_token": null, + "organization": { + "login": "supabase", + "id": 54469796, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0NDY5Nzk2", + "avatar_url": "https://avatars3.githubusercontent.com/u/54469796?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/supabase", + "html_url": "https://github.com/supabase", + "followers_url": "https://api.github.com/users/supabase/followers", + "following_url": "https://api.github.com/users/supabase/following{/other_user}", + "gists_url": "https://api.github.com/users/supabase/gists{/gist_id}", + "starred_url": "https://api.github.com/users/supabase/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/supabase/subscriptions", + "organizations_url": "https://api.github.com/users/supabase/orgs", + "repos_url": "https://api.github.com/users/supabase/repos", + "events_url": "https://api.github.com/users/supabase/events{/privacy}", + "received_events_url": "https://api.github.com/users/supabase/received_events", + "type": "Organization", + "site_admin": false + }, + "network_count": 1, + "subscribers_count": 0 +} diff --git a/apps/temp-docs/data/repos/supabase.json b/apps/temp-docs/data/repos/supabase.json new file mode 100644 index 00000000000..fed023886f7 --- /dev/null +++ b/apps/temp-docs/data/repos/supabase.json @@ -0,0 +1,123 @@ +{ + "id": 214587193, + "node_id": "MDEwOlJlcG9zaXRvcnkyMTQ1ODcxOTM=", + "name": "supabase", + "full_name": "supabase/supabase", + "private": false, + "owner": { + "login": "supabase", + "id": 54469796, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0NDY5Nzk2", + "avatar_url": "https://avatars3.githubusercontent.com/u/54469796?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/supabase", + "html_url": "https://github.com/supabase", + "followers_url": "https://api.github.com/users/supabase/followers", + "following_url": "https://api.github.com/users/supabase/following{/other_user}", + "gists_url": "https://api.github.com/users/supabase/gists{/gist_id}", + "starred_url": "https://api.github.com/users/supabase/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/supabase/subscriptions", + "organizations_url": "https://api.github.com/users/supabase/orgs", + "repos_url": "https://api.github.com/users/supabase/repos", + "events_url": "https://api.github.com/users/supabase/events{/privacy}", + "received_events_url": "https://api.github.com/users/supabase/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/supabase/supabase", + "description": "Website, docs, and client libraries. Follow to stay updated about our public Beta.", + "fork": false, + "url": "https://api.github.com/repos/supabase/supabase", + "forks_url": "https://api.github.com/repos/supabase/supabase/forks", + "keys_url": "https://api.github.com/repos/supabase/supabase/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/supabase/supabase/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/supabase/supabase/teams", + "hooks_url": "https://api.github.com/repos/supabase/supabase/hooks", + "issue_events_url": "https://api.github.com/repos/supabase/supabase/issues/events{/number}", + "events_url": "https://api.github.com/repos/supabase/supabase/events", + "assignees_url": "https://api.github.com/repos/supabase/supabase/assignees{/user}", + "branches_url": "https://api.github.com/repos/supabase/supabase/branches{/branch}", + "tags_url": "https://api.github.com/repos/supabase/supabase/tags", + "blobs_url": "https://api.github.com/repos/supabase/supabase/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/supabase/supabase/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/supabase/supabase/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/supabase/supabase/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/supabase/supabase/statuses/{sha}", + "languages_url": "https://api.github.com/repos/supabase/supabase/languages", + "stargazers_url": "https://api.github.com/repos/supabase/supabase/stargazers", + "contributors_url": "https://api.github.com/repos/supabase/supabase/contributors", + "subscribers_url": "https://api.github.com/repos/supabase/supabase/subscribers", + "subscription_url": "https://api.github.com/repos/supabase/supabase/subscription", + "commits_url": "https://api.github.com/repos/supabase/supabase/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/supabase/supabase/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/supabase/supabase/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/supabase/supabase/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/supabase/supabase/contents/{+path}", + "compare_url": "https://api.github.com/repos/supabase/supabase/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/supabase/supabase/merges", + "archive_url": "https://api.github.com/repos/supabase/supabase/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/supabase/supabase/downloads", + "issues_url": "https://api.github.com/repos/supabase/supabase/issues{/number}", + "pulls_url": "https://api.github.com/repos/supabase/supabase/pulls{/number}", + "milestones_url": "https://api.github.com/repos/supabase/supabase/milestones{/number}", + "notifications_url": "https://api.github.com/repos/supabase/supabase/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/supabase/supabase/labels{/name}", + "releases_url": "https://api.github.com/repos/supabase/supabase/releases{/id}", + "deployments_url": "https://api.github.com/repos/supabase/supabase/deployments", + "created_at": "2019-10-12T05:56:49Z", + "updated_at": "2020-11-01T18:31:33Z", + "pushed_at": "2020-10-30T20:22:07Z", + "git_url": "git://github.com/supabase/supabase.git", + "ssh_url": "git@github.com:supabase/supabase.git", + "clone_url": "https://github.com/supabase/supabase.git", + "svn_url": "https://github.com/supabase/supabase", + "homepage": "https://supabase.com", + "size": 31094, + "stargazers_count": 2551, + "watchers_count": 2551, + "language": "JavaScript", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "forks_count": 101, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 30, + "license": { + "key": "apache-2.0", + "name": "Apache License 2.0", + "spdx_id": "Apache-2.0", + "url": "https://api.github.com/licenses/apache-2.0", + "node_id": "MDc6TGljZW5zZTI=" + }, + "forks": 101, + "open_issues": 30, + "watchers": 2551, + "default_branch": "master", + "temp_clone_token": null, + "organization": { + "login": "supabase", + "id": 54469796, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0NDY5Nzk2", + "avatar_url": "https://avatars3.githubusercontent.com/u/54469796?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/supabase", + "html_url": "https://github.com/supabase", + "followers_url": "https://api.github.com/users/supabase/followers", + "following_url": "https://api.github.com/users/supabase/following{/other_user}", + "gists_url": "https://api.github.com/users/supabase/gists{/gist_id}", + "starred_url": "https://api.github.com/users/supabase/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/supabase/subscriptions", + "organizations_url": "https://api.github.com/users/supabase/orgs", + "repos_url": "https://api.github.com/users/supabase/repos", + "events_url": "https://api.github.com/users/supabase/events{/privacy}", + "received_events_url": "https://api.github.com/users/supabase/received_events", + "type": "Organization", + "site_admin": false + }, + "network_count": 101, + "subscribers_count": 91 +} diff --git a/apps/temp-docs/data/showcase.json b/apps/temp-docs/data/showcase.json new file mode 100644 index 00000000000..fe51488c706 --- /dev/null +++ b/apps/temp-docs/data/showcase.json @@ -0,0 +1 @@ +[] diff --git a/apps/temp-docs/data/sponsors.json b/apps/temp-docs/data/sponsors.json new file mode 100644 index 00000000000..a456b2121d9 --- /dev/null +++ b/apps/temp-docs/data/sponsors.json @@ -0,0 +1,202 @@ +[ + { + "tier": "$5 a month", + "sponsor": "sabberworm" + }, + { + "tier": "$5 a month", + "sponsor": "calendee" + }, + { + "tier": "$5 a month", + "sponsor": "kylewelsby" + }, + { + "tier": "$5 a month", + "sponsor": "tinjaw" + }, + { + "tier": "$5 a month", + "sponsor": "ricdex" + }, + { + "tier": "$49 a month", + "sponsor": "Illyism" + }, + { + "tier": "$5 a month", + "sponsor": "lexifdev" + }, + { + "tier": "$5 a month", + "sponsor": "tacowaco" + }, + { + "tier": "$5 a month", + "sponsor": "kachar" + }, + { + "tier": "$19 a month", + "sponsor": "tpberntsen" + }, + { + "tier": "$5 a month", + "sponsor": "zeluizr" + }, + { + "tier": "$5 a month", + "sponsor": "AndersGerner" + }, + { + "tier": "$5 a month", + "sponsor": "stopyellingatme" + }, + { + "tier": "$19 a month", + "sponsor": "Marviel" + }, + { + "tier": "$19 a month", + "sponsor": "bookofdom" + }, + { + "tier": "$5 a month", + "sponsor": "juzhiyuan" + }, + { + "tier": "$5 a month", + "sponsor": "gregaltuna" + }, + { + "tier": "$5 a month", + "sponsor": "ctwhome" + }, + { + "tier": "$5 a month", + "sponsor": "alienzz" + }, + { + "tier": "$5 a month", + "sponsor": "zlwaterfield" + }, + { + "tier": "$5 a month", + "sponsor": "Aaron-A" + }, + { + "tier": "$5 a month", + "sponsor": "gabrielmip" + }, + { + "tier": "$5 a month", + "sponsor": "glassmonkey" + }, + { + "tier": "$5 a month", + "sponsor": "zoutiyx" + }, + { + "tier": "$5 a month", + "sponsor": "adammoyle" + }, + { + "tier": "$5 a month", + "sponsor": "EvonuX" + }, + { + "tier": "$5 a month", + "sponsor": "KoreyPeters" + }, + { + "tier": "$49 a month", + "sponsor": "ymmtshny" + }, + { + "tier": "$19 a month", + "sponsor": "fefurst" + }, + { + "tier": "$5 a month", + "sponsor": "sebastianbachmann" + }, + { + "tier": "$5 a month", + "sponsor": "jvieirar" + }, + { + "tier": "$19 a month", + "sponsor": "dshukertjr" + }, + { + "tier": "$5 a month", + "sponsor": "CmplxStack" + }, + { + "tier": "$19 a month", + "sponsor": "roblack" + }, + { + "tier": "$5 a month", + "sponsor": "davilico05" + }, + { + "tier": "$19 a month", + "sponsor": "Kunstderfug" + }, + { + "tier": "$5 a month", + "sponsor": "hyochan" + }, + { + "tier": "$5 a month", + "sponsor": "chunterb" + }, + { + "tier": "$5 a month", + "sponsor": "madebyfabian" + }, + { + "tier": "$5 a month", + "sponsor": "jwanner83" + }, + { + "tier": "$5 a month", + "sponsor": "herbievine" + }, + { + "tier": "$5 a month", + "sponsor": "Lucostus" + }, + { + "tier": "$19 a month", + "sponsor": "peachp" + }, + { + "tier": "$5 a month", + "sponsor": "killshot13" + }, + { + "tier": "$19 a month", + "sponsor": "d-mok" + }, + { + "tier": "$19 a month", + "sponsor": "lIIIIIIIIIIIIIIIIIIIII" + }, + { + "tier": "$5 a month", + "sponsor": "yujong-lee" + }, + { + "tier": "$5 a month", + "sponsor": "gregdenson" + }, + { + "tier": "$5 a month", + "sponsor": "LeDragunov" + }, + { + "tier": "$49 a month", + "sponsor": "CryptoJobsList" + } +] \ No newline at end of file diff --git a/apps/temp-docs/data/stars/stargazers.json b/apps/temp-docs/data/stars/stargazers.json new file mode 100644 index 00000000000..a9336259f17 --- /dev/null +++ b/apps/temp-docs/data/stars/stargazers.json @@ -0,0 +1,2562 @@ +[ + { + "name": "2019-10-15", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 0, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 0, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 0, + "realtime-js": 0, + "supabase": 1, + "supabase-js": 0 + }, + { + "name": "2019-10-25", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 0, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 0, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 33, + "realtime-js": 0, + "supabase": 1, + "supabase-js": 0 + }, + { + "name": "2019-10-26", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 0, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 0, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 41, + "realtime-js": 0, + "supabase": 1, + "supabase-js": 0 + }, + { + "name": "2019-10-27", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 0, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 0, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 46, + "realtime-js": 0, + "supabase": 1, + "supabase-js": 0 + }, + { + "name": "2019-10-28", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 0, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 0, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 51, + "realtime-js": 0, + "supabase": 1, + "supabase-js": 0 + }, + { + "name": "2019-10-29", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 0, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 0, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 52, + "realtime-js": 0, + "supabase": 1, + "supabase-js": 0 + }, + { + "name": "2019-10-30", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 0, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 0, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 53, + "realtime-js": 0, + "supabase": 1, + "supabase-js": 0 + }, + { + "name": "2019-10-31", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 0, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 0, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 54, + "realtime-js": 0, + "supabase": 1, + "supabase-js": 0 + }, + { + "name": "2019-11-03", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 0, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 0, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 55, + "realtime-js": 0, + "supabase": 1, + "supabase-js": 0 + }, + { + "name": "2019-11-09", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 0, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 0, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 58, + "realtime-js": 0, + "supabase": 1, + "supabase-js": 0 + }, + { + "name": "2019-11-10", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 0, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 0, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 59, + "realtime-js": 0, + "supabase": 1, + "supabase-js": 0 + }, + { + "name": "2019-11-11", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 0, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 0, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 60, + "realtime-js": 0, + "supabase": 1, + "supabase-js": 0 + }, + { + "name": "2019-11-21", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 0, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 0, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 61, + "realtime-js": 0, + "supabase": 1, + "supabase-js": 0 + }, + { + "name": "2019-11-23", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 0, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 0, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 62, + "realtime-js": 0, + "supabase": 1, + "supabase-js": 0 + }, + { + "name": "2019-12-10", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 0, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 0, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 63, + "realtime-js": 0, + "supabase": 1, + "supabase-js": 0 + }, + { + "name": "2019-12-13", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 0, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 0, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 64, + "realtime-js": 0, + "supabase": 1, + "supabase-js": 0 + }, + { + "name": "2019-12-17", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 0, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 0, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 157, + "realtime-js": 0, + "supabase": 1, + "supabase-js": 0 + }, + { + "name": "2019-12-18", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 0, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 0, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 171, + "realtime-js": 0, + "supabase": 1, + "supabase-js": 0 + }, + { + "name": "2019-12-19", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 0, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 0, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 174, + "realtime-js": 0, + "supabase": 1, + "supabase-js": 0 + }, + { + "name": "2019-12-20", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 0, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 0, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 177, + "realtime-js": 0, + "supabase": 1, + "supabase-js": 0 + }, + { + "name": "2019-12-21", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 0, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 0, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 179, + "realtime-js": 0, + "supabase": 1, + "supabase-js": 0 + }, + { + "name": "2019-12-23", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 0, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 0, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 180, + "realtime-js": 0, + "supabase": 1, + "supabase-js": 0 + }, + { + "name": "2019-12-29", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 0, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 0, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 181, + "realtime-js": 0, + "supabase": 1, + "supabase-js": 0 + }, + { + "name": "2020-01-07", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 0, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 0, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 182, + "realtime-js": 0, + "supabase": 1, + "supabase-js": 0 + }, + { + "name": "2020-01-11", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 0, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 0, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 183, + "realtime-js": 0, + "supabase": 1, + "supabase-js": 0 + }, + { + "name": "2020-01-14", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 0, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 0, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 184, + "realtime-js": 0, + "supabase": 1, + "supabase-js": 0 + }, + { + "name": "2020-01-15", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 0, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 0, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 184, + "realtime-js": 0, + "supabase": 2, + "supabase-js": 0 + }, + { + "name": "2020-01-16", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 2, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 0, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 193, + "realtime-js": 0, + "supabase": 16, + "supabase-js": 0 + }, + { + "name": "2020-01-17", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 2, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 0, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 194, + "realtime-js": 0, + "supabase": 17, + "supabase-js": 0 + }, + { + "name": "2020-01-18", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 2, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 0, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 195, + "realtime-js": 0, + "supabase": 19, + "supabase-js": 0 + }, + { + "name": "2020-01-19", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 2, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 0, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 195, + "realtime-js": 0, + "supabase": 20, + "supabase-js": 0 + }, + { + "name": "2020-01-20", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 2, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 0, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 196, + "realtime-js": 0, + "supabase": 21, + "supabase-js": 0 + }, + { + "name": "2020-01-21", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 2, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 0, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 201, + "realtime-js": 0, + "supabase": 28, + "supabase-js": 0 + }, + { + "name": "2020-01-22", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 2, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 0, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 272, + "realtime-js": 0, + "supabase": 45, + "supabase-js": 0 + }, + { + "name": "2020-01-23", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 4, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 0, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 301, + "realtime-js": 0, + "supabase": 55, + "supabase-js": 0 + }, + { + "name": "2020-01-24", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 4, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 0, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 321, + "realtime-js": 0, + "supabase": 57, + "supabase-js": 0 + }, + { + "name": "2020-01-25", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 4, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 0, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 325, + "realtime-js": 0, + "supabase": 59, + "supabase-js": 0 + }, + { + "name": "2020-01-26", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 4, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 0, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 328, + "realtime-js": 0, + "supabase": 59, + "supabase-js": 0 + }, + { + "name": "2020-01-27", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 5, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 0, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 331, + "realtime-js": 0, + "supabase": 60, + "supabase-js": 0 + }, + { + "name": "2020-01-28", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 5, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 0, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 334, + "realtime-js": 0, + "supabase": 62, + "supabase-js": 0 + }, + { + "name": "2020-01-29", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 5, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 1, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 342, + "realtime-js": 0, + "supabase": 62, + "supabase-js": 0 + }, + { + "name": "2020-01-30", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 5, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 2, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 346, + "realtime-js": 0, + "supabase": 63, + "supabase-js": 0 + }, + { + "name": "2020-01-31", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 5, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 2, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 350, + "realtime-js": 0, + "supabase": 65, + "supabase-js": 0 + }, + { + "name": "2020-02-01", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 5, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 2, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 351, + "realtime-js": 0, + "supabase": 67, + "supabase-js": 0 + }, + { + "name": "2020-02-02", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 7, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 353, + "realtime-js": 0, + "supabase": 70, + "supabase-js": 0 + }, + { + "name": "2020-02-03", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 19, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 354, + "realtime-js": 0, + "supabase": 72, + "supabase-js": 0 + }, + { + "name": "2020-02-04", + "doctest-js": 0, + "jsdoc-template": 0, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 22, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 354, + "realtime-js": 0, + "supabase": 72, + "supabase-js": 0 + }, + { + "name": "2020-02-05", + "doctest-js": 1, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 24, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 354, + "realtime-js": 0, + "supabase": 73, + "supabase-js": 0 + }, + { + "name": "2020-02-10", + "doctest-js": 1, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 25, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 354, + "realtime-js": 0, + "supabase": 73, + "supabase-js": 0 + }, + { + "name": "2020-02-11", + "doctest-js": 1, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 25, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 355, + "realtime-js": 0, + "supabase": 73, + "supabase-js": 0 + }, + { + "name": "2020-02-14", + "doctest-js": 1, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 25, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 356, + "realtime-js": 0, + "supabase": 73, + "supabase-js": 0 + }, + { + "name": "2020-02-16", + "doctest-js": 1, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 25, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 357, + "realtime-js": 0, + "supabase": 73, + "supabase-js": 0 + }, + { + "name": "2020-02-19", + "doctest-js": 1, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 25, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 364, + "realtime-js": 0, + "supabase": 73, + "supabase-js": 0 + }, + { + "name": "2020-02-20", + "doctest-js": 1, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 25, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 365, + "realtime-js": 0, + "supabase": 73, + "supabase-js": 0 + }, + { + "name": "2020-02-21", + "doctest-js": 1, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 25, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 366, + "realtime-js": 0, + "supabase": 73, + "supabase-js": 0 + }, + { + "name": "2020-02-22", + "doctest-js": 3, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 25, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 366, + "realtime-js": 0, + "supabase": 73, + "supabase-js": 0 + }, + { + "name": "2020-02-23", + "doctest-js": 10, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 25, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 367, + "realtime-js": 0, + "supabase": 73, + "supabase-js": 0 + }, + { + "name": "2020-02-24", + "doctest-js": 12, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 25, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 368, + "realtime-js": 0, + "supabase": 74, + "supabase-js": 0 + }, + { + "name": "2020-02-25", + "doctest-js": 15, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 25, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 369, + "realtime-js": 0, + "supabase": 74, + "supabase-js": 0 + }, + { + "name": "2020-02-26", + "doctest-js": 18, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 25, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 370, + "realtime-js": 0, + "supabase": 75, + "supabase-js": 0 + }, + { + "name": "2020-02-27", + "doctest-js": 18, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 25, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 371, + "realtime-js": 0, + "supabase": 75, + "supabase-js": 0 + }, + { + "name": "2020-02-28", + "doctest-js": 19, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 25, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 371, + "realtime-js": 0, + "supabase": 75, + "supabase-js": 0 + }, + { + "name": "2020-02-29", + "doctest-js": 19, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 25, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 371, + "realtime-js": 0, + "supabase": 76, + "supabase-js": 0 + }, + { + "name": "2020-03-02", + "doctest-js": 19, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 26, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 372, + "realtime-js": 0, + "supabase": 76, + "supabase-js": 0 + }, + { + "name": "2020-03-06", + "doctest-js": 19, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 26, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 373, + "realtime-js": 0, + "supabase": 77, + "supabase-js": 0 + }, + { + "name": "2020-03-07", + "doctest-js": 19, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 26, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 374, + "realtime-js": 0, + "supabase": 77, + "supabase-js": 0 + }, + { + "name": "2020-03-08", + "doctest-js": 20, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 26, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 374, + "realtime-js": 0, + "supabase": 77, + "supabase-js": 0 + }, + { + "name": "2020-03-09", + "doctest-js": 21, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 26, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 374, + "realtime-js": 0, + "supabase": 78, + "supabase-js": 0 + }, + { + "name": "2020-03-10", + "doctest-js": 21, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 26, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 375, + "realtime-js": 0, + "supabase": 78, + "supabase-js": 0 + }, + { + "name": "2020-03-11", + "doctest-js": 21, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 26, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 376, + "realtime-js": 0, + "supabase": 80, + "supabase-js": 0 + }, + { + "name": "2020-03-12", + "doctest-js": 21, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 26, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 376, + "realtime-js": 0, + "supabase": 81, + "supabase-js": 0 + }, + { + "name": "2020-03-13", + "doctest-js": 21, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 27, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 376, + "realtime-js": 0, + "supabase": 81, + "supabase-js": 0 + }, + { + "name": "2020-03-14", + "doctest-js": 22, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 27, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 377, + "realtime-js": 0, + "supabase": 81, + "supabase-js": 0 + }, + { + "name": "2020-03-15", + "doctest-js": 23, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 27, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 377, + "realtime-js": 0, + "supabase": 81, + "supabase-js": 0 + }, + { + "name": "2020-03-19", + "doctest-js": 23, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 27, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 379, + "realtime-js": 0, + "supabase": 82, + "supabase-js": 0 + }, + { + "name": "2020-03-21", + "doctest-js": 23, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 27, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 379, + "realtime-js": 0, + "supabase": 83, + "supabase-js": 0 + }, + { + "name": "2020-03-22", + "doctest-js": 27, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 28, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 382, + "realtime-js": 0, + "supabase": 83, + "supabase-js": 0 + }, + { + "name": "2020-03-24", + "doctest-js": 27, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 28, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 383, + "realtime-js": 0, + "supabase": 83, + "supabase-js": 0 + }, + { + "name": "2020-03-25", + "doctest-js": 28, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 28, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 384, + "realtime-js": 0, + "supabase": 83, + "supabase-js": 0 + }, + { + "name": "2020-03-26", + "doctest-js": 28, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 28, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 385, + "realtime-js": 0, + "supabase": 84, + "supabase-js": 0 + }, + { + "name": "2020-03-27", + "doctest-js": 28, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 28, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 386, + "realtime-js": 0, + "supabase": 84, + "supabase-js": 0 + }, + { + "name": "2020-03-29", + "doctest-js": 28, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 28, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 386, + "realtime-js": 0, + "supabase": 85, + "supabase-js": 0 + }, + { + "name": "2020-03-30", + "doctest-js": 28, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 28, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 387, + "realtime-js": 0, + "supabase": 85, + "supabase-js": 0 + }, + { + "name": "2020-03-31", + "doctest-js": 28, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 29, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 387, + "realtime-js": 0, + "supabase": 86, + "supabase-js": 0 + }, + { + "name": "2020-04-01", + "doctest-js": 28, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 30, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 388, + "realtime-js": 0, + "supabase": 86, + "supabase-js": 0 + }, + { + "name": "2020-04-04", + "doctest-js": 28, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 31, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 389, + "realtime-js": 0, + "supabase": 100, + "supabase-js": 0 + }, + { + "name": "2020-04-05", + "doctest-js": 28, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 31, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 391, + "realtime-js": 0, + "supabase": 109, + "supabase-js": 0 + }, + { + "name": "2020-04-06", + "doctest-js": 29, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 31, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 392, + "realtime-js": 0, + "supabase": 109, + "supabase-js": 0 + }, + { + "name": "2020-04-08", + "doctest-js": 29, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 31, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 392, + "realtime-js": 0, + "supabase": 110, + "supabase-js": 0 + }, + { + "name": "2020-04-10", + "doctest-js": 29, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 31, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 393, + "realtime-js": 0, + "supabase": 111, + "supabase-js": 0 + }, + { + "name": "2020-04-11", + "doctest-js": 30, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 31, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 393, + "realtime-js": 0, + "supabase": 111, + "supabase-js": 0 + }, + { + "name": "2020-04-12", + "doctest-js": 31, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 31, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 393, + "realtime-js": 0, + "supabase": 111, + "supabase-js": 0 + }, + { + "name": "2020-04-15", + "doctest-js": 31, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 31, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 396, + "realtime-js": 0, + "supabase": 141, + "supabase-js": 0 + }, + { + "name": "2020-04-16", + "doctest-js": 31, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 31, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 398, + "realtime-js": 0, + "supabase": 148, + "supabase-js": 0 + }, + { + "name": "2020-04-18", + "doctest-js": 31, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 31, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 398, + "realtime-js": 0, + "supabase": 149, + "supabase-js": 0 + }, + { + "name": "2020-04-19", + "doctest-js": 31, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 0, + "postgrest-js": 31, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 399, + "realtime-js": 0, + "supabase": 149, + "supabase-js": 0 + }, + { + "name": "2020-04-21", + "doctest-js": 31, + "jsdoc-template": 1, + "marketplace": 6, + "pg-api": 0, + "pg_listen": 0, + "postgres": 1, + "postgrest-js": 31, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 399, + "realtime-js": 0, + "supabase": 149, + "supabase-js": 0 + }, + { + "name": "2020-04-22", + "doctest-js": 32, + "jsdoc-template": 2, + "marketplace": 7, + "pg-api": 0, + "pg_listen": 0, + "postgres": 2, + "postgrest-js": 32, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 400, + "realtime-js": 0, + "supabase": 149, + "supabase-js": 0 + }, + { + "name": "2020-04-23", + "doctest-js": 32, + "jsdoc-template": 2, + "marketplace": 7, + "pg-api": 0, + "pg_listen": 0, + "postgres": 2, + "postgrest-js": 36, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 400, + "realtime-js": 0, + "supabase": 149, + "supabase-js": 0 + }, + { + "name": "2020-04-24", + "doctest-js": 32, + "jsdoc-template": 2, + "marketplace": 7, + "pg-api": 0, + "pg_listen": 0, + "postgres": 2, + "postgrest-js": 37, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 400, + "realtime-js": 0, + "supabase": 149, + "supabase-js": 0 + }, + { + "name": "2020-04-25", + "doctest-js": 32, + "jsdoc-template": 2, + "marketplace": 7, + "pg-api": 0, + "pg_listen": 0, + "postgres": 2, + "postgrest-js": 39, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 400, + "realtime-js": 0, + "supabase": 149, + "supabase-js": 0 + }, + { + "name": "2020-04-27", + "doctest-js": 32, + "jsdoc-template": 2, + "marketplace": 7, + "pg-api": 0, + "pg_listen": 0, + "postgres": 2, + "postgrest-js": 39, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 400, + "realtime-js": 0, + "supabase": 150, + "supabase-js": 0 + }, + { + "name": "2020-04-28", + "doctest-js": 32, + "jsdoc-template": 2, + "marketplace": 7, + "pg-api": 0, + "pg_listen": 0, + "postgres": 2, + "postgrest-js": 39, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 401, + "realtime-js": 0, + "supabase": 151, + "supabase-js": 0 + }, + { + "name": "2020-04-29", + "doctest-js": 33, + "jsdoc-template": 2, + "marketplace": 8, + "pg-api": 0, + "pg_listen": 0, + "postgres": 5, + "postgrest-js": 39, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 419, + "realtime-js": 0, + "supabase": 151, + "supabase-js": 0 + }, + { + "name": "2020-04-30", + "doctest-js": 33, + "jsdoc-template": 2, + "marketplace": 8, + "pg-api": 0, + "pg_listen": 0, + "postgres": 10, + "postgrest-js": 39, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 420, + "realtime-js": 0, + "supabase": 156, + "supabase-js": 0 + }, + { + "name": "2020-05-01", + "doctest-js": 33, + "jsdoc-template": 2, + "marketplace": 8, + "pg-api": 0, + "pg_listen": 0, + "postgres": 14, + "postgrest-js": 39, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 488, + "realtime-js": 0, + "supabase": 158, + "supabase-js": 0 + }, + { + "name": "2020-05-02", + "doctest-js": 33, + "jsdoc-template": 2, + "marketplace": 8, + "pg-api": 0, + "pg_listen": 0, + "postgres": 15, + "postgrest-js": 39, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 515, + "realtime-js": 0, + "supabase": 165, + "supabase-js": 0 + }, + { + "name": "2020-05-03", + "doctest-js": 33, + "jsdoc-template": 2, + "marketplace": 8, + "pg-api": 0, + "pg_listen": 0, + "postgres": 15, + "postgrest-js": 39, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 525, + "realtime-js": 0, + "supabase": 167, + "supabase-js": 0 + }, + { + "name": "2020-05-04", + "doctest-js": 33, + "jsdoc-template": 2, + "marketplace": 8, + "pg-api": 0, + "pg_listen": 0, + "postgres": 15, + "postgrest-js": 39, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 534, + "realtime-js": 0, + "supabase": 167, + "supabase-js": 0 + }, + { + "name": "2020-05-05", + "doctest-js": 33, + "jsdoc-template": 2, + "marketplace": 8, + "pg-api": 0, + "pg_listen": 0, + "postgres": 15, + "postgrest-js": 40, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 542, + "realtime-js": 0, + "supabase": 168, + "supabase-js": 0 + }, + { + "name": "2020-05-06", + "doctest-js": 33, + "jsdoc-template": 2, + "marketplace": 8, + "pg-api": 0, + "pg_listen": 0, + "postgres": 15, + "postgrest-js": 40, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 544, + "realtime-js": 0, + "supabase": 168, + "supabase-js": 0 + }, + { + "name": "2020-05-07", + "doctest-js": 34, + "jsdoc-template": 2, + "marketplace": 8, + "pg-api": 0, + "pg_listen": 0, + "postgres": 15, + "postgrest-js": 40, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 547, + "realtime-js": 0, + "supabase": 171, + "supabase-js": 0 + }, + { + "name": "2020-05-08", + "doctest-js": 34, + "jsdoc-template": 2, + "marketplace": 8, + "pg-api": 0, + "pg_listen": 0, + "postgres": 16, + "postgrest-js": 40, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 548, + "realtime-js": 0, + "supabase": 178, + "supabase-js": 0 + }, + { + "name": "2020-05-09", + "doctest-js": 34, + "jsdoc-template": 2, + "marketplace": 8, + "pg-api": 0, + "pg_listen": 0, + "postgres": 17, + "postgrest-js": 40, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 550, + "realtime-js": 0, + "supabase": 181, + "supabase-js": 0 + }, + { + "name": "2020-05-10", + "doctest-js": 34, + "jsdoc-template": 2, + "marketplace": 8, + "pg-api": 0, + "pg_listen": 0, + "postgres": 17, + "postgrest-js": 40, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 551, + "realtime-js": 0, + "supabase": 183, + "supabase-js": 0 + }, + { + "name": "2020-05-11", + "doctest-js": 34, + "jsdoc-template": 2, + "marketplace": 8, + "pg-api": 0, + "pg_listen": 0, + "postgres": 18, + "postgrest-js": 40, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 552, + "realtime-js": 0, + "supabase": 189, + "supabase-js": 0 + }, + { + "name": "2020-05-12", + "doctest-js": 34, + "jsdoc-template": 2, + "marketplace": 9, + "pg-api": 0, + "pg_listen": 0, + "postgres": 19, + "postgrest-js": 41, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 554, + "realtime-js": 0, + "supabase": 192, + "supabase-js": 0 + }, + { + "name": "2020-05-13", + "doctest-js": 34, + "jsdoc-template": 2, + "marketplace": 9, + "pg-api": 0, + "pg_listen": 0, + "postgres": 19, + "postgrest-js": 41, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 555, + "realtime-js": 0, + "supabase": 193, + "supabase-js": 0 + }, + { + "name": "2020-05-14", + "doctest-js": 34, + "jsdoc-template": 2, + "marketplace": 9, + "pg-api": 0, + "pg_listen": 0, + "postgres": 19, + "postgrest-js": 41, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 556, + "realtime-js": 0, + "supabase": 193, + "supabase-js": 0 + }, + { + "name": "2020-05-15", + "doctest-js": 34, + "jsdoc-template": 2, + "marketplace": 9, + "pg-api": 0, + "pg_listen": 0, + "postgres": 19, + "postgrest-js": 42, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 556, + "realtime-js": 0, + "supabase": 194, + "supabase-js": 0 + }, + { + "name": "2020-05-16", + "doctest-js": 34, + "jsdoc-template": 2, + "marketplace": 9, + "pg-api": 0, + "pg_listen": 0, + "postgres": 19, + "postgrest-js": 42, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 556, + "realtime-js": 0, + "supabase": 195, + "supabase-js": 0 + }, + { + "name": "2020-05-17", + "doctest-js": 34, + "jsdoc-template": 2, + "marketplace": 9, + "pg-api": 0, + "pg_listen": 0, + "postgres": 20, + "postgrest-js": 42, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 556, + "realtime-js": 1, + "supabase": 197, + "supabase-js": 0 + }, + { + "name": "2020-05-18", + "doctest-js": 34, + "jsdoc-template": 2, + "marketplace": 9, + "pg-api": 0, + "pg_listen": 0, + "postgres": 20, + "postgrest-js": 42, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 556, + "realtime-js": 1, + "supabase": 199, + "supabase-js": 0 + }, + { + "name": "2020-05-19", + "doctest-js": 34, + "jsdoc-template": 2, + "marketplace": 9, + "pg-api": 0, + "pg_listen": 0, + "postgres": 21, + "postgrest-js": 42, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 558, + "realtime-js": 1, + "supabase": 200, + "supabase-js": 0 + }, + { + "name": "2020-05-20", + "doctest-js": 36, + "jsdoc-template": 2, + "marketplace": 9, + "pg-api": 0, + "pg_listen": 0, + "postgres": 21, + "postgrest-js": 42, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 558, + "realtime-js": 1, + "supabase": 200, + "supabase-js": 0 + }, + { + "name": "2020-05-21", + "doctest-js": 36, + "jsdoc-template": 2, + "marketplace": 9, + "pg-api": 1, + "pg_listen": 0, + "postgres": 21, + "postgrest-js": 42, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 559, + "realtime-js": 1, + "supabase": 201, + "supabase-js": 0 + }, + { + "name": "2020-05-23", + "doctest-js": 36, + "jsdoc-template": 2, + "marketplace": 9, + "pg-api": 1, + "pg_listen": 0, + "postgres": 21, + "postgrest-js": 44, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 561, + "realtime-js": 1, + "supabase": 202, + "supabase-js": 0 + }, + { + "name": "2020-05-24", + "doctest-js": 36, + "jsdoc-template": 2, + "marketplace": 9, + "pg-api": 1, + "pg_listen": 0, + "postgres": 21, + "postgrest-js": 44, + "postgrest-py": 0, + "postgrest-rs": 0, + "realtime": 562, + "realtime-js": 1, + "supabase": 204, + "supabase-js": 0 + }, + { + "name": "2020-05-25", + "doctest-js": 36, + "jsdoc-template": 2, + "marketplace": 9, + "pg-api": 1, + "pg_listen": 0, + "postgres": 21, + "postgrest-js": 44, + "postgrest-py": 0, + "postgrest-rs": 1, + "realtime": 563, + "realtime-js": 1, + "supabase": 204, + "supabase-js": 0 + }, + { + "name": "2020-05-26", + "doctest-js": 36, + "jsdoc-template": 2, + "marketplace": 9, + "pg-api": 1, + "pg_listen": 0, + "postgres": 23, + "postgrest-js": 45, + "postgrest-py": 0, + "postgrest-rs": 1, + "realtime": 563, + "realtime-js": 1, + "supabase": 204, + "supabase-js": 0 + }, + { + "name": "2020-05-27", + "doctest-js": 36, + "jsdoc-template": 2, + "marketplace": 9, + "pg-api": 15, + "pg_listen": 0, + "postgres": 56, + "postgrest-js": 53, + "postgrest-py": 1, + "postgrest-rs": 5, + "realtime": 725, + "realtime-js": 1, + "supabase": 734, + "supabase-js": 2 + }, + { + "name": "2020-05-28", + "doctest-js": 37, + "jsdoc-template": 2, + "marketplace": 9, + "pg-api": 23, + "pg_listen": 0, + "postgres": 75, + "postgrest-js": 59, + "postgrest-py": 1, + "postgrest-rs": 5, + "realtime": 791, + "realtime-js": 3, + "supabase": 1027, + "supabase-js": 3 + }, + { + "name": "2020-05-29", + "doctest-js": 37, + "jsdoc-template": 2, + "marketplace": 9, + "pg-api": 24, + "pg_listen": 0, + "postgres": 80, + "postgrest-js": 59, + "postgrest-py": 1, + "postgrest-rs": 5, + "realtime": 822, + "realtime-js": 3, + "supabase": 1166, + "supabase-js": 3 + }, + { + "name": "2020-05-30", + "doctest-js": 37, + "jsdoc-template": 2, + "marketplace": 9, + "pg-api": 24, + "pg_listen": 0, + "postgres": 82, + "postgrest-js": 60, + "postgrest-py": 1, + "postgrest-rs": 6, + "realtime": 834, + "realtime-js": 3, + "supabase": 1217, + "supabase-js": 3 + }, + { + "name": "2020-05-31", + "doctest-js": 37, + "jsdoc-template": 2, + "marketplace": 9, + "pg-api": 24, + "pg_listen": 0, + "postgres": 83, + "postgrest-js": 60, + "postgrest-py": 1, + "postgrest-rs": 6, + "realtime": 859, + "realtime-js": 3, + "supabase": 1262, + "supabase-js": 3 + }, + { + "name": "2020-06-01", + "doctest-js": 37, + "jsdoc-template": 2, + "marketplace": 9, + "pg-api": 25, + "pg_listen": 0, + "postgres": 87, + "postgrest-js": 61, + "postgrest-py": 1, + "postgrest-rs": 6, + "realtime": 915, + "realtime-js": 3, + "supabase": 1321, + "supabase-js": 5 + }, + { + "name": "2020-06-02", + "doctest-js": 38, + "jsdoc-template": 2, + "marketplace": 9, + "pg-api": 26, + "pg_listen": 0, + "postgres": 87, + "postgrest-js": 64, + "postgrest-py": 1, + "postgrest-rs": 6, + "realtime": 1084, + "realtime-js": 3, + "supabase": 1375, + "supabase-js": 5 + }, + { + "name": "2020-06-03", + "doctest-js": 38, + "jsdoc-template": 2, + "marketplace": 9, + "pg-api": 27, + "pg_listen": 0, + "postgres": 90, + "postgrest-js": 64, + "postgrest-py": 1, + "postgrest-rs": 6, + "realtime": 1255, + "realtime-js": 3, + "supabase": 1429, + "supabase-js": 5 + }, + { + "name": "2020-06-04", + "doctest-js": 39, + "jsdoc-template": 2, + "marketplace": 10, + "pg-api": 28, + "pg_listen": 0, + "postgres": 91, + "postgrest-js": 66, + "postgrest-py": 2, + "postgrest-rs": 7, + "realtime": 1357, + "realtime-js": 4, + "supabase": 1490, + "supabase-js": 6 + }, + { + "name": "2020-06-05", + "doctest-js": 39, + "jsdoc-template": 2, + "marketplace": 10, + "pg-api": 28, + "pg_listen": 0, + "postgres": 92, + "postgrest-js": 66, + "postgrest-py": 2, + "postgrest-rs": 7, + "realtime": 1388, + "realtime-js": 4, + "supabase": 1528, + "supabase-js": 6 + }, + { + "name": "2020-06-06", + "doctest-js": 39, + "jsdoc-template": 2, + "marketplace": 10, + "pg-api": 28, + "pg_listen": 0, + "postgres": 92, + "postgrest-js": 67, + "postgrest-py": 2, + "postgrest-rs": 7, + "realtime": 1399, + "realtime-js": 4, + "supabase": 1542, + "supabase-js": 6 + }, + { + "name": "2020-06-07", + "doctest-js": 39, + "jsdoc-template": 2, + "marketplace": 10, + "pg-api": 29, + "pg_listen": 0, + "postgres": 95, + "postgrest-js": 68, + "postgrest-py": 2, + "postgrest-rs": 7, + "realtime": 1404, + "realtime-js": 5, + "supabase": 1553, + "supabase-js": 6 + }, + { + "name": "2020-06-08", + "doctest-js": 39, + "jsdoc-template": 2, + "marketplace": 10, + "pg-api": 30, + "pg_listen": 0, + "postgres": 97, + "postgrest-js": 68, + "postgrest-py": 2, + "postgrest-rs": 7, + "realtime": 1419, + "realtime-js": 5, + "supabase": 1588, + "supabase-js": 6 + }, + { + "name": "2020-06-09", + "doctest-js": 41, + "jsdoc-template": 2, + "marketplace": 10, + "pg-api": 30, + "pg_listen": 0, + "postgres": 97, + "postgrest-js": 68, + "postgrest-py": 2, + "postgrest-rs": 7, + "realtime": 1431, + "realtime-js": 5, + "supabase": 1604, + "supabase-js": 6 + }, + { + "name": "2020-06-10", + "doctest-js": 41, + "jsdoc-template": 2, + "marketplace": 10, + "pg-api": 31, + "pg_listen": 0, + "postgres": 97, + "postgrest-js": 69, + "postgrest-py": 2, + "postgrest-rs": 10, + "realtime": 1444, + "realtime-js": 5, + "supabase": 1616, + "supabase-js": 7 + }, + { + "name": "2020-06-11", + "doctest-js": 41, + "jsdoc-template": 2, + "marketplace": 10, + "pg-api": 31, + "pg_listen": 0, + "postgres": 97, + "postgrest-js": 69, + "postgrest-py": 2, + "postgrest-rs": 17, + "realtime": 1445, + "realtime-js": 5, + "supabase": 1631, + "supabase-js": 7 + }, + { + "name": "2020-06-12", + "doctest-js": 41, + "jsdoc-template": 2, + "marketplace": 10, + "pg-api": 31, + "pg_listen": 0, + "postgres": 98, + "postgrest-js": 70, + "postgrest-py": 2, + "postgrest-rs": 25, + "realtime": 1451, + "realtime-js": 5, + "supabase": 1637, + "supabase-js": 7 + }, + { + "name": "2020-06-13", + "doctest-js": 41, + "jsdoc-template": 2, + "marketplace": 10, + "pg-api": 32, + "pg_listen": 0, + "postgres": 98, + "postgrest-js": 70, + "postgrest-py": 2, + "postgrest-rs": 25, + "realtime": 1453, + "realtime-js": 5, + "supabase": 1643, + "supabase-js": 7 + }, + { + "name": "2020-06-14", + "doctest-js": 41, + "jsdoc-template": 2, + "marketplace": 10, + "pg-api": 32, + "pg_listen": 0, + "postgres": 98, + "postgrest-js": 70, + "postgrest-py": 2, + "postgrest-rs": 25, + "realtime": 1459, + "realtime-js": 5, + "supabase": 1651, + "supabase-js": 7 + }, + { + "name": "2020-06-15", + "doctest-js": 41, + "jsdoc-template": 2, + "marketplace": 10, + "pg-api": 32, + "pg_listen": 0, + "postgres": 98, + "postgrest-js": 70, + "postgrest-py": 2, + "postgrest-rs": 26, + "realtime": 1467, + "realtime-js": 5, + "supabase": 1660, + "supabase-js": 7 + }, + { + "name": "2020-06-16", + "doctest-js": 41, + "jsdoc-template": 2, + "marketplace": 10, + "pg-api": 34, + "pg_listen": 0, + "postgres": 99, + "postgrest-js": 70, + "postgrest-py": 2, + "postgrest-rs": 26, + "realtime": 1472, + "realtime-js": 5, + "supabase": 1663, + "supabase-js": 7 + }, + { + "name": "2020-06-17", + "doctest-js": 41, + "jsdoc-template": 2, + "marketplace": 10, + "pg-api": 34, + "pg_listen": 0, + "postgres": 99, + "postgrest-js": 70, + "postgrest-py": 2, + "postgrest-rs": 26, + "realtime": 1475, + "realtime-js": 5, + "supabase": 1668, + "supabase-js": 7 + }, + { + "name": "2020-06-18", + "doctest-js": 41, + "jsdoc-template": 2, + "marketplace": 10, + "pg-api": 34, + "pg_listen": 0, + "postgres": 100, + "postgrest-js": 70, + "postgrest-py": 2, + "postgrest-rs": 27, + "realtime": 1476, + "realtime-js": 5, + "supabase": 1678, + "supabase-js": 7 + }, + { + "name": "2020-06-19", + "doctest-js": 41, + "jsdoc-template": 2, + "marketplace": 10, + "pg-api": 34, + "pg_listen": 0, + "postgres": 101, + "postgrest-js": 70, + "postgrest-py": 2, + "postgrest-rs": 27, + "realtime": 1479, + "realtime-js": 5, + "supabase": 1682, + "supabase-js": 7 + }, + { + "name": "2020-06-20", + "doctest-js": 41, + "jsdoc-template": 2, + "marketplace": 10, + "pg-api": 34, + "pg_listen": 0, + "postgres": 101, + "postgrest-js": 71, + "postgrest-py": 2, + "postgrest-rs": 27, + "realtime": 1480, + "realtime-js": 5, + "supabase": 1688, + "supabase-js": 7 + }, + { + "name": "2020-06-21", + "doctest-js": 41, + "jsdoc-template": 2, + "marketplace": 10, + "pg-api": 35, + "pg_listen": 0, + "postgres": 101, + "postgrest-js": 71, + "postgrest-py": 2, + "postgrest-rs": 27, + "realtime": 1482, + "realtime-js": 5, + "supabase": 1697, + "supabase-js": 7 + }, + { + "name": "2020-06-22", + "doctest-js": 41, + "jsdoc-template": 2, + "marketplace": 10, + "pg-api": 35, + "pg_listen": 0, + "postgres": 101, + "postgrest-js": 71, + "postgrest-py": 2, + "postgrest-rs": 27, + "realtime": 1488, + "realtime-js": 5, + "supabase": 1703, + "supabase-js": 7 + }, + { + "name": "2020-06-23", + "doctest-js": 41, + "jsdoc-template": 2, + "marketplace": 10, + "pg-api": 35, + "pg_listen": 0, + "postgres": 101, + "postgrest-js": 71, + "postgrest-py": 2, + "postgrest-rs": 28, + "realtime": 1491, + "realtime-js": 5, + "supabase": 1713, + "supabase-js": 7 + }, + { + "name": "2020-06-24", + "doctest-js": 41, + "jsdoc-template": 2, + "marketplace": 10, + "pg-api": 36, + "pg_listen": 0, + "postgres": 101, + "postgrest-js": 71, + "postgrest-py": 2, + "postgrest-rs": 28, + "realtime": 1494, + "realtime-js": 5, + "supabase": 1718, + "supabase-js": 7 + }, + { + "name": "2020-06-25", + "doctest-js": 41, + "jsdoc-template": 2, + "marketplace": 10, + "pg-api": 36, + "pg_listen": 0, + "postgres": 101, + "postgrest-js": 71, + "postgrest-py": 2, + "postgrest-rs": 28, + "realtime": 1496, + "realtime-js": 5, + "supabase": 1724, + "supabase-js": 7 + } +] diff --git a/apps/temp-docs/docs/404.mdx b/apps/temp-docs/docs/404.mdx new file mode 100644 index 00000000000..78c7d88f970 --- /dev/null +++ b/apps/temp-docs/docs/404.mdx @@ -0,0 +1,6 @@ +--- +title: '404' +description: 'Page not found' +--- + +# Page not found diff --git a/apps/temp-docs/docs/architecture.mdx b/apps/temp-docs/docs/architecture.mdx new file mode 100644 index 00000000000..706b3319a55 --- /dev/null +++ b/apps/temp-docs/docs/architecture.mdx @@ -0,0 +1,16 @@ +--- +title: 'Architecture' +description: 'Supabase Architecture' +--- + +# Architecture + +Supabase is open source. Wherever possible, we use and support existing tools rather than developing from scratch. We choose open source tools which are scalable and we make them simple to use. + +![Supabase Architecture](https://supabase.com/docs/assets/images/supabase-architecture-9050a7317e9ec7efb7807f5194122e48.png) + +Supabase is not a 1-to-1 mapping of Firebase. While we are building many of the features that Firebase offers, we are not going about it the same way. + +Our technological choices are quite different to Firebase. Everything we use is open source. Wherever possible, we use and support existing tools in the ecosystem, rather than developing from scratch. + +Most notably, we use Postgres rather than a NoSQL store. This was a deliberate choice. We believe that no other database on the market offers the scalability and functionality required to legitimately compete with Firebase. diff --git a/apps/temp-docs/docs/cli/.gitkeep b/apps/temp-docs/docs/cli/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/apps/temp-docs/docs/cli/config-reference.mdx b/apps/temp-docs/docs/cli/config-reference.mdx new file mode 100644 index 00000000000..98a85be9067 --- /dev/null +++ b/apps/temp-docs/docs/cli/config-reference.mdx @@ -0,0 +1,35 @@ +--- +id: config-reference +title: "Config reference" +slug: config-reference +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/cli.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +The config file resides in `supabase/config.json` after you run `supabase init`. + +#### `projectId` (required) + +A string used to distinguish different Supabase projects on the same host. Defaults to the working directory name when running `supabase init`. + +#### `ports.api` (required) + +Host port used for the API URL. Defaults to `54321`. + +#### `ports.db` (required) + +Host port used for the DB URL. Defaults to `54322`. + +#### `ports.studio` (required) + +Host port used for Supabase Studio. Defaults to `54323`. + +#### `ports.inbucket` (optional) + +Host port used for the web interface of Inbucket email testing server. When not specified, emails are automatically confirmed. When specified, emails are not sent to the recipient, but rather monitored and accessible via the web interface. + +#### `dbVersion` (required) + +Server version number used for the database. This needs to match the server version number of the remote database you intend to link to with `supabase db remote set`. You can retrieve it by running `SHOW server_version_num`. \ No newline at end of file diff --git a/apps/temp-docs/docs/cli/index.mdx b/apps/temp-docs/docs/cli/index.mdx new file mode 100644 index 00000000000..257df67ebac --- /dev/null +++ b/apps/temp-docs/docs/cli/index.mdx @@ -0,0 +1,27 @@ +--- +id: index +title: "About" +slug: about +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/cli.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +The Supabase CLI can be found in our [CLI](https://github.com/supabase/cli) repository. + +- [x] Running Supabase locally +- [x] Managing database migrations +- [x] Pushing your local changes to production +- [ ] Manage your Supabase Account +- [ ] Manage your Supabase Projects +- [ ] Generating types directly from your database schema +- [ ] Generating API and validation schemas from your database + +## Installing the CLI + +Installation instructions can be found [here](https://github.com/supabase/cli#install-the-cli). + +## Support + +Report issues to our [issue tracker](https://github.com/supabase/cli/issues). \ No newline at end of file diff --git a/apps/temp-docs/docs/cli/supabase-db-branch-create.mdx b/apps/temp-docs/docs/cli/supabase-db-branch-create.mdx new file mode 100644 index 00000000000..276da242581 --- /dev/null +++ b/apps/temp-docs/docs/cli/supabase-db-branch-create.mdx @@ -0,0 +1,16 @@ +--- +id: supabase-db-branch-create +title: "supabase db branch create" +slug: supabase-db-branch-create +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/cli.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +``` +Create a branch. + +Usage: + supabase db branch create +``` \ No newline at end of file diff --git a/apps/temp-docs/docs/cli/supabase-db-branch-delete.mdx b/apps/temp-docs/docs/cli/supabase-db-branch-delete.mdx new file mode 100644 index 00000000000..37ddb844a7c --- /dev/null +++ b/apps/temp-docs/docs/cli/supabase-db-branch-delete.mdx @@ -0,0 +1,16 @@ +--- +id: supabase-db-branch-delete +title: "supabase db branch delete" +slug: supabase-db-branch-delete +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/cli.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +``` +Delete a branch. + +Usage: + supabase db branch delete +``` \ No newline at end of file diff --git a/apps/temp-docs/docs/cli/supabase-db-branch-list.mdx b/apps/temp-docs/docs/cli/supabase-db-branch-list.mdx new file mode 100644 index 00000000000..9933f256e6e --- /dev/null +++ b/apps/temp-docs/docs/cli/supabase-db-branch-list.mdx @@ -0,0 +1,16 @@ +--- +id: supabase-db-branch-list +title: "supabase db branch list" +slug: supabase-db-branch-list +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/cli.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +``` +List branches. + +Usage: + supabase db branch list +``` \ No newline at end of file diff --git a/apps/temp-docs/docs/cli/supabase-db-changes.mdx b/apps/temp-docs/docs/cli/supabase-db-changes.mdx new file mode 100644 index 00000000000..2b4bdbe6cf1 --- /dev/null +++ b/apps/temp-docs/docs/cli/supabase-db-changes.mdx @@ -0,0 +1,16 @@ +--- +id: supabase-db-changes +title: "supabase db changes" +slug: supabase-db-changes +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/cli.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +``` +Diffs the local database with current migrations, then print the diff to standard output. + +Usage: + supabase db changes +``` \ No newline at end of file diff --git a/apps/temp-docs/docs/cli/supabase-db-commit.mdx b/apps/temp-docs/docs/cli/supabase-db-commit.mdx new file mode 100644 index 00000000000..8823a7fa6d3 --- /dev/null +++ b/apps/temp-docs/docs/cli/supabase-db-commit.mdx @@ -0,0 +1,16 @@ +--- +id: supabase-db-commit +title: "supabase db commit" +slug: supabase-db-commit +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/cli.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +``` +Diffs the local database with current migrations, writing it as a new migration. + +Usage: + supabase db commit +``` \ No newline at end of file diff --git a/apps/temp-docs/docs/cli/supabase-db-push.mdx b/apps/temp-docs/docs/cli/supabase-db-push.mdx new file mode 100644 index 00000000000..0b3435b4186 --- /dev/null +++ b/apps/temp-docs/docs/cli/supabase-db-push.mdx @@ -0,0 +1,16 @@ +--- +id: supabase-db-push +title: "supabase db push" +slug: supabase-db-push +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/cli.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +``` +Push new migrations to the remote database. + +Usage: + supabase db push +``` \ No newline at end of file diff --git a/apps/temp-docs/docs/cli/supabase-db-remote-commit.mdx b/apps/temp-docs/docs/cli/supabase-db-remote-commit.mdx new file mode 100644 index 00000000000..c09e1ee77e0 --- /dev/null +++ b/apps/temp-docs/docs/cli/supabase-db-remote-commit.mdx @@ -0,0 +1,16 @@ +--- +id: supabase-db-remote-commit +title: "supabase db remote commit" +slug: supabase-db-remote-commit +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/cli.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +``` +Commit changes on the remote database since the last pushed migration. + +Usage: + supabase db remote commit +``` \ No newline at end of file diff --git a/apps/temp-docs/docs/cli/supabase-db-remote-set.mdx b/apps/temp-docs/docs/cli/supabase-db-remote-set.mdx new file mode 100644 index 00000000000..93a240ee0a5 --- /dev/null +++ b/apps/temp-docs/docs/cli/supabase-db-remote-set.mdx @@ -0,0 +1,16 @@ +--- +id: supabase-db-remote-set +title: "supabase db remote set" +slug: supabase-db-remote-set +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/cli.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +``` +Set the remote database to push migrations to. + +Usage: + supabase db remote set +``` \ No newline at end of file diff --git a/apps/temp-docs/docs/cli/supabase-db-reset.mdx b/apps/temp-docs/docs/cli/supabase-db-reset.mdx new file mode 100644 index 00000000000..dea74ae7534 --- /dev/null +++ b/apps/temp-docs/docs/cli/supabase-db-reset.mdx @@ -0,0 +1,16 @@ +--- +id: supabase-db-reset +title: "supabase db reset" +slug: supabase-db-reset +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/cli.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +``` +Resets the local database to reflect current migrations. Any changes on the local database that is not committed will be lost. + +Usage: + supabase db reset +``` \ No newline at end of file diff --git a/apps/temp-docs/docs/cli/supabase-db-switch.mdx b/apps/temp-docs/docs/cli/supabase-db-switch.mdx new file mode 100644 index 00000000000..faf65f86268 --- /dev/null +++ b/apps/temp-docs/docs/cli/supabase-db-switch.mdx @@ -0,0 +1,16 @@ +--- +id: supabase-db-switch +title: "supabase db switch" +slug: supabase-db-switch +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/cli.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +``` +Switch branches. + +Usage: + supabase db switch +``` \ No newline at end of file diff --git a/apps/temp-docs/docs/cli/supabase-eject.mdx b/apps/temp-docs/docs/cli/supabase-eject.mdx new file mode 100644 index 00000000000..e7d12225dab --- /dev/null +++ b/apps/temp-docs/docs/cli/supabase-eject.mdx @@ -0,0 +1,17 @@ +--- +id: supabase-eject +title: "supabase eject" +slug: supabase-eject +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/cli.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +```bash +supabase eject +``` + +Run in any folder to create a `docker` folder with a `docker-compose.yml`. This is useful for self-hosting or adding custom configuration. + +See our [Self Hosting](/docs/guides/hosting/overview) docs for more details. \ No newline at end of file diff --git a/apps/temp-docs/docs/cli/supabase-help.mdx b/apps/temp-docs/docs/cli/supabase-help.mdx new file mode 100644 index 00000000000..8494f7305ee --- /dev/null +++ b/apps/temp-docs/docs/cli/supabase-help.mdx @@ -0,0 +1,17 @@ +--- +id: supabase-help +title: "supabase help" +slug: supabase-help +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/cli.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +``` +Help provides help for any command in the application. +Simply type supabase help [path to command] for full details. + +Usage: + supabase help [command] +``` \ No newline at end of file diff --git a/apps/temp-docs/docs/cli/supabase-init.mdx b/apps/temp-docs/docs/cli/supabase-init.mdx new file mode 100644 index 00000000000..21472d298d8 --- /dev/null +++ b/apps/temp-docs/docs/cli/supabase-init.mdx @@ -0,0 +1,16 @@ +--- +id: supabase-init +title: "supabase init" +slug: supabase-init +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/cli.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +``` +Initialize a project to use Supabase CLI. + +Usage: + supabase init +``` \ No newline at end of file diff --git a/apps/temp-docs/docs/cli/supabase-migration-new.mdx b/apps/temp-docs/docs/cli/supabase-migration-new.mdx new file mode 100644 index 00000000000..90d692a1598 --- /dev/null +++ b/apps/temp-docs/docs/cli/supabase-migration-new.mdx @@ -0,0 +1,16 @@ +--- +id: supabase-migration-new +title: "supabase migration new" +slug: supabase-migration-new +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/cli.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +``` +Create an empty migration. + +Usage: + supabase migration new +``` \ No newline at end of file diff --git a/apps/temp-docs/docs/cli/supabase-start.mdx b/apps/temp-docs/docs/cli/supabase-start.mdx new file mode 100644 index 00000000000..d7eb6395774 --- /dev/null +++ b/apps/temp-docs/docs/cli/supabase-start.mdx @@ -0,0 +1,16 @@ +--- +id: supabase-start +title: "supabase start" +slug: supabase-start +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/cli.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +``` +Start the Supabase local development setup. + +Usage: + supabase start +``` \ No newline at end of file diff --git a/apps/temp-docs/docs/cli/supabase-stop.mdx b/apps/temp-docs/docs/cli/supabase-stop.mdx new file mode 100644 index 00000000000..ca813c5a1c2 --- /dev/null +++ b/apps/temp-docs/docs/cli/supabase-stop.mdx @@ -0,0 +1,15 @@ +--- +id: supabase-stop +title: "supabase stop" +slug: supabase-stop +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/cli.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +```bash +supabase stop +``` + +When you are finished with Supabase, run `supabase stop` to stop the Docker services. \ No newline at end of file diff --git a/apps/temp-docs/docs/company/aup.mdx b/apps/temp-docs/docs/company/aup.mdx new file mode 100644 index 00000000000..df03e2efe3d --- /dev/null +++ b/apps/temp-docs/docs/company/aup.mdx @@ -0,0 +1,54 @@ +--- +id: aup +title: Acceptable Use Policy +--- + +# Acceptable Use Policy + +`Last Modified: 15 April 2021` + +This Acceptable Use Policy (this “Policy”) describes prohibited uses of the web services offered by Supabase, Inc. and its affiliates (the “Services”) and the website located at https://supabase.com (the “Supabase Site”). The examples described in this Policy are not exhaustive. We may modify this Policy at any time by posting a revised version on the Supabase Site. By using the Services or accessing the Supabase Site, you agree to the latest version of this Policy. If you violate the Policy or authorize or help others to do so, we may suspend or terminate your use of the Services. + +## No Illegal, Harmful, or Offensive Use or Content + +You may not use, or encourage, promote, facilitate or instruct others to use, the Services or Supabase Site for any illegal, harmful, fraudulent, infringing or offensive use, or to transmit, store, display, distribute or otherwise make available content that is illegal, harmful, fraudulent, infringing or offensive. Prohibited activities or content include: + +- **Illegal, Harmful or Fraudulent Activities.** Any activities that are illegal, that violate the rights of others, or that may be harmful to others, our operations or reputation, including disseminating, promoting or facilitating child pornography, offering or disseminating fraudulent goods, services, schemes, or promotions, make-money-fast schemes, ponzi and pyramid schemes, phishing, or pharming. +- **Infringing Content.** Content that infringes or misappropriates the intellectual property or proprietary rights of others. +- **Offensive Content.** Content that is defamatory, obscene, abusive, invasive of privacy, or otherwise objectionable, including content that constitutes child pornography, relates to bestiality, or depicts non-consensual sex acts. +- **Harmful Content.** Content or other computer technology that may damage, interfere with, surreptitiously intercept, or expropriate any system, program, or data, including viruses, Trojan horses, worms, time bombs, or cancelbots. +- **Platform compliance.** Any activities that are deemed unacceptable by the platforms used by the Supabase Site and Services, including [AWS](https://aws.amazon.com/aup/). + +## No Security Violations + +You may not use the Services to violate the security or integrity of any network, computer or communications system, software application, or network or computing device (each, a “System”). Prohibited activities include: + +- **Unauthorized Access.** Accessing or using any System without permission, including attempting to probe, scan, or test the vulnerability of a System or to breach any security or authentication measures used by a System. +- **Interception.** Monitoring of data or traffic on a System without permission. +- **Falsification of Origin.** Forging TCP-IP packet headers, e-mail headers, or any part of a message describing its origin or route. The legitimate use of aliases and anonymous remailers is not prohibited by this provision. + +## No Network Abuse + +You may not make network connections to any users, hosts, or networks unless you have permission to communicate with them. Prohibited activities include: + +- **Monitoring or Crawling.** Monitoring or crawling of a System that impairs or disrupts the System being monitored or crawled. +- **Denial of Service (DoS).** Inundating a target with communications requests so the target either cannot respond to legitimate traffic or responds so slowly that it becomes ineffective. +- **Intentional Interference.** Interfering with the proper functioning of any System, including any deliberate attempt to overload a system by mail bombing, news bombing, broadcast attacks, or flooding techniques. +- **Operation of Certain Network Services.** Operating network services like open proxies, open mail relays, or open recursive domain name servers. +- **Avoiding System Restrictions.** Using manual or electronic means to avoid any use limitations placed on a System, such as access and storage restrictions. + +## No E-Mail or Other Message Abuse + +You will not distribute, publish, send, or facilitate the sending of unsolicited mass e-mail or other messages, promotions, advertising, or solicitations (like “spam”), including commercial advertising and informational announcements. You will not alter or obscure mail headers or assume a sender’s identity without the sender’s explicit permission. You will not collect replies to messages sent from another internet service provider if those messages violate this Policy or the acceptable use policy of that provider. + +## Our Monitoring and Enforcement + +We reserve the right, but do not assume the obligation, to investigate any violation of this Policy or misuse of the Services or Supabase Site. We may: + +- investigate violations of this Policy or misuse of the Services or Supabase Site; or +- remove, disable access to, or modify any content or resource that violates this Policy or any other agreement we have with you for use of the Services or the Supabase Site. + +We may report any activity that we suspect violates any law or regulation to appropriate law enforcement officials, regulators, or other appropriate third parties. Our reporting may include disclosing appropriate customer information. We also may cooperate with appropriate law enforcement agencies, regulators, or other appropriate third parties to help with the investigation and prosecution of illegal conduct by providing network and systems information related to alleged violations of this Policy. +Reporting of Violations of this Policy + +If you become aware of any violation of this Policy, you will immediately notify us and provide us with assistance, as requested, to stop or remedy the violation. To report any violation of this Policy, please contact us at support@supabase.io. diff --git a/apps/temp-docs/docs/company/privacy.mdx b/apps/temp-docs/docs/company/privacy.mdx new file mode 100644 index 00000000000..794e7415702 --- /dev/null +++ b/apps/temp-docs/docs/company/privacy.mdx @@ -0,0 +1,294 @@ +--- +id: privacy +title: Privacy Policy +--- + +# Privacy Policy + +`Last modified: 27 March 2021` + +Thank you for your interest in Supabase, Inc., ("**_Supabase_**," "**_we_**", "**_our_**" or "**_us_**"). Supabase provides a suite of open source tools, stitched together to build a seamless developer experience. This Privacy Notice explains how information about you, that directly identifies you, or that makes you identifiable ("**_personal information_**") is collected, used and disclosed by Supabase in connection with our website at [supabase.io](https://supabase.com) (the "**_Site_**") and our services offered in connection with the Site (collectively with the Site, the "**_Service_**"). + +We may also provide you with additional privacy notices or disclosures where the scope of the inquiry, request, or personal information we require falls outside the scope of this Privacy Notice. In that case, the additional Privacy Notice or disclosures will govern how we may process the information you provide at that time. Please note that this Privacy Notice does not cover or apply to our processing of information about our employees or contractors. + +This Policy explains how we use your personal information when we act as a data controller. As far as you use our Service as a natural person, we are the controller of your personal information. We are responsible for, and control, the processing of your personal information. + +Wherever our customers use our Service to submit, manage, or otherwise use content relating to our customers’ end users ("**_Customer Data_**") during the provision of our Service, we have contractually committed ourselves to only process such information on behalf and under the instruction of the respective customer, who is the data controller. This Privacy Notice does not apply to such processing and we recommend you read the Privacy Notice of the respective customer, if their processing concerns your personal information. + +## Region-specific Disclosures + +- **California - Your California Privacy Rights:** If you are a California resident, California Civil Code Section 1798.83 permits you to request information regarding the disclosure of personal information to third parties for their direct marketing purposes during the immediately preceding calendar year. Note we do not share your personal information with third parties for their own marketing purposes. +- **Nevada:** Chapter 603A of the Nevada Revised Statutes permits a Nevada resident to opt out of future sales of certain covered information that a website operator has collected or will collect about the resident. Note we do not sell your personal information within the meaning of Chapter 603A. However, if you would still like to submit such a request, please contact us at support@supabase.io. +- **European Economic Area, United Kingdom or Switzerland:** If you are located in the European Economic Area ("**_EEA_**"), United Kingdom or Switzerland, or otherwise engage with Supabase’s European operations, please see the **Privacy Disclosures for the European Economic Area, United Kingdom and Switzerland** for additional European-specific privacy disclosures, including what constitutes your personal information, the lawful bases we rely on to process your personal information, how we use cookies when you access our Sites from the EEA, UK or Switzerland and your rights in respect of your personal information. + +**Note for International Visitors:** Personal information may be transferred to, stored and processed in a country other than the one in which it was collected. For example, the Sites are primarily hosted in and provided from the United States. Please note the country to which personal data is transferred may not provide the same level of protection for personal information as the country from which it was transferred. + +## 1. Information we collect and our use + +We collect personal information in connection with your visits to and use of the Service. This collection includes information that you provide in connection with the Service, information from third parties, and information that is collected automatically such as through the use of cookies and other technologies. + +### Information That You Provide + +We collect personal information from you. The categories of information we collect can include: + +- **_Registration information._** We collect personal and/or business information that you provide when you register for an account at the Site. This information may include your name, email address, GitHub username. We use this information to administer your account, provide you with the relevant services and information, communicate with you regarding your account, the Site and for customer support purposes. +- **_Information collected through the Use of the Service._** After registration, you may create, upload or transmit files, documents, videos, images, data or information as part of your use of the Service (collectively, "**_User Content_**"). User Content and any information contained in the User Content, including personal information you may have included, is stored and collected as part of the Service. You have full control of the information included in the User Content. +- **_Payment information._** If you make a purchase or payment on the Site, such as for a subscription, we collect transactional information provided in connection with your purchase or payment. Please note that we use third party payment processors, including Stripe, to process payments made to us. As such, we do not retain any personally identifiable financial information such as credit card numbers. Rather, all such information is provided directly by you to our third-party processor. The payment processor’s use of your personal information is governed by their privacy notice. To view Stripe’s privacy notice, please visit: . +- **_Communications._** If you communicate with us through any paper or electronic form, we may collect your name, email address, mailing address, phone number, or any other personal information you choose to provide to us. We use this information to investigate and respond to your inquiries, and to communicate with you, to enhance the services we offer to our users and to manage and grow our organization. If you register for our newsletters or updates, we may communicate with you by email. To unsubscribe from promotional messages, please follow the instructions within our messages and review the **Control Over Your Information** section below. If you become a contributor, we may also collect your GitHub name and feature you on our website. +- **_Inquiries and Feedback._** If you contact us, we will collect the information that you provide us, such as your contact information and the contents of your communication with us. + +You are free to choose which personal information you want to provide to us or whether you want to provide us with personal information at all. However, some information, such as your name, address, payment transaction information, and information on your requested Services may be necessary for the performance of our contractual obligations. + +### Information from Third Party Sources + +We may receive personal information about you from our business partners and service providers and combine this information with other data we collect from you. The third-parties may include website and service operators, payment processors, marketing partners, and shipping providers. The information may include contact information, demographic information, information about your communications and related activities, and information about your orders. We may use this information to administer and facilitate our services, your orders and our marketing activities. + +- **_Single Sign-On._** We use single sign-on ("**SSO**") such as Github to allow a user to authenticate their account using one set of login information. We will have access to certain information from those third parties in accordance with the authorization procedures determined by those third parties, including, for example, your name, username, email address, language preference, and profile picture. We use this information to operate, maintain, and provide to you the features and functionality of the Service. We may also send you service-related emails or messages (e.g., account verification, purchase confirmation, customer support, changes or updates to features of the Site, technical and security notices). +- **_Social Media._** When you interact with our Site through various social media, such as when you click on the social media icon on the Site, follow us on a social media site, or post a comment to one of our pages, we may receive information from the social network such as your profile information, profile picture, gender, user name, user ID associated with your social media account, age range, language, country, and any other information you permit the social network to share with third parties. The data we receive is dependent upon your privacy settings with the social network. We use this information to operate, maintain, and provide to you the features and functionality of the Service, as well as to communicate directly with you, such as to send you email messages about products and services that may be of interest to you. +- **_Employment Applications._** If you apply for employment, we collect your contact and demographic information, educational and work history, employment interests, information obtained during interviews and any other information you choose to provide. We use the information provided to evaluate your candidacy for employment, to communicate with you during the application process and to facilitate the onboarding process. +- **_Information from Other Sources._** We may obtain information from other sources, including through third-party information providers, our shareholders, customers, or through transactions such as mergers and acquisitions. We may combine this information with other information we collect from or about you. In these cases, our Privacy Notice governs the handling of the combined personal information. We use this information to operate, maintain, and provide to you the features and functionality of the Service, as well as to communicate directly with you, such as to send you email messages about products and services that may be of interest to you. + +### Other Uses of Personal Information + +In addition to the uses described above, we may collect and use personal information for the following purposes: + +- For our business activities, including to operate the Service and to provide you with the features and functionality of the Service; +- To communicate with you and respond to your requests, such as to respond to your questions, contact you about changes to the Service, and communicate about account related matters; +- For marketing and advertising purposes, such as to market to you or offer you with information and updates on our products or services we think that you may be interested in. While we may use your personal information in this manner, please note that we do not use User Content to serve you ads, and we will never share User Content with any third parties for marketing or advertising purposes, unless you have explicitly submitted it to us for that purpose; +- For analytics and research purposes; +- To enforce our **Terms of Service**, to resolve disputes, to carry out our obligations and enforce our rights, and to protect our business interests and the interests and rights of third parties; +- To comply with contractual and legal obligations and requirements; +- To fulfill any other purpose for which you provide personal information; and +- For any other lawful purpose, or other purpose that you consent to. + +## 2. How we share personal information + +We may share your personal information in the instances described below. For further information on your choices regarding your information, see **Control Over Your Information**. + +- We may share your personal information with third-party service providers or business partners who help us deliver or improve our Site or services, or who perform services on our behalf, which are subject to reasonable confidentiality terms, and may include processing payments, providing web hosting services, or providing analytics. +- Third parties as required by law or subpoena or if we reasonably believe that such action is necessary to (a) comply with the law and the reasonable requests of law enforcement; (b) to enforce our **Terms of Service** or other agreements or to protect the security or integrity of the Supabase services, including to prevent harm or financial loss, or in connection with preventing fraud or illegal activity; and/or (c) to exercise or protect the rights, property, or personal safety of Supabase, our Customers, visitors, or others. +- We may share with other companies and brands owned or controlled by Supabase, and other companies owned by or under common ownership as Supabase. These companies will use your personal information in the same way as we can under this Privacy Notice. +- We may transfer any information we collect in the event we sell or transfer all or a portion of our business or assets (including any shares in the company) or any portion or combination of our products, services, businesses and/or assets. Should such a transaction occur (whether a divestiture, merger, acquisition, bankruptcy, dissolution, reorganization, liquidation, or similar transaction or proceeding), we will use reasonable efforts to ensure that any transferred information is treated in a manner consistent with this Privacy Notice. +- We may disclose your information publicly or with another third party with your prior authorization. +- With others in an aggregated or otherwise anonymized form that does not reasonably identify you directly as an individual. + +## 3. Control over your information + +### Email Communications + +From time to time, we may send you emails regarding updates to our Service, products or services, notices about our organization, or information about products/services we offer (or promotional offers from third parties) that we think may be of interest to you. If you wish to unsubscribe from such emails, simply click the "unsubscribe link" provided at the bottom of the email communication. Note that you cannot unsubscribe from certain services-related email communications (e.g., account verification, confirmations of transactions, technical or legal notices). + +### Modifying Account Information + +If you have an online account with us, you have the ability to modify certain information in your account (e.g., your contact information) through the account options provided on the Site. If there is personal information in your User Content, you can use the features and functionality of the Service to edit or delete the personal information or User Content. Not all personal information is maintained in a format that you can access or change. If you would like to request access to, or correction or deletion of personal information, you may send your request to us at the email provided below. We will review your request and may require you to provide additional information to identify yourself, but we do not promise that we will be able to satisfy your request. + +## 4. How We Use Cookies and Other Tracking Technology to Collect Information + +We, and our third-party partners, automatically collect certain types of usage information when you visit our Site, read our emails, or otherwise engage with us.  We typically collect this information through a variety of tracking technologies, including cookies, web beacons, embedded scripts, location-identifying technologies, file information, and similar technology (collectively, "**tracking technologies**"). + +We, and our third-party partners, use tracking technologies to automatically collect usage and device information, such as: + +- Information about your device and its software, such as your IP address, browser type, Internet service provider, device type/model/manufacturer, operating system, date and time stamp, and a unique ID that allows us to uniquely identify your browser or your account (including, for example, a persistent device identifier), and other such information. +- When you access our sites from a mobile device, we may collect unique identification numbers associated with your device or our mobile application mobile carrier, device type, model and manufacturer, mobile device operating system brand and model, and depending on your mobile device settings, we may be able to approximate a device’s location by analyzing other information, like an IP address. +- Information about the way you access and use our services, for example, the site from which you came and the site to which you are going when you leave our services, the pages you visit, the links you click, whether you open emails or click the links contained in emails, whether you access the services from multiple devices, and other actions you take on the Sites. + +We use the data collected through tracking technologies to:  (a) remember information so that you will not have to re-enter it during your visit or the next time you visit the site; (b) provide custom content and information; (c) identify you across multiple devices; (d) provide and monitor the effectiveness of our services; (e) monitor aggregate metrics such as total number of visitors, traffic, usage, and demographic patterns on our Site; (f) diagnose or fix technology problems; and (g) to provide, plan for, and enhance our services. + +**Note we do not engage in online targeted advertising.** + +**Cookies and Other Tracking Technologies Opt-Out.** Depending on your browser or mobile device, you may be able to set your browser to delete or notify you of cookies and other tracking technology by actively managing the settings on your browser or mobile device. + +If you would prefer not to accept cookies, most browsers will allow you to: (i) change your browser settings to notify you when you receive a cookie, which lets you choose whether or not to accept it; (ii) disable existing cookies; or (iii) set your browser to automatically reject cookies. Please note that doing so may negatively impact your experience using the sites, as some features and services on our sites may not work properly. Depending on your mobile device and operating system, you may not be able to delete or block all cookies. You may also set your e-mail options to prevent the automatic downloading of images that may contain technologies that would allow us to know whether you have accessed our e-mail and performed certain functions with it. + +## 5. Data Retention and Security + +We will retain your personal information for the length of time needed to fulfill the purposes outlined in this Privacy Notice, unless a longer retention period is required or permitted by law. We store data on servers in the U.S. or any other country in which Supabase or its affiliates, subsidiaries, agents or contractors maintain facilities. If you are located in the European Union or other regions with laws governing data collection and use that may differ from U.S. law, please note that your personal information may be transferred to a country and jurisdiction that does not have the same data protection laws as your jurisdiction. When you register for use with Supabase you have the option of where you store your information and we will not transfer it without providing information to you in advance. + +Supabase cares about the security of your information and uses commercially reasonable physical, technical and organizational measures designed to preserve the integrity and security of all information we collect. However, no security system is impenetrable, and we cannot guarantee the security of our systems 100%. In the event that any information under our control is compromised as a result of a breach of security, we will take reasonable steps to investigate the situation and where appropriate, notify those individuals whose information may have been compromised and take other steps, in accordance with any applicable laws and regulations. + +## 6. Links to Third-Party Websites and Services + +For your convenience, our Site may provide links to third-party websites or services that we do not own or operate. We are not responsible for the practices employed by any websites or services linked to or from the services, including the information or content contained within them. Your browsing and interaction on any other website or service are subject to the applicable third party’s rules and policies, not ours. If you are using a third-party website or service, you do so at your own risk. We encourage you to review the privacy policies of any site or service before providing any personal information. + +## 7. Children’s Privacy + +Our services are not intended for children under the age of 13. We do not knowingly solicit or collect personal information from children under the age of 13. If we learn that any personal information has been collected inadvertently from a child under 13, we will delete the information as soon as possible. If you believe that we might have collected information from a child under 13, please contact us at privacy@supabase.io. + +## 8. Changes to Privacy Notice + +We reserve the right to change this Privacy Notice from time to time in our sole discretion. We will notify you about material changes in the way we treat personal data by sending a notice to the primary email address specified in your Supabase account and/or by placing a prominent notice on our Site. It is your responsibility to review this Privacy Notice periodically. When we do change the Privacy Notice, we will also revise the "last modified" date. + +## 9. Contact Us + +For additional inquiries about this Privacy Notice, please send us an email at privacy@supabase.io. + +This Privacy Notice was last modified on 27th March 2021 + +## Privacy disclosures for the European economic area, United Kingdom, and Switzerland. + +While we are primarily based in the United States, Supabase maintains operations in Europe and may direct our services to individuals located in the European Economic Area ("**_EEA_**"), United Kingdom and Switzerland, including through our Site [supabase.io](/) (collectively, our "**_European Services_**"). The following disclosures ("**_Privacy Disclosures_**") apply to our processing of personal data in connection with our European Services. + +Supabase, Inc. is the data controller responsible for the processing of personal data in connection with our European Services. This means that we determine and are responsible for how your personal information is used. + +**Personal Data:** When we use the term "personal data" in this section, we mean information relating to an identified or identifiable natural person. + +### 1. Personal data we collect from you when you use the Supabase European Services, and how we use it. + +We collect the categories of personal data that you voluntarily submit directly to us when you use the European Services, as set forth in our Privacy Notice under the section entitled **Information We Collect and Our Use**. The table at **Annex 1** sets out in detail the categories of personal data we collect about you and how we use that information when you use the European Services, as well as the legal basis which we rely on to process the personal information and recipients of that personal information. + +### 2. Information we collect about you automatically. + +We also automatically collect personal information indirectly about how you access and use the European Services, and information about the device you use to access the European Services. For example, we may collect: + +(a) information about the features you use and the pages you view on the European Services; + +(b) information about your device (such as your IP address, device identifier, device type, model and manufacturer); and + +(c) information about your usage patterns (such as how often you use the Supabase European Services and your language settings). + +We use this information to provide you the features and functionality of the European Services, to monitor and improve the European Services and to develop new services. + +The table at **Annex 2** sets out further information about the categories of personal information we collect about you automatically and how we use that information. The table also lists the legal basis which we rely on to process the personal information and recipients of that personal information. + +We may link or combine the personal information we collect about you and the information we collect automatically. + +We may anonymise and aggregate any of the personal information we collect (so that it does not directly identify you). We may use anonymised information for purposes that include testing our IT systems, research, data analysis, improving the Supabase European Services. We may also share such anonymised and aggregated information with others. + +### 3. How long will we store your personal information + +We will usually store the personal information we collect about you for no longer than necessary for the purposes set out in Annex 1 and Annex 2, in accordance with our legal obligations and legitimate business interests. + +The criteria used to determine the period for which personal information about you will be retained varies depending on the legal basis under which we process the personal information: + +1. **Legitimate Interests.** Where we are processing personal information based on our legitimate interests, we generally will retain such information for a reasonable period of time based on the particular interest, taking into account the fundamental interests and the rights and freedoms of data subjects. +2. **Consent.** Where we are processing personal information based on your consent, we generally will retain the information until you withdraw your consent, or otherwise for the period of time necessary to fulfill the underlying agreement with you or provide you with the applicable service for which we process that personal information. +3. **Contract.** Where we are processing personal information based on contract, we generally will retain the information for the duration of the contract plus some additional limited period of time that is necessary to comply with law or that represents the statute of limitations for legal claims that could arise from the contractual relationship. +4. **Legal Obligation.** Where we are processing personal information based on a legal obligation, we generally will retain the information for the period of time necessary to fulfill the legal obligation. +5. **Legal Claim.** We may need to apply a "legal hold" that retains information beyond our typical retention period where we face threat of legal claim.  In that case, we will retain the information until the hold is removed, which typically means the claim or threat of claim has been resolved. + +In all cases, in addition to the purposes and legal bases, we consider the amount, nature and sensitivity of the personal information, as well as the potential risk of harm from unauthorized use or disclosure of your personal information. + +### 4. Recipients of Personal Information + +In addition to the recipients listed in Annexes 1 and 2, we may also share your personal information with the following (as required in accordance with the uses set out in Annexes 1 and 2): + +1. **Service providers and advisors**: we may share your personal information with third party vendors and other service providers that perform services for us or on our behalf, which may include providing professional services, such as legal and accounting services, mailing, email or chat services, fraud prevention, web hosting, or providing analytic services. +2. **Affiliates**. Other companies owned by or under common ownership as Supabase, including our subsidiaries (i.e., any organization we own or control) and our ultimate holding company (i.e., any organization that owns or controls us) and any subsidiaries it owns. These companies will use your personal information in the same way as we can under these Privacy Disclosures. +3. **Purchasers and third parties in connection with a business transaction**: your personal information may be disclosed to third parties in connection with a transaction, such as a merger, sale of assets or shares, reorganization, financing, change of control or acquisition of all or a portion of our business. +4. **Law enforcement, regulators and other parties for legal reasons**: we may share your personal information with third parties as required by law or if we reasonably believe that such action is necessary to (i) comply with the law and the reasonable requests of law enforcement; (ii) detect and investigate illegal activities and breaches of agreements, including our Terms; and/or (iii) exercise or protect the rights, property, or personal safety of Supabase, its users or others. + +### 5. Marketing and Advertising + +From time to time we may contact you with information about our services, including sending you marketing messages and asking for your feedback on our services. Most marketing messages we send will be by email. For some marketing messages, we may use personal information we collect about you to help us determine the most relevant marketing information to share with you. + +We will only send you marketing messages if you have given us your consent to do so. You can withdraw your consent at a later date by clicking on the unsubscribe link at the bottom of our marketing emails or by updating your preferences via your account on the Site. + +### 6. Storing and transferring your personal information + +**Security**. We implement appropriate technical and organizational measures to protect your personal information against accidental or unlawful destruction, loss, change or damage. All personal information we collect will be stored by our cloud hosting provider on secure servers. We will never send you unsolicited emails or contact you by phone requesting credit or debit card information or national identification numbers. + +**International Transfers of your Personal Information**. The personal information we collect may be transferred to and stored in countries outside of the jurisdiction you are in where we and our third party service providers have operations. If you are located in the EEA, United Kingdom or Switzerland, your personal information may be processed outside of those regions, including in the United States. + +In the event of such a transfer, we ensure that: (i) the personal information is transferred to countries recognized as offering an equivalent level of protection; or (ii) the transfer is made pursuant to appropriate safeguards, such as standard data protection clauses adopted by the European Commission. + +If you wish to enquire further about these safeguards used, please contact us using the details set out at the end of these Privacy Disclosures. + +### 7. Profiling + +We may analyze personal data we have collected about you to create a profile of your interests and send product updates. We may also use personal data about you to detect and reduce fraud. + +### 8. Your rights in respect of your personal information + +In accordance with applicable privacy law, you have the following rights in respect of your personal information that we hold: + +1. **Right of access**. You have the right to obtain: + 1. confirmation of whether, and where, we are processing your personal information; + 2. information about the categories of personal information we are processing, the purposes for which we process your personal information and information as to how we determine applicable retention periods; + 3. information about the categories of recipients with whom we may share your personal information; and + 4. a copy of the personal information we hold about you. +2. **Right of portability**. You have the right, in certain circumstances, to receive a copy of the personal information you have provided to us in a structured, commonly used, machine-readable format that supports re-use, or to request the transfer of your personal data to another person. +3. **Right to rectification**. You have the right to obtain rectification of any inaccurate or incomplete personal information we hold about you without undue delay. +4. **Right to erasure**. You have the right, in some circumstances, to require us to erase your personal information without undue delay if the continued processing of that personal information is not justified. +5. **Right to restriction**. You have the right, in some circumstances, to require us to limit the purposes for which we process your personal information if the continued processing of the personal information in this way is not justified, such as where the accuracy of the personal information is contested by you. +6. **Right to withdraw consent**. There are certain circumstances where we require your consent to process your personal information. In these instances, and if you have provided consent, you have the right to withdraw your consent. If you withdraw your consent, this will not affect the lawfulness of our use of your personal information before your withdrawal. + +**You also have the right to object to any processing based on our legitimate interests where there are grounds relating to your particular situation. There may be compelling reasons for continuing to process your personal information, and we will assess and inform you if that is the case. You can object to marketing activities for any reason.** + +You also have the right to lodge a complaint to your local data protection authority. If you are based in the European Union, information about how to contact your local data protection authority is available [here](http://ec.europa.eu/justice/data-protection/bodies/authorities/index_en.htm). If you are based in the UK or Switzerland, your local data protection authorities are the UK Information Commissioner's Office () and the Swiss Federal Data Protection and Information Commissioner (). + +If you wish to exercise one of these rights, please contact us using the contact details at the end of these Privacy Disclosures. + +Due to the confidential nature of data processing we may ask you to provide proof of identity when exercising the above rights. This can be done by providing a scanned copy of a valid identity document or a signed photocopy of a valid identity document. + +### 9. Cookies and similar technologies used on our European Services + +Our European Services uses cookies and similar technologies such as pixels and Local Storage Objects (LSOs) like HTML5 (together "**_cookies_**") to distinguish you from other users of our European Services. This helps us to provide you with a good experience when you browse our European Services and also allows us to monitor and analyse how you use and interact with our European Services so that we can continue to improve our European Services. + +Cookies are pieces of code that allow for personalization of our European Services experience by saving your information such as user ID and other preferences. A cookie is a small data file that we transfer to your computer's hard disk for record-keeping purposes. + +We use the following types of cookies: + +1. **Strictly necessary cookies**. These are cookies that are required for the operation of our European Services. They include, for example, cookies that enable you to log into secure areas of our European Services. + +Please see **Annex 3** for more information about the cookies we use on the European Services. + +Most browsers also allow you to change your cookie settings to block certain cookies. Depending on your mobile device and operating system, you may not be able to delete or block all cookies. Please note that if you choose to refuse all cookies you may not be able to use the full functionality of our European Services. These settings will typically be found in the "options" or "preferences" menu of your browser. In order to understand these settings, the following links may be helpful, otherwise you should use the "Help" option in your browser for more details. + +- [Cookie settings in Internet Explorer](https://support.microsoft.com/en-gb/help/278835/how-to-delete-cookie-files-in-internet-explorer) +- [Cookie settings in Firefox](http://support.mozilla.org/en-US/kb/cookies) +- [Cookie settings in Chrome](https://support.google.com/chrome/answer/95647?hl=en) +- [Cookies settings in Safari web](https://support.apple.com/en-gb/guide/safari/manage-cookies-and-website-data-sfri11471/mac) and [iOS](https://support.apple.com/en-gb/HT201265). + +If you would like to find out more about cookies and other similar technologies, please visit [allaboutcookies.org](http://www.allaboutcookies.org). + +Please note that deleting or blocking cookies may not be effective for all types of tracking technologies, such as Local Storage Objects (LSOs) like HTML5. + +### 10. Tracking technologies used in our emails + +Our emails may contain tracking pixels that identify if and when you have opened an email that we have sent you, how many times you have read it and whether you have clicked on any links in that email. This helps us measure the effectiveness of our marketing email campaigns, make the emails we send to you more relevant to your interests and to understand if you have opened and read any important administrative emails we might send you. + +Most popular email clients will allow you to block these pixels by disabling certain external images in emails. You can do this through the settings on your email client – these generally give you the option of choosing whether emails will display "remote images", "remote content" or "images" by default. + +Some browsers also give you the option of downloading and installing extensions that block pixels and other tracking technologies. + +## Annex 1 – Personal information you provide to us + +| **Category of Personal Information** | **How we may use the Personal Information** | **Legal Bases for Processing** | **Recipients of Personal Information** | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Contact information**, such as first name, last name and email address. | We may use this information to set up and authenticate your account on the Service. | The processing is necessary for the performance of a contract with you and to take steps prior to entering into a contract with you, namely our Terms of Service. |

    We may share this information with the following service providers through the provision of the Service: Segment, Auth0, Stripe, Intercom, Hubspot, Mixpanel, Notion, Slack, Amazon Web Services, and BigQuery (Google Cloud).

    | +| | We may use this information to communicate with you, including sending service-related communications. | The processing is necessary for the performance of a contract with you, namely our Terms of Service. | | +| | We may use this information to deal with enquiries and complaints made by or about you relating to the Service. | The processing is necessary for our legitimate interests, namely administering the Service, and for communicating with you effectively to respond to your queries or complaints. | | +| | We may use this information in connection with providing you with marketing communications in accordance with your preferences. | We will only use your personal information in this way to the extent you have given us consent to do so. | | +| **Your registration / account information** such as your full name, email, and password. |

    We may use this information to create your account on the Service.

    |

    The processing is necessary for the performance of a contract with you.

    |

    We may share this information with the following service providers through the provision of the Service: Segment, Auth0, Stripe, Amazon Web Services.

    | +| |

    We use this information to deal with enquiries and complaints made by or about you relating to the Service.

    | The processing is necessary for our legitimate interests, namely for communicating with our members effectively to respond to any queries or complaints. | | +| **Payment transaction information.** When you make a purchase, we may collect information such as your billing address and other information such as date and time of your transaction. |

    We may use this information to process your orders through the Service.

    | The processing is necessary for the performance of a contract. |

    We may share this information with the following service providers through the provision of the Service: Stripe, and Amazon Web Services.

    | +| | We may use this information to verify your identity in connection with the detection and prevention of fraud or financial crime. | The processing is necessary for our and third partiers' legitimate interests, namely the detection and prevention of fraud and financial crime. | | +| **Approximate Location information.** When you visit our Service, we may collect information about your location. This information may be derived from WiFi positioning or your IP address. | We may use information to present the Service to you on your device. | The processing is necessary for performance of a contract with you. |

    We may share this information with the following service providers through the provision of the Service: Sentry, BigQuery (Google Cloud), and Amazon Web Services.

    | +| | We may use this information to localise features of the Service. | The processing is necessary for our legitimate interest, namely localising features of the Service and tailoring the Service so that it is more relevant to our users. | | +| | We may use this information to determine content that may be of interest to you. | The processing is necessary for our legitimate interests, namely tailoring the Service so that it is more relevant to you. | | +| **Chat, comments and opinions.** When you contact us directly, e.g. by email or phone we will record your comments and opinions. | We may use this information to address your questions, issues and concerns. | The processing is necessary for our legitimate interests, namely communicating with you and responding to queries, complaints and concerns. |

    We may share this information with the following service providers through the provision of the Service: Intercom, Hubspot, Google Gsuite, and Slack.

    | +| | We may use this information to improve the Service. | The processing is necessary for our legitimate interests (to develop and improve our service). | | +| **Information received from third parties, such as social networks.** If you interact with us through a social network, we may receive information from the social network such as your name, profile information, and any other information you permit the social network to share with third parties. We use single sign-on ("**_SSO_**") such as Github to allow a user to authenticate their account using one set of login information. The data we receive is dependent on your privacy settings with the social network. | We may use this information to reshare content created through the use of the Service | The processing is necessary for our legitimate interests (to develop our service and inform our marketing strategy) | We may share this information with the following service providers through the provision of the Service: Auth0 and Slack. | +| |

    We may use this information to authenticate you and allow you to access the Service.

    | The processing is necessary for the performance of a contract with you. | | +| **Your preferences**, such as preferences set for notifications, marketing communications, how the Service is displayed and the active functionalities on the Service. |

    We use this information to provide notifications, send news, alerts and marketing communications and provide the Service in accordance with your choices.

    |

    The processing is necessary for our legitimate interest, namely ensuring the user receives the correct marketing and other communications, and that this is displayed in accordance with the user's preferences.

    | We may share this information with the following service providers through the provision of the Service: Segment, Intercom and Hubspot. | +| |

    We use this information to ensure that we comply with our legal obligation to send only those marketing communications to which you have consented.

    | The processing is necessary for compliance with a legal obligation to which we are subject. | | + +## Annex 2 – Personal information collected automatically + +| **Category of personal information** | **How we may use it** | **Legal basis for the processing** | **Recipients of Personal Data** | +| :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Approximate location information.** Other than information you choose to provide to us, we do not collect information about your precise location. Your device’s IP address may however help us determine an approximate location. | We may use information you provide to us about your location to monitor and detect fraud or suspicious activity in relation to your Supabase account. | The processing is necessary for our legitimate interests, namely to protect our business and your account from fraud and other illegal activities. |

    **Approximate location information:** We may share this information with the following service providers through the provision of the Service: Sentry, BigQuery (Google Cloud), and Amazon Web Services.

    **Information about how you access and use the Service.** We may share this information with the following service providers through the provision of the Service: Segment, Mixpanel, Intercom, Hubspot, BigQuery (Google Cloud), and Amazon Web Services.

    **Log files and information about your device.** We may share this information with the following service providers through the provision of the Service: Segment, Mixpanel, Intercom, Hubspot, Sentry, BigQuery (Google Cloud), and Amazon Web Services.

    | +| | We may use this information to tailor how the Service is displayed to you (such as the language in which it is provided to you). | The processing is necessary for our legitimate interest, namely tailoring our service so that it is more relevant to our users. | | +| **Information about how you access and use the Service.** For example, how frequently you access the Service, the time you access the Service and how long you use it for, the approximate location that you access the Service from, the site from which you came and the site to which you are going when you leave our website, the website pages you visit, the links you click, whether you open emails or click the links contained in emails, whether you access the Service from multiple devices, and other actions you take on the Service. |

    We may use information about how you use and connect to the Service to present the Service to you on your device.

    | The processing is necessary for our legitimate interests, namely to tailor the Service to the user. | | +| | We may use this information to determine products and services that may be of interest to you for marketing purposes. | The processing is necessary for our legitimate interests, namely to inform our direct marketing. | | +| |

    We may use this information to monitor and improve the Service and business, resolve issues and to inform the development of new products and services.

    | The processing is necessary for our legitimate interests, namely to monitor and resolve issues with the Service and to improve the Service generally. | | +| **Log files and information about your device.** We also collect information about the tablet, smartphone or other electronic device you use to connect to the Service. This information can include details about the, operating systems, browsers and applications connected to the Service through the device and your IP address. |

    We may use information about how you use and connect to the Service to present the Service to you on your device.

    | The processing is necessary for our legitimate interests, namely to tailor the Service to the user. | | +| |

    We may use this information to monitor and improve the Service and business, resolve issues and to inform the development of new products and services.

    | The processing is necessary for our legitimate interests, namely to monitor and resolve issues with the Service and to improve the Service generally. | | + +## Annex 3 - Cookies + +| **Cookie Name** | **Type of cookie** | **How long does the cookie stay on my device?** | **Purpose of the cookie** | +| :----------------------------- | :----------------- | :---------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +|

    a0:session

    | Strictly necessary | 1 Day | Authentication Purposes. | +|

    a0:state

    | Strictly necessary | 2 Hours | Authentication Purposes. | +|

    youtube-nocookie

    | Strictly necessary | Persistent |

    Privacy-enhanced cookie, essential for embedded videos. [Link.](https://support.google.com/youtube/answer/171780)

    Privacy Enhanced Mode allows you to embed YouTube videos without using cookies that track viewing behavior. This means no activity is collected to personalize the viewing experience.

    | diff --git a/apps/temp-docs/docs/company/terms.mdx b/apps/temp-docs/docs/company/terms.mdx new file mode 100644 index 00000000000..f3cd9dd3537 --- /dev/null +++ b/apps/temp-docs/docs/company/terms.mdx @@ -0,0 +1,237 @@ +--- +id: terms +title: Terms of Service +--- + +# Terms of Service + +`Last Modified: 20 November 2020` + +These Customer Terms and Conditions (this "**Agreement**"), effective as of the date on which you click a button or check a box (or something similar) acknowledging your acceptance of this Agreement (the "**Effective Date**"), is by and between Supabase, Inc., a Delaware corporation with offices located at 970 Toa Payoh North #07-04, Singapore 318992 ("**Supabase**") and the entity on whose behalf the individual accepting this Agreement accepts this Agreement ("**Customer**"). The individual accepting this Agreement hereby represents and warrants that it is duly authorized by the entity on whose behalf it accepts this Agreement to so accept this Agreement. Supabase and Customer may be referred to herein collectively as the "**Parties**" or individually as a "**Party**." The Parties agree as follows: + +## 1. Definitions. + +1. "**Aggregated Data**" means data and information related to or derived from Customer Data or Customer's use of the Services that is used by Supabase in an aggregate and anonymized manner, including to compile statistical and performance information related to the Services. +2. "**Authorized User**" means Customer's employees, consultants, contractors, and agents (i) who are authorized by Customer to access and use the Services under the rights granted to Customer pursuant to this Agreement; and (ii) for whom access to the Services has been purchased hereunder. +3. "**Customer Data**" means information, data, and other content, in any form or medium, that is submitted, posted, or otherwise transmitted by or on behalf of Customer or an Authorized User through the Services; provided that, for purposes of clarity, Customer Data does not include Aggregated Data. +4. "**Documentation**" means Supabase's end user documentation relating to the Services available at [supabase.io](https://supabase.com). +5. "**Harmful Code**" means any software, hardware, or other technology, device, or means, including any virus, worm, malware, or other malicious computer code, the purpose or effect of which is to permit unauthorized access to, or to destroy, disrupt, disable, distort, or otherwise harm or impede in any manner any (i) computer, software, firmware, hardware, system, or network; or (ii) any application or function of any of the foregoing or the security, integrity, confidentiality, or use of any data processed thereby. +6. "**Order**" means: (i) the purchase order, order form, or other ordering document entered into by the Parties that incorporates this Agreement by reference; or (ii) if Customer registered for the Services through Supabase's online ordering process, the results of such online ordering process. +7. "**Personal Information**" means any information that, individually or in combination, does or can identify a specific individual or by or from which a specific individual may be identified, contacted, or located, including without limitation all data considered "personal data", "personally identifiable information", or something similar under applicable laws, rules, or regulations relating to data privacy. +8. "**Supabase IP**" means the Services, the Documentation, and any and all intellectual property provided to Customer or any Authorized User in connection with the foregoing. For the avoidance of doubt, Supabase IP includes Aggregated Data and any information, data, or other content derived from Supabase's provision of the Services but does not include Customer Data. +9. "**Services**" means Supabase's proprietary hosted software platform, as made available by Supabase to Authorized Users from time to time. +10. "**Subscription Period**" means the time period identified on the Order during which Customer's Authorized Users may access and use the Services. +11. "**Third-Party Products**" means any third-party products provided with, integrated with, or incorporated into the Services. +12. "**Usage Limitations**" means the usage limitations set forth in this Agreement and the Order, including without limitation any limitations on the number of Authorized Users (if any), and the applicable product, pricing, and support tiers agreed-upon by the Parties. + +## 2. Access and Use. + +### 1. Provision of Access. + +Subject to and conditioned on Customer's compliance with the terms and conditions of this Agreement, including without limitation the Usage Limitations, Supabase will make available to Customer during the Subscription Period, on a non-exclusive, non-transferable (except in compliance with Section 13.8), and non-sublicensable basis, access to and use of the Services, solely for use by Authorized Users. Such use is limited to Customer's internal business purposes and the features and functionalities specified in the Order. Supabase shall provide to Customer the necessary access credentials to allow Customer to access the Services. + +### 2. Documentation License. + +Subject to and conditioned on Customer's compliance with the terms and conditions of this Agreement, Supabase hereby grants to Customer a non-exclusive, non-transferable (except in compliance with Section 13.8), and non-sublicensable license to use the Documentation during the Subscription Period solely for Customer's internal business purposes in connection with its use of the Services. + +### 3. Use Restrictions. + +Customer shall not use the Services for any purposes beyond the scope of the access granted in this Agreement. Customer shall not at any time, directly or indirectly, and shall not permit any Authorized Users to: (i) copy, modify, or create derivative works of any Supabase IP, whether in whole or in part; (ii) rent, lease, lend, sell, license, sublicense, assign, distribute, publish, transfer, or otherwise make available the Services or Documentation to any third party; (iii) reverse engineer, disassemble, decompile, decode, adapt, or otherwise attempt to derive or gain access to any software component of the Services, in whole or in part; (iv) remove any proprietary notices from any Supabase IP; (v) use any Supabase IP in any manner or for any purpose that infringes, misappropriates, or otherwise violates any intellectual property right or other right of any person, or that violates any applicable law; (vi) access or use any Supabase IP for purposes of competitive analysis of Supabase or the Services, the development, provision, or use of a competing software service or product, or any other purpose that is to Supabase's detriment or commercial disadvantage; (vii) bypass or breach any security device or protection used by the Services or access or use the Services other than by an Authorized User through the use of valid access credentials; or (vii) input, upload, transmit, or otherwise provide to or through the Services any information or materials that are unlawful or injurious, or that contain, transmit, or activate any Harmful Code. + +### 4. Reservation of Rights. + +Supabase reserves all rights not expressly granted to Customer in this Agreement. Except for the limited rights and licenses expressly granted under this Agreement, nothing in this Agreement grants, by implication, waiver, estoppel, or otherwise, to Customer or any third party any intellectual property rights or other right, title, or interest in or to the Supabase IP. + +### 5. Suspension. + +Notwithstanding anything to the contrary in this Agreement, Supabase may temporarily suspend Customer's and any Authorized User's access to any portion or all of the Services if: (i) Supabase reasonably determines that (A) there is a threat or attack on any of the Supabase IP; (B) Customer's or any Authorized User's use of the Supabase IP disrupts or poses a security risk to the Supabase IP or to any other customer or vendor of Supabase; (C) Customer, or any Authorized User, is using the Supabase IP for fraudulent or illegal activities; (D) subject to applicable law, Customer has ceased to continue its business in the ordinary course, made an assignment for the benefit of creditors or similar disposition of its assets, or become the subject of any bankruptcy, reorganization, liquidation, dissolution, or similar proceeding; or (E) Supabase's provision of the Services to Customer or any Authorized User is prohibited by applicable law; (ii) any vendor of Supabase has suspended or terminated Supabase's access to or use of any Third-Party Products required to enable Customer to access the Services; or (iii) in accordance with Section 5.1 (any such suspension described in subclause (i), (ii), or (iii), a "**Service Suspension**"). Supabase shall use commercially reasonable efforts to provide written notice of any Service Suspension to Customer and to provide updates regarding resumption of access to the Services following any Service Suspension. Supabase shall use commercially reasonable efforts to resume providing access to the Services as soon as reasonably possible after the event giving rise to the Service Suspension is cured. Supabase will have no liability for any damage, liabilities, losses (including any loss of data or profits), or any other consequences that Customer or any Authorized User may incur as a result of a Service Suspension. + +### 6. Aggregated Data. + +Notwithstanding anything to the contrary in this Agreement, Supabase may monitor Customer's use of the Services and collect and compile Aggregated Data. As between Supabase and Customer, all right, title, and interest in Aggregated Data, and all intellectual property rights therein, belong to and are retained solely by Supabase. Customer acknowledges that Supabase may compile Aggregated Data based on Customer Data input into the Services. Customer agrees that Supabase may (i) make Aggregated Data available to third parties including its other customers in compliance with applicable law, and (ii) use Aggregated Data to the extent and in the manner permitted under applicable law. + +## 3. Customer Responsibilities. + +### 1. General. + +Customer is responsible and liable for all uses of the Services and Documentation resulting from access provided by Customer, directly or indirectly, whether such access or use is permitted by or in violation of this Agreement. Without limiting the generality of the foregoing, Customer is responsible for all acts and omissions of Authorized Users, and any act or omission by an Authorized User that would constitute a breach of this Agreement if taken by Customer will be deemed a breach of this Agreement by Customer. Customer shall use reasonable efforts to make all Authorized Users aware of this Agreement's provisions as applicable to such Authorized User's use of the Services and shall cause Authorized Users to comply with such provisions. + +### 2. Third-Party Products. + +Supabase may from time to time make Third-Party Products available to Customer or Supabase may allow for certain Third-Party Products to be integrated with the Services to allow for the transmission of Customer Data from such Third-Party Products into the Services. For purposes of this Agreement, such Third-Party Products are subject to their own terms and conditions. If Customer does not agree to abide by the applicable terms for any such Third-Party Products, then Customer should not install or use such Third-Party Products. By authorizing Supabase to transmit Customer Data from Third-Party Products into the Services, Customer represents and warrants to Supabase that it has all right, power, and authority to provide such authorization. + +### 3. Customer Control and Responsibility. + +Customer has and will retain sole responsibility for: (i) all Customer Data, including its content and use; (ii) all information, instructions, and materials provided by or on behalf of Customer or any Authorized User in connection with the Services; (iii) Customer's information technology infrastructure, including computers, software, databases, electronic systems (including database management systems), and networks, whether operated directly by Customer or through the use of third-party services ("**Customer Systems**"); (iv) the security and use of Customer's and its Authorized Users' access credentials; and (v) all access to and use of the Services directly or indirectly by or through the Customer Systems or its or its Authorized Users' access credentials, with or without Customer's knowledge or consent, including all results obtained from, and all conclusions, decisions, and actions based on, such access or use. + +## 4. Support. + +During the Subscription Period, Supabase will use commercially reasonable efforts to provide Customer with basic customer support via Supabase's standard support channels during Supabase's normal business hours. + +## 5. Fees and Taxes. + +### 1. Fees. + +Where paid for services are agreed between Supabase and Customer per the Order, Customer shall pay Supabase the fees ("**Fees**") identified in the Order without offset or deduction at the cadence identified in the Order (e.g., monthly or annually). Fees paid by Customer are non-refundable. If Customer fails to make any payment when due, and Customer has not notified Supabase in writing within ten (10) days of the payment becoming due and payable that the payment is subject to a good faith dispute, without limiting Supabase's other rights and remedies: (i) Supabase may charge interest on the undisputed past due amount at the rate of 1.5% per month, calculated daily and compounded monthly or, if lower, the highest rate permitted under applicable law; (ii) Customer shall reimburse Supabase for all reasonable costs incurred by Supabase in collecting any late payments or interest, including attorneys' fees, court costs, and collection agency fees; and (iii) if such failure continues for ten (10) days or more, Supabase may suspend Customer's and its Authorized Users' access to any portion or all of the Services until such amounts are paid in full. + +### 2. Taxes. + +All Fees and other amounts payable by Customer under this Agreement are exclusive of taxes and similar assessments. Customer is responsible for all sales, use, and excise taxes, and any other similar taxes, duties, and charges of any kind imposed by any federal, state, or local governmental or regulatory authority on any amounts payable by Customer hereunder, other than any taxes imposed on Supabase's income. To the extent that Supabase is required by law to pay any such taxes, duties, or other charges to any governmental or regulatory authority, Supabase may invoice Customer for such taxes, duties, or other charges and Customer will pay such invoiced amounts in accordance with this Agreement. + +## 6. Confidential Information. + +### 1. Definition. + +From time to time during the Subscription Period, either Party may disclose or make available to the other Party information about its business affairs, products, confidential intellectual property, trade secrets, third-party confidential information, and other sensitive or proprietary information, whether orally or in written, electronic, or other form or media that: (i) is marked, designated or otherwise identified as "confidential" or something similar at the time of disclosure or within a reasonable period of time thereafter; or (ii) would be considered confidential by a reasonable person given the nature of the information or the circumstances of its disclosure (collectively, "**Confidential Information**"). Except for Personal Information, Confidential Information does not include information that, at the time of disclosure is: (a) in the public domain; (b) known to the receiving Party at the time of disclosure; (c) rightfully obtained by the receiving Party on a non-confidential basis from a third party; or (d) independently developed by the receiving Party without use of, reference to, or reliance upon the disclosing Party's Confidential Information. + +### 2. Duty. + +The receiving Party shall not disclose the disclosing Party's Confidential Information to any person or entity, except to the receiving Party's employees, contractors, and agents who have a need to know the Confidential Information for the receiving Party to exercise its rights or perform its obligations hereunder ("**Representatives**"). The receiving Party will be responsible for all the acts and omissions of its Representatives as they relate to Confidential Information hereunder. Notwithstanding the foregoing, each Party may disclose Confidential Information to the limited extent required (i) in order to comply with the order of a court or other governmental body, or as otherwise necessary to comply with applicable law, provided that the Party making the disclosure pursuant to the order shall first have given written notice to the other Party and made a reasonable effort to obtain a protective order; or (ii) to establish a Party's rights under this Agreement, including to make required court filings. Further, notwithstanding the foregoing, each Party may disclose the terms and existence of this Agreement to its actual or potential investors, debtholders, acquirers, or merger partners under customary confidentiality terms. + +### 3. Return of Materials; Effects of Termination/Expiration. + +On the expiration or termination of the Agreement, the receiving Party shall promptly return to the disclosing Party all copies, whether in written, electronic, or other form or media, of the disclosing Party's Confidential Information, or destroy all such copies and certify in writing to the disclosing Party that such Confidential Information has been destroyed. Each Party's obligations of non-use and non-disclosure with regard to Confidential Information are effective as of the Effective Date and will expire three (3) years from the date of termination or expiration of this Agreement; provided, however, with respect to any Confidential Information that constitutes a trade secret (as determined under applicable law), such obligations of non-disclosure will survive the termination or expiration of this Agreement for as long as such Confidential Information remains subject to trade secret protection under applicable law. + +## 7. Personal Information. + +Customer will ensure that its Customer Data, and its use of such Customer Data, complies with this Agreement and any applicable law. Customer is responsible for properly configuring and using the Services and taking its own steps to maintain appropriate security, protection, and backup of Customer Data. Customer may not store or process protected health information (as defined in HIPAA) using the Services unless Customer signs a Business Associate Agreement with Supabase. Customer may not store any payment cardholder information using the Services without Supabase's prior written approval. + +## 8. Intellectual Property Ownership; Feedback. + +### 1. Supabase IP. + +Customer acknowledges that, as between Customer and Supabase, Supabase owns all right, title, and interest, including all intellectual property rights, in and to the Supabase IP and, with respect to Third-Party Products, the applicable third-party providers own all right, title, and interest, including all intellectual property rights, in and to the Third-Party Products. + +### 2. Customer Data. + +Supabase acknowledges that, as between Supabase and Customer, Customer owns all right, title, and interest, including all intellectual property rights, in and to the Customer Data. Customer hereby grants to Supabase a non-exclusive, royalty-free, worldwide license to reproduce, distribute, and otherwise use and display the Customer Data and perform all acts with respect to the Customer Data as may be necessary for Supabase to provide the Services to Customer, and a non-exclusive, perpetual, irrevocable, royalty-free, worldwide license to reproduce, distribute, modify, and otherwise use and display Customer Data incorporated within the Aggregated Data. Customer may export the Customer Data at any time through the features and functionalities made available via the Services. + +### 3. Feedback. + +If Customer or any of its employees or contractors sends or transmits any communications or materials to Supabase by mail, email, telephone, or otherwise, suggesting or recommending changes to the Supabase IP, including without limitation, new features or functionality relating thereto, or any comments, questions, suggestions, or the like ("**Feedback**"), Supabase is free to use such Feedback irrespective of any other obligation or limitation between the Parties governing such Feedback so long as Supabase does not identify Customer as the source of the Feedback without Customer's prior approval. + +## 9. Warranty Disclaimer. + +The Supabase IP is provided "as is" and Supabase +hereby disclaims all warranties, whether express, implied, statutory, or +otherwise. Supabase specifically disclaims all implied warranties of +merchantability, fitness for a particular purpose, title, and non-infringement, +and all warranties arising from course of dealing, usage, or trade practice. Supabase +makes no warranty of any kind that the Supabase IP, or any products or results +of the use thereof, will meet Customer’s or any other person’s requirements, +operate without interruption, achieve any intended result, be compatible or +work with any software, system or other services, or be secure, accurate, +complete, free of harmful code, or error free. + +## 10. Indemnification. + +### 1. Supabase Indemnification. + +1. Supabase shall indemnify, defend, and hold harmless Customer from and against any and all losses, damages, liabilities, costs (including reasonable attorneys' fees) ("**Losses**") incurred by Customer resulting from any third-party claim, suit, action, or proceeding ("**Third-Party Claim**") that the Services, or any use of the Services in accordance with this Agreement, infringes or misappropriates such third party's US copyrights or trade secrets; provided that Customer promptly notifies Supabase in writing of the claim, cooperates with Supabase, and allows Supabase sole authority to control the defense and settlement of such claim. +2. If such a claim is made or appears possible, Customer agrees to permit Supabase, at Supabase's sole discretion: to (i) modify or replace the Services, or component or part thereof, to make it non-infringing; or (ii) obtain the right for Customer to continue use. If Supabase determines that neither alternative is reasonably commercially available, Supabase may terminate this Agreement, in its entirety or with respect to the affected component or part, effective immediately on written notice to Customer. +3. This Section 10.1 will not apply to the extent that the alleged infringement arises from: (i) use of the Services in combination with data, software, hardware, equipment, or technology not provided by Supabase or authorized by Supabase in writing; (ii) modifications to the Services not made by Supabase; (iii) Customer Data; or (iv) Third-Party Products. + +### 2. Customer Indemnification. + +Customer shall indemnify, hold harmless, and, at Supabase's option, defend Supabase from and against any Losses resulting from any Third-Party Claim that the Customer Data, or any use of the Customer Data in accordance with this Agreement, infringes or misappropriates such third party's US intellectual property or other rights and any Third-Party Claims based on Customer's or any Authorized User's (i) negligence or willful misconduct; (ii) use of the Services in a manner not authorized by this Agreement; or (iii) use of the Services in combination with data, software, hardware, equipment or technology not provided by Supabase or authorized by Supabase in writing; in each case provided that Customer may not settle any Third-Party Claim against Supabase unless Supabase consents to such settlement, and further provided that Supabase will have the right, at its option, to defend itself against any such Third-Party Claim or to participate in the defense thereof by counsel of its own choice. + +### 3. Sole Remedy. + +This section 10.3 sets forth Customer's sole remedies and Supabase's sole liability and obligation for any actual, threatened, or alleged claims that the services infringe, misappropriate, or otherwise violate any intellectual property rights of any third party. + +## 11. Limitations of Liability. + +Except for: (i) a party’s breach of its confidentiality obligations; +(ii) a party’s indemnity obligations; or (iii) a party’s gross negligence, +fraud, or willful misconduct ("**Excluded Liabilities**"), (a) in no +event will either party be liable under or in connection with this agreement +under any legal or equitable theory, including breach of contract, tort +(including negligence), strict liability, and otherwise, for any: (1) +consequential, incidental, indirect, exemplary, special, enhanced, or punitive +damages; (2) increased costs, diminution in value or lost business, production, +revenues, or profits; (3) loss of goodwill or reputation; (4) use, inability to +use, loss, interruption, delay or recovery of any data, or breach of data or +system security; or (5) cost of replacement goods or services, in each case +regardless of whether such party was advised of the possibility of such losses +or damages or such losses or damages were otherwise foreseeable; and (b) in no +event will either party’s aggregate liability arising out of or related to this +agreement under any legal or equitable theory, including breach of contract, +tort (including negligence), strict liability, and otherwise exceed the total +amounts paid and/or payable to Supabase under this agreement in the twelve (12) +months immediately preceding the claim; provided that, notwithstanding the +foregoing, Supabase's aggregate liability arising out of or relating to any +excluded liabilities will not exceed three times (3x) the total amounts paid +and/or payable to Supabase by Customer under this agreement in the twelve (12) +months immediately preceding the claim. + +## 12. Subscription Period and Termination. + +### 1. Subscription Period. + +The initial term of this Agreement begins on the Effective Date and, unless terminated earlier pursuant to Section 12.2, will continue in effect for the period identified in the Order (the "**Initial Subscription Period**"). This Agreement will automatically renew for additional successive terms equal to the length of the Initial Subscription Period unless earlier terminated pursuant to this Agreement's express provisions or either Party gives the other Party written notice of non-renewal at least thirty (30) days prior to the expiration of the then-current term (each a "**Renewal Subscription Period**" and together with the Initial Subscription Period, the "**Subscription Period**").] + +#### 2. Termination. + +In addition to any other express termination right set forth in this Agreement: + +1. Supabase may terminate this Agreement, effective on written notice to Customer, if Customer: (i) fails to pay any amount when due hereunder, and such failure continues more than ten (10) calendar days after Supabase's delivery of written notice thereof; or (ii) breaches any of its obligations under Section 2.3 or Section 6; +2. either Party may terminate this Agreement, effective on written notice to the other Party, if the other Party materially breaches this Agreement, and such breach: (i) is incapable of cure; or (ii) being capable of cure, remains uncured thirty (30) calendar days after the non-breaching Party provides the breaching Party with written notice of such breach; or +3. either Party may terminate this Agreement, effective immediately upon written notice to the other Party, if the other Party: (i) becomes insolvent or is generally unable to pay, or fails to pay, its debts as they become due; (ii) files or has filed against it, a petition for voluntary or involuntary bankruptcy or otherwise becomes subject, voluntarily or involuntarily, to any proceeding under any domestic or foreign bankruptcy or insolvency law; (iii) makes or seeks to make a general assignment for the benefit of its creditors; or (iv) applies for or has appointed a receiver, trustee, custodian, or similar agent appointed by order of any court of competent jurisdiction to take charge of or sell any material portion of its property or business. + +### 3. Effect of Expiration or Termination. + +Upon expiration or earlier termination of this Agreement, Customer shall immediately discontinue use of the Supabase IP and, without limiting Customer's obligations under Section 6, Customer shall delete, destroy, or return all copies of the Supabase IP and certify in writing to the Supabase that the Supabase IP has been deleted or destroyed. No expiration or termination will affect Customer's obligation to pay all Fees that may have become due before such expiration or termination or entitle Customer to any refund. + +### 4. Survival. + +This Section 12.4 and Sections 1, 5, 6, 8, 9, 10, 11, and 13 survive any termination or expiration of this Agreement. No other provisions of this Agreement survive the expiration or earlier termination of this Agreement. + +## 13. Miscellaneous. + +### 1. Entire Agreement. + +This Agreement, together with any other documents incorporated herein by reference, constitutes the sole and entire agreement of the Parties with respect to the subject matter of this Agreement and supersedes all prior and contemporaneous understandings, agreements, and representations and warranties, both written and oral, with respect to such subject matter. In the event of any inconsistency between the statements made in the body of this Agreement, the related Exhibits, and any other documents incorporated herein by reference, the following order of precedence governs: (i) first, this Agreement; and (ii) second, any other documents incorporated herein by reference. + +### 2. Notices. + +All notices, requests, consents, claims, demands, waivers, and other communications hereunder (each, a "**Notice**") must be in writing and addressed to the Parties at the addresses set forth on the first page of this Agreement or as identified on the Order Form (or to such other address that may be designated by the Party giving Notice from time to time in accordance with this Section). All Notices must be delivered by personal delivery, nationally recognized signed for on delivery courier (with all fees pre-paid), or email (with confirmation of transmission). All email Notices to Supabase must be sent to [legal@supabase.io](mailto:legal@supabase.io). Except as otherwise provided in this Agreement, a Notice is effective only: (i) upon receipt by the receiving Party; and (ii) if the Party giving the Notice has complied with the requirements of this Section. + +### 3. Force Majeure. + +In no event shall either Party be liable to the other Party, or be deemed to have breached this Agreement, for any failure or delay in performing its obligations under this Agreement (except for any obligations to make payments), if and to the extent such failure or delay is caused by any circumstances beyond such Party's reasonable control, including but not limited to acts of God, flood, fire, earthquake, explosion, war, terrorism, invasion, riot or other civil unrest, strikes, labor stoppages or slowdowns or other industrial disturbances, or passage of law or any action taken by a governmental or public authority, including imposing an embargo. + +### 4. Amendment and Modification. + +Supabase may change this Agreement (except for any Orders) from time to time at its discretion. The date on which the Agreement was last modified will be updated at the top of this Agreement. Supabase will provide Customer with reasonable notice prior to any amendments or modifications taking effect, either by emailing the email address associated with Customer's account on the Services or by another method reasonably designed to provide notice to Customer. If Customer accesses or uses the Services after the effective date of the revised Agreement, such access and use will constitute Customer's acceptance of the revised Agreement beginning at the next Renewal Subscription Period or, if Customer enters into a new Order with Supabase, as of the date of execution of such Order. + +### 5. Waiver. + +No failure or delay by either Party in exercising any right or remedy available to it in connection with this Agreement will constitute a waiver of such right or remedy. No waiver under this Agreement will be effective unless made in writing and signed by an authorized representative of the Party granting the waiver. + +### 6. Severability. + +If any provision of this Agreement is invalid, illegal, or unenforceable in any jurisdiction, such invalidity, illegality, or unenforceability will not affect any other term or provision of this Agreement or invalidate or render unenforceable such term or provision in any other jurisdiction. Upon such determination that any term or other provision is invalid, illegal, or unenforceable, the Parties shall negotiate in good faith to modify this Agreement so as to effect their original intent as closely as possible in a mutually acceptable manner in order that the transactions contemplated hereby be consummated as originally contemplated to the greatest extent possible. + +### 7. Governing Law; Submission to Jurisdiction. + +This Agreement is governed by and construed in accordance with the internal laws of the State of California without giving effect to any choice or conflict of law provision or rule that would require or permit the application of the laws of any jurisdiction other than those of the State of California. Any legal suit, action, or proceeding arising out of or related to this Agreement or the licenses granted hereunder must be instituted in the federal courts of the United States or the courts of the State of California in each case located in San Francisco County, California and each Party irrevocably submits to the exclusive jurisdiction of such courts in any such suit, action, or proceeding. + +### 8. Assignment. + +Customer may not assign any of its rights or delegate any of its obligations hereunder, in each case whether voluntarily, involuntarily, by operation of law or otherwise, without the prior written consent of Supabase. Any purported assignment or delegation in violation of this Section will be null and void. No assignment or delegation will relieve the assigning or delegating Party of any of its obligations hereunder. This Agreement is binding upon and inures to the benefit of the Parties and their respective permitted successors and assigns. + +### 9. Export Regulation. + +The Services utilize software and technology that may be subject to US export control laws, including the US Export Administration Act and its associated regulations. Customer shall not, directly or indirectly, export, re-export, or release the Services or the underlying software or technology to, or make the Services or the underlying software or technology accessible from, any jurisdiction or country to which export, re-export, or release is prohibited by law, rule, or regulation. Customer shall comply with all applicable federal laws, regulations, and rules, and complete all required undertakings (including obtaining any necessary export license or other governmental approval), prior to exporting, re-exporting, releasing, or otherwise making the Services or the underlying software or technology available outside the US. + +### 10. US Government Rights. + +Each of the Documentation and the software components that constitute the Services is a "commercial item" as that term is defined at 48 C.F.R. § 2.101, consisting of "commercial computer software" and "commercial computer software documentation" as such terms are used in 48 C.F.R. § 12.212. Accordingly, if Customer is an agency of the US Government or any contractor therefor, Customer only receives those rights with respect to the Services and Documentation as are granted to all other end users, in accordance with (a) 48 C.F.R. § 227.7201 through 48 C.F.R. § 227.7204, with respect to the Department of Defense and their contractors, or (b) 48 C.F.R. § 12.212, with respect to all other US Government users and their contractors. + +### 11. Equitable Relief. + +Each Party acknowledges and agrees that a breach or threatened breach by such Party of any of its obligations under Section 6 or, in the case of Customer, Section 2.3, would cause the other Party irreparable harm for which monetary damages would not be an adequate remedy and agrees that, in the event of such breach or threatened breach, the other Party will be entitled to equitable relief, including a restraining order, an injunction, specific performance and any other relief that may be available from any court, without any requirement to post a bond or other security, or to prove actual damages or that monetary damages are not an adequate remedy. Such remedies are not exclusive and are in addition to all other remedies that may be available at law, in equity or otherwise. + +### 12. Publicity. + +Supabase may identify Customer as a user of the Services and may use Customer's name, logo, and other trademarks in Supabase's customer list, press releases, blog posts, advertisements, and website (and all use thereof and goodwill arising therefrom shall inure to the sole and exclusive benefit of Customer). Otherwise, neither Party may use the name, logo, or other trademarks of the other Party for any purpose without the other Party's prior written approval. diff --git a/apps/temp-docs/docs/dart/.gitkeep b/apps/temp-docs/docs/dart/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/apps/temp-docs/docs/dart/auth-onauthstatechange.mdx b/apps/temp-docs/docs/dart/auth-onauthstatechange.mdx new file mode 100644 index 00000000000..e495f9deeb2 --- /dev/null +++ b/apps/temp-docs/docs/dart/auth-onauthstatechange.mdx @@ -0,0 +1,72 @@ +--- +id: auth-onauthstatechange +title: "auth.onAuthStateChange()" +slug: auth-onauthstatechange +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Receive a notification every time an auth event happens. + + + + + + +```dart +final subscription = supabase.auth.onAuthStateChange((event, session) { + print(session?.user?.id); + // handle auth state change +}); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### Listen to auth changes + + + + + + + +```dart +final subscription = supabase.auth.onAuthStateChange((event, session) { + print(session?.user?.id); + // handle auth state change +}); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/auth-session.mdx b/apps/temp-docs/docs/dart/auth-session.mdx new file mode 100644 index 00000000000..361bb5d22fb --- /dev/null +++ b/apps/temp-docs/docs/dart/auth-session.mdx @@ -0,0 +1,66 @@ +--- +id: auth-session +title: "auth.session()" +slug: auth-session +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Returns the session data, if there is an active session. + + + + + + +```dart +final session = supabase.auth.session(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### Get the session data + + + + + + + +```dart +final session = supabase.auth.session(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/auth-signin.mdx b/apps/temp-docs/docs/dart/auth-signin.mdx new file mode 100644 index 00000000000..b991760a4dc --- /dev/null +++ b/apps/temp-docs/docs/dart/auth-signin.mdx @@ -0,0 +1,124 @@ +--- +id: auth-signin +title: "auth.signIn()" +slug: auth-signin +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Log in an existing user, or login via a third-party provider. + + + + + + +```dart +final res = await supabase.auth.signIn(email: 'example@email.com', password: 'example-password'); + +final user = res.data?.user; +final error = res.error; +``` + + + + + + + + + + +## Notes + +- A user can sign up via email, phone number. +- If you provide `email` without a `password`, the user will be sent a magic link. +- The magic link's destination URL is determined by the SITE_URL config variable. To change this, you can go to Authentication -> Settings on [app.supabase.io](https://app.supabase.io) +- Similarly, if you provide `phone` without a `password`, the user will be sent a one time password. +- If you are looking to sign users in with OAuth in Flutter apps, go to [`signInWithProvider()`](/docs/reference/dart/auth-signinwithprovider). + + + + + + + + + + +## Examples + +### Sign in with email. + + + + + + + +```dart +final res = await supabase.auth.signIn(email: 'example@email.com', password: 'example-password'); + +final user = res.data?.user; +final error = res.error; +``` + + + + + + +### Sign in with magic link. + +If email is provided, but no password is provided, the user will be sent a "magic link" to their email address, which they can click to open your application with a valid session. By default, a given user can only request a Magic Link once every 60 seconds. + + + + + +```dart +final res = await supabase.auth.signIn(email: 'example@email.com'); + +final error = res.error; +``` + + + + + + +### Get OAuth sign in URL. + +Passing provider parameter to `signIn()` will return a URL to sign your user in via OAuth. +If you are looking to sign in a user via OAuth on Flutter app, go to [`signInWithProvider()`](/docs/reference/dart/auth-signinwithprovider). + + + + + + +```dart +final res = await supabase.auth.signIn(provider: Provider.github); + +final url = res.data?.url; +final error = res.error; +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/auth-signinwithprovider.mdx b/apps/temp-docs/docs/dart/auth-signinwithprovider.mdx new file mode 100644 index 00000000000..62863ba012e --- /dev/null +++ b/apps/temp-docs/docs/dart/auth-signinwithprovider.mdx @@ -0,0 +1,129 @@ +--- +id: auth-signinwithprovider +title: "auth.signInWithProvider()" +slug: auth-signinwithprovider +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Signs the user in using third party OAuth providers. + + + + + + +```dart +final res = await supabase.auth.signInWithProvider(Provider.github); + +final error = res.error; +``` + + + + + + + + + + +## Notes + +- `auth.signInWithProvider()` is only available on `supabase_flutter` +- It will open the browser to the relevant login page. + + + + + + + + + + +## Examples + +### Sign in with provider. + + + + + + + +```dart +final res = await supabase.auth.signInWithProvider(Provider.github); + +final error = res.error; +``` + + + + + + +### With `redirectTo` + +Specify the redirect link to bring back the user via deeplink. +Note that `redirectTo` should be null for Flutter Web. + + + + + + +```dart +final res = await supabase.auth.signInWithProvider( + Provider.github, + options: AuthOptions( + redirectTo: kIsWeb + ? null + : 'io.supabase.flutter://reset-callback/'), +); + +final error = res.error; +``` + + + + + + +### With scopes + +If you need additional data from an OAuth provider, you can include a space-separated list of scopes in your request to get back an OAuth provider token. +You may also need to specify the scopes in the provider's OAuth app settings, depending on the provider. + + + + + + +```dart +const { user, session, error } = await supabase.auth.signIn({ + provider: 'github' +}, { + scopes: 'repo gist notifications' +}) +const oAuthToken = session.provider_token // use to access provider API +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/auth-signout.mdx b/apps/temp-docs/docs/dart/auth-signout.mdx new file mode 100644 index 00000000000..d1458aec554 --- /dev/null +++ b/apps/temp-docs/docs/dart/auth-signout.mdx @@ -0,0 +1,70 @@ +--- +id: auth-signout +title: "auth.signOut()" +slug: auth-signout +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Signs out the current user, if there is a logged in user. + + + + + + +```dart +final res = await supabase.auth.signOut(); + +final error = res.error; +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### Sign out + + + + + + + +```dart +final res = await supabase.auth.signOut(); + +final error = res.error; +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/auth-signup.mdx b/apps/temp-docs/docs/dart/auth-signup.mdx new file mode 100644 index 00000000000..f1a87c75440 --- /dev/null +++ b/apps/temp-docs/docs/dart/auth-signup.mdx @@ -0,0 +1,80 @@ +--- +id: auth-signup +title: "auth.signUp()" +slug: auth-signup +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Creates a new user. + + + + + + +```dart +final res = await supabase.auth.signUp('example@email.com', 'example-password'); + +final user = res.data?.user; +final error = res.error; +``` + + + + + + + + + + +## Notes + +- By default, the user will need to verify their email address before logging in. If you would like to change this, you can disable "Email Confirmations" by going to Authentication -> Settings on [app.supabase.io](https://app.supabase.io) +- If "Email Confirmations" is turned on, a `user` is returned but `session` will be null +- If "Email Confirmations" is turned off, both a `user` and a `session` will be returned +- When the user confirms their email address, they will be redirected to localhost:3000 by default. To change this, you can go to Authentication -> Settings on [app.supabase.io](https://app.supabase.io) + + + + + + + + + + +## Examples + +### Sign up. + + + + + + + +```dart +final res = await supabase.auth.signUp('example@email.com', 'example-password'); + +final user = res.data?.user; +final error = res.error; +``` + + + + + + +### Sign up with third-party providers. + +If you are using Flutter, you can sign up with OAuth providers using the [`signInWithProvider()`](/docs/reference/dart/auth-signinwithprovider) method available on `supabase_flutter`. \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/auth-update.mdx b/apps/temp-docs/docs/dart/auth-update.mdx new file mode 100644 index 00000000000..95451f08b8e --- /dev/null +++ b/apps/temp-docs/docs/dart/auth-update.mdx @@ -0,0 +1,76 @@ +--- +id: auth-update +title: "auth.update()" +slug: auth-update +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Updates user data, if there is a logged in user. + + + + + + +```dart +final res = await supabase.auth.update( + UserAttributes(data: {'hello': 'world'}) +); + +final error = res.error; +``` + + + + + + + + + + +## Notes + +It's generally better to store user data in a table inside your public schema (i.e. `public.users`). +Use the `update()` method if you have data which rarely changes or is specific only to the logged in user. + + + + + + + + + + +## Examples + +### Update a user's metadata. + + + + + + + +```dart +final res = await supabase.auth.update( + UserAttributes(data: {'hello': 'world'}) +); + +final error = res.error; +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/auth-user.mdx b/apps/temp-docs/docs/dart/auth-user.mdx new file mode 100644 index 00000000000..fb11208dea8 --- /dev/null +++ b/apps/temp-docs/docs/dart/auth-user.mdx @@ -0,0 +1,66 @@ +--- +id: auth-user +title: "auth.user()" +slug: auth-user +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Returns the user data, if there is a logged in user. + + + + + + +```dart +final user = supabase.auth.user(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### Get the logged in user + + + + + + + +```dart +final user = supabase.auth.user(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/containedby.mdx b/apps/temp-docs/docs/dart/containedby.mdx new file mode 100644 index 00000000000..0902ece9744 --- /dev/null +++ b/apps/temp-docs/docs/dart/containedby.mdx @@ -0,0 +1,145 @@ +--- +id: containedby +title: ".containedBy()" +slug: containedby +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + + + + + + + +```dart +final res = await supabase + .from('countries') + .select('name, id, main_exports') + .containedBy('main_exports', ['cars', 'food', 'machine']) + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .select('name, id, main_exports') + .containedBy('main_exports', ['cars', 'food', 'machine']) + .execute(); +``` + + + + + + +### With `update()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .update({ 'name': 'Mordor' }) + .containedBy('main_exports', ['orks', 'surveillance', 'evil']) + .execute(); +``` + + + + + + +### With `delete()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .delete() + .containedBy('main_exports', ['cars', 'food', 'machine']) + .execute(); +``` + + + + + + +### With `rpc()` + + + + + + + +```dart +// Only valid if the Stored Procedure returns a table type. +final res = await supabase + .rpc('echo_all_countries') + .containedBy('main_exports', ['cars', 'food', 'machine']) + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/contains.mdx b/apps/temp-docs/docs/dart/contains.mdx new file mode 100644 index 00000000000..c350feeecbc --- /dev/null +++ b/apps/temp-docs/docs/dart/contains.mdx @@ -0,0 +1,145 @@ +--- +id: contains +title: ".contains()" +slug: contains +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + + + + + + + +```dart +final res = await supabase + .from('countries') + .select('name, id, main_exports') + .contains('main_exports', ['oil']) + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .select('name, id, main_exports') + .contains('main_exports', ['oil']) + .execute(); +``` + + + + + + +### With `update()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .update({ 'name': 'Mordor' }) + .contains('main_exports', ['oil']) + .execute(); +``` + + + + + + +### With `delete()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .delete() + .contains('main_exports', ['oil']) + .execute(); +``` + + + + + + +### With `rpc()` + + + + + + + +```dart +// Only valid if the Stored Procedure returns a table type. +final res = await supabase + .rpc('echo_all_countries') + .contains('main_exports', ['oil']) + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/delete.mdx b/apps/temp-docs/docs/dart/delete.mdx new file mode 100644 index 00000000000..37b570eefa3 --- /dev/null +++ b/apps/temp-docs/docs/dart/delete.mdx @@ -0,0 +1,76 @@ +--- +id: delete +title: "Delete data: delete()" +slug: delete +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Performs a DELETE on the table. + + + + + + +```dart +final res = await supabase + .from('cities') + .delete() + .match({ 'id': 666 }) + .execute(); +``` + + + + + + + + + + +## Notes + +TODO update link to dart +- `delete()` should always be combined with [Filters](/docs/reference/javascript/using-filters) to target the item(s) you wish to delete. + + + + + + + + + + +## Examples + +### Delete records + + + + + + + +```dart +final res = await supabase + .from('cities') + .delete() + .match({ 'id': 666 }) + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/eq.mdx b/apps/temp-docs/docs/dart/eq.mdx new file mode 100644 index 00000000000..b631453c7f3 --- /dev/null +++ b/apps/temp-docs/docs/dart/eq.mdx @@ -0,0 +1,146 @@ +--- +id: eq +title: ".eq()" +slug: eq +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose value on the stated `column` exactly matches the specified `value`. + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .eq('name', 'The shire') + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .eq('name', 'The shire') + .execute(); +``` + + + + + + +### With `update()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .update({ 'name': 'Mordor' }) + .eq('name', 'San Francisco') + .execute(); +``` + + + + + + +### With `delete()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .delete() + .eq('name', 'Mordor') + .execute(); +``` + + + + + + +### With `rpc()` + + + + + + + +```dart +// Only valid if the Stored Procedure returns a table type. +final res = await supabase + .rpc('echo_all_cities') + .eq('name', 'San Francisco') + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/filter.mdx b/apps/temp-docs/docs/dart/filter.mdx new file mode 100644 index 00000000000..b637f533442 --- /dev/null +++ b/apps/temp-docs/docs/dart/filter.mdx @@ -0,0 +1,170 @@ +--- +id: filter +title: ".filter()" +slug: filter +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose `column` satisfies the filter. + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .filter('name', 'in', '("Paris","Tokyo")') + .execute(); +``` + + + + + + + + + + +## Notes + +- `.filter()` expects you to use the raw [PostgREST syntax](https://postgrest.org/en/stable/api.html#horizontal-filtering-rows) for the filter values, so it should only be used as an escape hatch in case other filters don't work. + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .filter('name', 'in', '("Paris","Tokyo")') + .execute(); +``` + + + + + + +### With `update()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .update({ 'name': 'Mordor' }) + .filter('name', 'in', '("Paris","Tokyo")') + .execute(); +``` + + + + + + +### With `delete()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .delete() + .filter('name', 'in', '("Paris","Tokyo")') + .execute(); +``` + + + + + + +### With `rpc()` + + + + + + + +```dart +// Only valid if the Stored Procedure returns a table type. +final res = await supabase + .rpc('echo_all_cities') + .filter('name', 'in', '("Paris","Tokyo")') +``` + + + + + + +### Filter embedded resources + + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, countries ( name )') + .filter('countries.name', 'in', '("France","Japan")') + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/getsubscriptions.mdx b/apps/temp-docs/docs/dart/getsubscriptions.mdx new file mode 100644 index 00000000000..1ddf8924852 --- /dev/null +++ b/apps/temp-docs/docs/dart/getsubscriptions.mdx @@ -0,0 +1,66 @@ +--- +id: getsubscriptions +title: "getSubscriptions()" +slug: getsubscriptions +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Returns an array of all your subscriptions. + + + + + + +```dart +final subscriptions = supabase.getSubscriptions(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### Get all subscriptions + + + + + + + +```dart +final subscriptions = supabase.getSubscriptions(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/gt.mdx b/apps/temp-docs/docs/dart/gt.mdx new file mode 100644 index 00000000000..4c211f5b871 --- /dev/null +++ b/apps/temp-docs/docs/dart/gt.mdx @@ -0,0 +1,146 @@ +--- +id: gt +title: ".gt()" +slug: gt +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose value on the stated `column` is greater than the specified `value`. + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .gt('country_id', 250) + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .gt('country_id', 250) + .execute(); +``` + + + + + + +### With `update()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .update({ 'name': 'Mordor' }) + .gt('country_id', 250) + .execute(); +``` + + + + + + +### With `delete()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .delete() + .gt('country_id', 250) + .execute(); +``` + + + + + + +### With `rpc()` + + + + + + + +```dart +// Only valid if the Stored Procedure returns a table type. +final res = await supabase + .rpc('echo_all_cities') + .gt('country_id', 250) + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/gte.mdx b/apps/temp-docs/docs/dart/gte.mdx new file mode 100644 index 00000000000..1effd302292 --- /dev/null +++ b/apps/temp-docs/docs/dart/gte.mdx @@ -0,0 +1,146 @@ +--- +id: gte +title: ".gte()" +slug: gte +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose value on the stated `column` is greater than or equal to the specified `value`. + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .gte('country_id', 250) + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .gte('country_id', 250) + .execute(); +``` + + + + + + +### With `update()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .update({ 'name': 'Mordor' }) + .gte('country_id', 250) + .execute(); +``` + + + + + + +### With `delete()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .delete() + .gte('country_id', 250) + .execute(); +``` + + + + + + +### With `rpc()` + + + + + + + +```dart +// Only valid if the Stored Procedure returns a table type. +final res = await supabase + .rpc('echo_all_cities') + .gte('country_id', 250) + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/ilike.mdx b/apps/temp-docs/docs/dart/ilike.mdx new file mode 100644 index 00000000000..35fa42c2602 --- /dev/null +++ b/apps/temp-docs/docs/dart/ilike.mdx @@ -0,0 +1,146 @@ +--- +id: ilike +title: ".ilike()" +slug: ilike +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose value in the stated `column` matches the supplied `pattern` (case insensitive). + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .ilike('name', '%la%') + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .ilike('name', '%la%') + .execute(); +``` + + + + + + +### With `update()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .update({ 'name': 'Mordor' }) + .ilike('name', '%la%') + .execute(); +``` + + + + + + +### With `delete()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .delete() + .ilike('name', '%la%') + .execute(); +``` + + + + + + +### With `rpc()` + + + + + + + +```dart +// Only valid if the Stored Procedure returns a table type. +final res = await supabase + .rpc('echo_all_cities') + .ilike('name', '%la%') + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/in_.mdx b/apps/temp-docs/docs/dart/in_.mdx new file mode 100644 index 00000000000..23d18ca4ed3 --- /dev/null +++ b/apps/temp-docs/docs/dart/in_.mdx @@ -0,0 +1,148 @@ +--- +id: in_ +title: ".in_()" +slug: in_ +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose value on the stated `column` is found on the specified `values`. + +`is_` and `in_` filter methods are suffixed with `_` to avoid collisions with reserved keywords. + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .in_('name', ['Rio de Janeiro', 'San Francisco']) + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .in_('name', ['Rio de Janeiro', 'San Francisco']) + .execute(); +``` + + + + + + +### With `update()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .update({ 'name': 'Mordor' }) + .in_('name', ['Rio de Janeiro', 'San Francisco']) + .execute(); +``` + + + + + + +### With `delete()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .delete() + .in_('name', ['Rio de Janeiro', 'San Francisco']) + .execute(); +``` + + + + + + +### With `rpc()` + + + + + + + +```dart +// Only valid if the Stored Procedure returns a table type. +final res = await supabase + .rpc('echo_all_cities') + .in_('name', ['Rio de Janeiro', 'San Francisco']) + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/index.mdx b/apps/temp-docs/docs/dart/index.mdx new file mode 100644 index 00000000000..acffea0ac94 --- /dev/null +++ b/apps/temp-docs/docs/dart/index.mdx @@ -0,0 +1,12 @@ +--- +id: index +title: "Getting started" +slug: getting-started +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + + +Supabase Dart. \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/initializing.mdx b/apps/temp-docs/docs/dart/initializing.mdx new file mode 100644 index 00000000000..87b3b493a6c --- /dev/null +++ b/apps/temp-docs/docs/dart/initializing.mdx @@ -0,0 +1,84 @@ +--- +id: initializing +title: "Initializing" +slug: initializing +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +## Dart +You can initialize a new Supabase client using the `SupabaseClient()` method. + +The Supabase client is your entrypoint to the rest of the Supabase functionality +and is the easiest way to interact with everything we offer within the Supabase ecosystem. + + +## Flutter + +For `supabase_flutter`, you will be using the static `initialize()` method on `Supabase` class. + + + + + + + + + + + + + + + + + + + + +## Examples + +### Dart SupabaseClient() + + + + + + + +```dart +final supabase = SupabaseClient('https://xyzcompany.supabase.co', 'public-anon-key'); +``` + + + + + + +### Flutter initialize() + + + + + + + +```dart title="main.dart" +Future main() async { + await Supabase.initialize(url: 'https://xyzcompany.supabase.co', anonKey: 'public-anon-key'); + runApp(MyApp()); +} +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/insert.mdx b/apps/temp-docs/docs/dart/insert.mdx new file mode 100644 index 00000000000..c5422081ee2 --- /dev/null +++ b/apps/temp-docs/docs/dart/insert.mdx @@ -0,0 +1,102 @@ +--- +id: insert +title: "Create data: insert()" +slug: insert +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Performs an INSERT into the table. + + + + + + +```dart +final res = await supabase + .from('cities') + .insert([ + {'name': 'The Shire', 'country_id': 554} + ]).execute(); +``` + + + + + + + + + + +## Notes + +- By default, every time you run `insert()`, the client library will make a `select` to return the full record. +This is convenient, but it can also cause problems if your Policies are not configured to allow the `select` operation. +If you are using Row Level Security and you are encountering problems, try setting the `returning` param to `minimal`. + + + + + + + + + + +## Examples + +### Create a record + + + + + + + +```dart +final res = await supabase + .from('cities') + .insert([ + {'name': 'The Shire', 'country_id': 554} + ]).execute(); +``` + + + + + + +### Bulk create + + + + + + + +```dart +final res = await supabase + .from('cities') + .insert([ + {'name': 'The Shire', 'country_id': 554}, + {'name': 'Rohan', 'country_id': 555}, + ]).execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/installing.mdx b/apps/temp-docs/docs/dart/installing.mdx new file mode 100644 index 00000000000..290000ecd86 --- /dev/null +++ b/apps/temp-docs/docs/dart/installing.mdx @@ -0,0 +1,32 @@ +--- +id: installing +title: "Installing" +slug: installing +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +## Dart + +Dart libraries are built and supported by the community. + +```bash +dart pub add supabase +``` + +Find the source code on [GitHub](https://github.com/supabase/supabase-dart). + +## Flutter + +For Flutter project, you can use [supabase_flutter](https://github.com/supabase/supabase-flutter). + +```bash +flutter pub add supabase_flutter +``` + +`supabase_flutter` plugin uses `supabase` plugin internally, and it adds some Flutter specific functionality such as handling deeplinks coming back from magic link verifications. +If you are creating a Flutter application, we recommend using `supabase_flutter` instead of `supabase`. + +For the most part `supabase_flutter` shares the same API as `supabase` with few exceptions such as initialization or OAuth sign in. \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/is_.mdx b/apps/temp-docs/docs/dart/is_.mdx new file mode 100644 index 00000000000..c1d5af70780 --- /dev/null +++ b/apps/temp-docs/docs/dart/is_.mdx @@ -0,0 +1,148 @@ +--- +id: is_ +title: ".is_()" +slug: is_ +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +A check for exact equality (null, true, false), finds all rows whose value on the stated `column` exactly match the specified `value`. + +`is_` and `in_` filter methods are suffixed with `_` to avoid collisions with reserved keywords. + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .is_('name', null) + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .is_('name', null) + .execute(); +``` + + + + + + +### With `update()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .update({ 'name': 'Mordor' }) + .is_('name', null) + .execute(); +``` + + + + + + +### With `delete()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .delete() + .is_('name', null) + .execute(); +``` + + + + + + +### With `rpc()` + + + + + + + +```dart +// Only valid if the Stored Procedure returns a table type. +final res = await supabase + .rpc('echo_all_cities') + .is_('name', null) + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/like.mdx b/apps/temp-docs/docs/dart/like.mdx new file mode 100644 index 00000000000..4fae8c3c8c7 --- /dev/null +++ b/apps/temp-docs/docs/dart/like.mdx @@ -0,0 +1,191 @@ +--- +id: like +title: ".like()" +slug: like +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose value in the stated `column` matches the supplied `pattern` (case sensitive). + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .like('name', '%la%') + .execute(); +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + column + + + required + + + object + +

      +
      + +The column to filter on. + +
      + +
    • + + +
    • +

      + + pattern + + + required + + + string + +

      +
      + +The pattern to filter with. + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .like('name', '%la%') + .execute(); +``` + + + + + + +### With `update()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .update({ 'name': 'Mordor' }) + .like('name', '%la%') + .execute(); +``` + + + + + + +### With `delete()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .delete() + .like('name', '%la%') + .execute(); +``` + + + + + + +### With `rpc()` + + + + + + + +```dart +// Only valid if the Stored Procedure returns a table type. +final res = await supabase + .rpc('echo_all_cities') + .like('name', '%la%') + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/limit.mdx b/apps/temp-docs/docs/dart/limit.mdx new file mode 100644 index 00000000000..2a22a201405 --- /dev/null +++ b/apps/temp-docs/docs/dart/limit.mdx @@ -0,0 +1,99 @@ +--- +id: limit +title: "limit()" +slug: limit +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Limits the result with the specified count. + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .limit(1) + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .limit(1) + .execute(); +``` + + + + + + +### With embedded resources + + + + + + + +```dart +final res = await supabase + .from('countries') + .select('name, cities(name)') + .eq('name', 'United States') + .limit(1, foreignTable: 'cities' ) + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/lt.mdx b/apps/temp-docs/docs/dart/lt.mdx new file mode 100644 index 00000000000..b98cd7589b7 --- /dev/null +++ b/apps/temp-docs/docs/dart/lt.mdx @@ -0,0 +1,146 @@ +--- +id: lt +title: ".lt()" +slug: lt +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose value on the stated `column` is less than the specified `value`. + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .lt('country_id', 250) + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .lt('country_id', 250) + .execute(); +``` + + + + + + +### With `update()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .update({ 'name': 'Mordor' }) + .lt('country_id', 250) + .execute(); +``` + + + + + + +### With `delete()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .delete() + .lt('country_id', 250) + .execute(); +``` + + + + + + +### With `rpc()` + + + + + + + +```dart +// Only valid if the Stored Procedure returns a table type. +final res = await supabase + .rpc('echo_all_cities') + .lt('country_id', 250) + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/lte.mdx b/apps/temp-docs/docs/dart/lte.mdx new file mode 100644 index 00000000000..8337ccc9a89 --- /dev/null +++ b/apps/temp-docs/docs/dart/lte.mdx @@ -0,0 +1,191 @@ +--- +id: lte +title: ".lte()" +slug: lte +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose value on the stated `column` is less than or equal to the specified `value`. + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .lte('country_id', 250) + .execute(); +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + column + + + required + + + object + +

      +
      + +The column to filter on. + +
      + +
    • + + +
    • +

      + + value + + + required + + + object + +

      +
      + +The value to filter with. + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .lte('country_id', 250) + .execute(); +``` + + + + + + +### With `update()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .update({ 'name': 'Mordor' }) + .lte('country_id', 250) + .execute(); +``` + + + + + + +### With `delete()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .delete() + .lte('country_id', 250) + .execute(); +``` + + + + + + +### With `rpc()` + + + + + + + +```dart +// Only valid if the Stored Procedure returns a table type. +final res = await supabase + .rpc('echo_all_cities') + .lte('country_id', 250) + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/match.mdx b/apps/temp-docs/docs/dart/match.mdx new file mode 100644 index 00000000000..69f9a18c47d --- /dev/null +++ b/apps/temp-docs/docs/dart/match.mdx @@ -0,0 +1,146 @@ +--- +id: match +title: ".match()" +slug: match +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose columns match the specified `query` object. + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .match({'name': 'Beijing', 'country_id': 156}) + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .match({'name': 'Beijing', 'country_id': 156}) + .execute(); +``` + + + + + + +### With `update()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .update({ 'name': 'Mordor' }) + .match({'name': 'Beijing', 'country_id': 156}) + .execute(); +``` + + + + + + +### With `delete()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .delete() + .match({'name': 'Beijing', 'country_id': 156}) + .execute(); +``` + + + + + + +### With `rpc()` + + + + + + + +```dart +// Only valid if the Stored Procedure returns a table type. +final res = await supabase + .rpc('echo_all_cities') + .match({'name': 'Beijing', 'country_id': 156}) + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/neq.mdx b/apps/temp-docs/docs/dart/neq.mdx new file mode 100644 index 00000000000..92654e12b36 --- /dev/null +++ b/apps/temp-docs/docs/dart/neq.mdx @@ -0,0 +1,146 @@ +--- +id: neq +title: ".neq()" +slug: neq +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose value on the stated `column` doesn't match the specified `value`. + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .neq('name', 'The shire') + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .neq('name', 'The shire') + .execute(); +``` + + + + + + +### With `update()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .update({ 'name': 'Mordor' }) + .neq('name', 'San Francisco') + .execute(); +``` + + + + + + +### With `delete()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .delete() + .neq('name', 'Mordor') + .execute(); +``` + + + + + + +### With `rpc()` + + + + + + + +```dart +// Only valid if the Stored Procedure returns a table type. +final res = await supabase + .rpc('echo_all_cities') + .neq('name', 'Lagos') + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/not.mdx b/apps/temp-docs/docs/dart/not.mdx new file mode 100644 index 00000000000..cc41b7f6038 --- /dev/null +++ b/apps/temp-docs/docs/dart/not.mdx @@ -0,0 +1,146 @@ +--- +id: not +title: ".not()" +slug: not +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows which doesn't satisfy the filter. + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .not('name', 'eq', 'Paris') + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .not('name', 'eq', 'Paris') + .execute(); +``` + + + + + + +### With `update()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .update({ 'name': 'Mordor' }) + .not('name', 'eq', 'Paris') + .execute(); +``` + + + + + + +### With `delete()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .delete() + .not('name', 'eq', 'Paris') + .execute(); +``` + + + + + + +### With `rpc()` + + + + + + + +```dart +// Only valid if the Stored Procedure returns a table type. +final res = await supabase + .rpc('echo_all_cities) + .not('name', 'eq', 'Paris') + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/or.mdx b/apps/temp-docs/docs/dart/or.mdx new file mode 100644 index 00000000000..4852ebc659b --- /dev/null +++ b/apps/temp-docs/docs/dart/or.mdx @@ -0,0 +1,98 @@ +--- +id: or +title: ".or()" +slug: or +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows satisfying at least one of the filters. + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .or('id.eq.20,id.eq.30') + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .or('id.eq.20,id.eq.30') + .execute(); +``` + + + + + + +### Use `or` with `and` + + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .or('id.gt.20,and(name.eq.New Zealand,name.eq.France)') + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/order.mdx b/apps/temp-docs/docs/dart/order.mdx new file mode 100644 index 00000000000..18daaacd619 --- /dev/null +++ b/apps/temp-docs/docs/dart/order.mdx @@ -0,0 +1,99 @@ +--- +id: order +title: "order()" +slug: order +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Orders the result with the specified column. + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .order('id', ascending: false ) + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .order('id', ascending: false ) + .execute(); +``` + + + + + + +### With embedded resources + + + + + + + +```dart +final res = await supabase + .from('countries') + .select('name, cities(name)') + .eq('name', 'United States') + .order('name', foreignTable: 'cities') + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/overlaps.mdx b/apps/temp-docs/docs/dart/overlaps.mdx new file mode 100644 index 00000000000..d7ca0f689b2 --- /dev/null +++ b/apps/temp-docs/docs/dart/overlaps.mdx @@ -0,0 +1,145 @@ +--- +id: overlaps +title: ".overlaps()" +slug: overlaps +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + + + + + + + +```dart +final res = await supabase + .from('countries') + .select('name, id, main_exports') + .overlaps('main_exports', ['computers', 'minerals']) + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .select('name, id, main_exports') + .overlaps('main_exports', ['computers', 'minerals']) + .execute(); +``` + + + + + + +### With `update()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .update({ 'name': 'Mordor' }) + .overlaps('main_exports', ['computers', 'minerals']) + .execute(); +``` + + + + + + +### With `delete()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .delete() + .overlaps('main_exports', ['computers', 'minerals']) + .execute(); +``` + + + + + + +### With `rpc()` + + + + + + + +```dart +// Only valid if the Stored Procedure returns a table type. +final res = await supabase + .rpc('echo_all_countries') + .overlaps('main_exports', ['computers', 'minerals']) + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/range.mdx b/apps/temp-docs/docs/dart/range.mdx new file mode 100644 index 00000000000..affd16f8583 --- /dev/null +++ b/apps/temp-docs/docs/dart/range.mdx @@ -0,0 +1,74 @@ +--- +id: range +title: "range()" +slug: range +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Limits the result to rows within the specified range, inclusive. + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .range(0,3) + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .range(0,3) + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/rangeadjacent.mdx b/apps/temp-docs/docs/dart/rangeadjacent.mdx new file mode 100644 index 00000000000..f31f4f505e9 --- /dev/null +++ b/apps/temp-docs/docs/dart/rangeadjacent.mdx @@ -0,0 +1,145 @@ +--- +id: rangeadjacent +title: ".rangeAdjacent()" +slug: rangeadjacent +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + + + + + + + +```dart +final res = await supabase + .from('countries') + .select('name, id, population_range_millions') + .rangeAdjacent('population_range_millions', '[70, 185]') + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .select('name, id, population_range_millions') + .rangeAdjacent('population_range_millions', '[70, 185]') + .execute(); +``` + + + + + + +### With `update()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .update({ 'name': 'Mordor' }) + .rangeAdjacent('population_range_millions', '[70, 185]') + .execute(); +``` + + + + + + +### With `delete()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .delete() + .rangeAdjacent('population_range_millions', '[70, 185]') + .execute(); +``` + + + + + + +### With `rpc()` + + + + + + + +```dart +// Only valid if the Stored Procedure returns a table type. +final res = await supabase + .rpc('echo_all_countries') + .rangeAdjacent('population_range_millions', '[70, 185]') + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/rangegt.mdx b/apps/temp-docs/docs/dart/rangegt.mdx new file mode 100644 index 00000000000..6ddd4b34ed8 --- /dev/null +++ b/apps/temp-docs/docs/dart/rangegt.mdx @@ -0,0 +1,145 @@ +--- +id: rangegt +title: ".rangeGt()" +slug: rangegt +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + + + + + + + +```dart +final res = await supabase + .from('countries') + .select('name, id, population_range_millions') + .rangeGt('population_range_millions', '[150, 250]') + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .select('name, id, population_range_millions') + .rangeGt('population_range_millions', '[150, 250]') + .execute(); +``` + + + + + + +### With `update()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .update({ 'name': 'Mordor' }) + .rangeGt('population_range_millions', '[150, 250]') + .execute(); +``` + + + + + + +### With `delete()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .delete() + .rangeGt('population_range_millions', '[150, 250]') + .execute(); +``` + + + + + + +### With `rpc()` + + + + + + + +```dart +// Only valid if the Stored Procedure returns a table type. +final res = await supabase + .rpc('echo_all_countries') + .rangeGt('population_range_millions', '[150, 250]') + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/rangegte.mdx b/apps/temp-docs/docs/dart/rangegte.mdx new file mode 100644 index 00000000000..3a674440832 --- /dev/null +++ b/apps/temp-docs/docs/dart/rangegte.mdx @@ -0,0 +1,145 @@ +--- +id: rangegte +title: ".rangeGte()" +slug: rangegte +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + + + + + + + +```dart +final res = await supabase + .from('countries') + .select('name, id, population_range_millions') + .rangeGte('population_range_millions', '[150, 250]') + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .select('name, id, population_range_millions') + .rangeGte('population_range_millions', '[150, 250]') + .execute(); +``` + + + + + + +### With `update()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .update({ 'name': 'Mordor' }) + .rangeGte('population_range_millions', '[150, 250]') + .execute(); +``` + + + + + + +### With `delete()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .delete() + .rangeGte('population_range_millions', '[150, 250]') + .execute(); +``` + + + + + + +### With `rpc()` + + + + + + + +```dart +// Only valid if the Stored Procedure returns a table type. +final res = await supabase + .rpc('echo_all_countries') + .rangeGte('population_range_millions', '[150, 250]') + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/rangelt.mdx b/apps/temp-docs/docs/dart/rangelt.mdx new file mode 100644 index 00000000000..43cb40cbd68 --- /dev/null +++ b/apps/temp-docs/docs/dart/rangelt.mdx @@ -0,0 +1,145 @@ +--- +id: rangelt +title: ".rangeLt()" +slug: rangelt +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + + + + + + + +```dart +final res = await supabase + .from('countries') + .select('name, id, population_range_millions') + .rangeLt('population_range_millions', '[150, 250]') + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .select('name, id, population_range_millions') + .rangeLt('population_range_millions', '[150, 250]') + .execute(); +``` + + + + + + +### With `update()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .update({ 'name': 'Mordor' }) + .rangeLt('population_range_millions', '[150, 250]') + .execute(); +``` + + + + + + +### With `delete()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .delete() + .rangeLt('population_range_millions', '[150, 250]') + .execute(); +``` + + + + + + +### With `rpc()` + + + + + + + +```dart +// Only valid if the Stored Procedure returns a table type. +final res = await supabase + .rpc('echo_all_countries') + .rangeLt('population_range_millions', '[150, 250]') + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/rangelte.mdx b/apps/temp-docs/docs/dart/rangelte.mdx new file mode 100644 index 00000000000..c673b888736 --- /dev/null +++ b/apps/temp-docs/docs/dart/rangelte.mdx @@ -0,0 +1,145 @@ +--- +id: rangelte +title: ".rangeLte()" +slug: rangelte +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + + + + + + + +```dart +final res = await supabase + .from('countries') + .select('name, id, population_range_millions') + .rangeLte('population_range_millions', '[150, 250]') + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .select('name, id, population_range_millions') + .rangeLte('population_range_millions', '[150, 250]') + .execute(); +``` + + + + + + +### With `update()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .update({ 'name': 'Mordor' }) + .rangeLte('population_range_millions', '[150, 250]') + .execute(); +``` + + + + + + +### With `delete()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .delete() + .rangeLte('population_range_millions', '[150, 250]') + .execute(); +``` + + + + + + +### With `rpc()` + + + + + + + +```dart +// Only valid if the Stored Procedure returns a table type. +final res = await supabase + .rpc('echo_all_countries') + .rangeLte('population_range_millions', [150, 250]) + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/removesubscription.mdx b/apps/temp-docs/docs/dart/removesubscription.mdx new file mode 100644 index 00000000000..76504e2880d --- /dev/null +++ b/apps/temp-docs/docs/dart/removesubscription.mdx @@ -0,0 +1,67 @@ +--- +id: removesubscription +title: "removeSubscription()" +slug: removesubscription +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Removes an active subscription and returns the number of open connections. + + + + + + +```dart +supabase.removeSubscription(mySubscription); +``` + + + + + + + + + + +## Notes + +- Removing subscriptions is a great way to maintain the performance of your project's database. Supabase will automatically handle cleanup 30 seconds after a user is disconnected, but unused subscriptions may cause degradation as more users are simultaneously subscribed. + + + + + + + + + + +## Examples + +### Remove a subscription + + + + + + + +```dart +supabase.removeSubscription(mySubscription); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/reset-password-email.mdx b/apps/temp-docs/docs/dart/reset-password-email.mdx new file mode 100644 index 00000000000..27086ba3c05 --- /dev/null +++ b/apps/temp-docs/docs/dart/reset-password-email.mdx @@ -0,0 +1,114 @@ +--- +id: reset-password-email +title: "Reset Password (Email)" +slug: reset-password-email +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Sends a reset request to an email address. + + + + + + +```dart +final res = await supabase.auth.api.resetPasswordForEmail('user@example.com'); + +final error = res.error; +``` + + + + + + + + + + +## Notes + +Sends a reset request to an email address. + +When the user clicks the reset link in the email they will be forwarded to: + +`#access_token=x&refresh_token=y&expires_in=z&token_type=bearer&type=recovery` + +Your app must detect `type=recovery` in the fragment and display a password reset form to the user. + +You should then use the access_token in the url and new password to update the user as follows: + +```dart +final res = await supabase.auth.api.updateUser( + accessToken, + UserAttributes(password: 'NEW_PASSWORD'), +); +``` + + + + + + + + + + +## Examples + +### Reset password + + + + + + + +```dart +final res = await supabase.auth.api.resetPasswordForEmail('user@example.com'); + +final error = res.error; +``` + + + + + + +### Reset password for Flutter + + + + + + + +You can pass `redirectTo` to open the app via deeplink when user opens the password reset email. +```dart +final res = await supabase.auth.api.resetPasswordForEmail( + 'user@example.com', + options: AuthOptions(redirectTo: kIsWeb + ? null + : 'io.supabase.flutter://reset-callback/'), +); + +final error = res.error; +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/rpc.mdx b/apps/temp-docs/docs/dart/rpc.mdx new file mode 100644 index 00000000000..f24ef39b765 --- /dev/null +++ b/apps/temp-docs/docs/dart/rpc.mdx @@ -0,0 +1,119 @@ +--- +id: rpc +title: "Stored Procedures: rpc()" +slug: rpc +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +You can call stored procedures as a "Remote Procedure Call". + +That's a fancy way of saying that you can put some logic into your database then call it from anywhere. +It's especially useful when the logic rarely changes - like password resets and updates. + + + + + + +```dart +final res = await supabase + .rpc('hello_world') + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### Call a stored procedure + +This is an example invoking a stored procedure. + + + + + +```dart +final res = await supabase + .rpc('hello_world') + .execute(); +``` + + + + + + +### With Parameters + + + + + + + +```dart +final res = await supabase + .rpc('echo_city', params: { 'name': 'The Shire' }) + .execute(); +``` + + + + + + +### With count option + +You can specify a count option to get the row count along with your data. +Allowed values for count option are `exact`, `planned` and `estimated`. + + + + + + +```dart +final res = await supabase + .rpc('hello_world') + .execute(count: CountOption.exact); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/select.mdx b/apps/temp-docs/docs/dart/select.mdx new file mode 100644 index 00000000000..15037ea81b6 --- /dev/null +++ b/apps/temp-docs/docs/dart/select.mdx @@ -0,0 +1,272 @@ +--- +id: select +title: "Fetch data: select()" +slug: select +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Performs vertical filtering with SELECT. + + + + + + +```dart +final res = await supabase + .from('cities') + .select() + .execute(); + +final data = res.data; +final error = res.error; +``` + + + + + + + + + + +## Notes + +- By default, Supabase projects will return a maximum of 1,000 rows. This setting can be changed in Project API Settings. It's recommended that you keep it low to limit the payload size of accidental or malicious requests. You can use `range()` queries to paginate through your data. +- `select()` can be combined with [Modifiers](/docs/reference/dart/using-modifiers) +- `select()` can be combined with [Filters](/docs/reference/dart/using-filters) + + + + + + + + + + +## Examples + +### Getting your data + + + + + + + +```dart +final res = await supabase + .from('cities') + .select() + .execute(); + +final data = res.data; +final error = res.error; +``` + + + + + + +### Selecting specific columns + +You can select specific fields from your tables. + + + + + +```dart +final res = await supabase + .from('cities') + .select('name') + .execute(); +``` + + + + + + +### Query foreign tables + +If your database has relationships, you can query related tables too. + + + + + +```dart +final res = await supabase + .from('countries') + .select(''' + name, + cities ( + name + ) + ''') + .execute(); +``` + + + + + + +### Query the same foreign table multiple times + +Sometimes you will need to query the same foreign table twice. +In this case, you can use the name of the joined column to identify +which join you intend to use. For convenience, you can also give an +alias for each column. For example, if we had a shop of products, +and we wanted to get the supplier and the purchaser at the same time +(both in the users) table: + + + + + + +```dart +final res = await supabase + .from('products') + .select(''' + id, + supplier:supplier_id ( name ), + purchaser:purchaser_id ( name ) + ''') + .execute(); +``` + + + + + + +### Filtering with inner joins + +If you want to filter a table based on a child table's values you can use the `!inner()` function. For example, if you wanted +to select all rows in a `message` table which belong to a user with the `username` "Jane": + + + + + + + +``` +Not yet implemented +``` + + + + + + +### Querying with count option + +You can get the number of rows by using the count option. +Allowed values for count option are [exact](https://postgrest.org/en/stable/api.html#exact-count), [planned](https://postgrest.org/en/stable/api.html#planned-count) and [estimated](https://postgrest.org/en/stable/api.html#estimated-count). + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name') + .execute(count: CountOption.exact); + +final count = res.count; +``` + + + + + + +### Querying JSON data + +If you have data inside of a JSONB column, you can apply select +and query filters to the data values. Postgres offers a +[number of operators](https://www.postgresql.org/docs/current/functions-json.html) +for querying JSON data. Also see +[PostgREST docs](http://postgrest.org/en/v7.0.0/api.html#json-columns) for more details. + + + + + + +```dart +final res = await supabase + .from('users') + .select(''' + id, name, + address->street + ''') + .eq('address->postcode', 90210) + .execute(); +``` + + + + + + +### Return data as CSV + +By default the data is returned in JSON format, however you can also request for it to be returned as Comma Separated Values. + + + + + + +```dart +final res = await supabase + .from('users') + .select() + .csv() + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/single.mdx b/apps/temp-docs/docs/dart/single.mdx new file mode 100644 index 00000000000..8d201ae0dca --- /dev/null +++ b/apps/temp-docs/docs/dart/single.mdx @@ -0,0 +1,74 @@ +--- +id: single +title: "single()" +slug: single +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Retrieves only one row from the result. Result must be one row (e.g. using limit), otherwise this will result in an error. + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .single() + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .single() + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/storage-createbucket.mdx b/apps/temp-docs/docs/dart/storage-createbucket.mdx new file mode 100644 index 00000000000..01ea9fa63b0 --- /dev/null +++ b/apps/temp-docs/docs/dart/storage-createbucket.mdx @@ -0,0 +1,73 @@ +--- +id: storage-createbucket +title: "createBucket()" +slug: storage-createbucket +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Creates a new Storage bucket + + + + + + +```dart +final res = await supabase + .storage + .createBucket('avatars'); +``` + + + + + + + + + + +## Notes + +- Policy permissions required: + - `buckets` permissions: `insert` + - `objects` permissions: none + + + + + + + + + + +## Examples + +### Create bucket + + + + + + + +```dart +final res = await supabase + .storage + .createBucket('avatars'); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/storage-deletebucket.mdx b/apps/temp-docs/docs/dart/storage-deletebucket.mdx new file mode 100644 index 00000000000..60a020ac22b --- /dev/null +++ b/apps/temp-docs/docs/dart/storage-deletebucket.mdx @@ -0,0 +1,73 @@ +--- +id: storage-deletebucket +title: "deleteBucket()" +slug: storage-deletebucket +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Deletes an existing bucket. A bucket can't be deleted with existing objects inside it. You must first `empty()` the bucket. + + + + + + +```dart +final res = await supabase + .storage + .deleteBucket('avatars'); +``` + + + + + + + + + + +## Notes + +- Policy permissions required: + - `buckets` permissions: `select` and `delete` + - `objects` permissions: none + + + + + + + + + + +## Examples + +### Delete bucket + + + + + + + +```dart +final res = await supabase + .storage + .deleteBucket('avatars'); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/storage-emptybucket.mdx b/apps/temp-docs/docs/dart/storage-emptybucket.mdx new file mode 100644 index 00000000000..0476cb9d25c --- /dev/null +++ b/apps/temp-docs/docs/dart/storage-emptybucket.mdx @@ -0,0 +1,73 @@ +--- +id: storage-emptybucket +title: "emptyBucket()" +slug: storage-emptybucket +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Removes all objects inside a single bucket. + + + + + + +```dart +final res = await supabase + .storage + .emptyBucket('avatars'); +``` + + + + + + + + + + +## Notes + +- Policy permissions required: + - `buckets` permissions: `select` + - `objects` permissions: `select` and `delete` + + + + + + + + + + +## Examples + +### Empty bucket + + + + + + + +```dart +final res = await supabase + .storage + .emptyBucket('avatars'); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/storage-from-createsignedurl.mdx b/apps/temp-docs/docs/dart/storage-from-createsignedurl.mdx new file mode 100644 index 00000000000..9609d9a96c6 --- /dev/null +++ b/apps/temp-docs/docs/dart/storage-from-createsignedurl.mdx @@ -0,0 +1,79 @@ +--- +id: storage-from-createsignedurl +title: "from.createSignedUrl()" +slug: storage-from-createsignedurl +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Create signed url to download file without requiring permissions. This URL can be valid for a set number of seconds. + + + + + + +```dart +final res = await supabase + .storage + .from('avatars') + .createSignedUrl('avatar1.png', 60); + +final signedURL = res.data; +``` + + + + + + + + + + +## Notes + +- Policy permissions required: + - `buckets` permissions: none + - `objects` permissions: `select` + + + + + + + + + + +## Examples + +### Create Signed URL + + + + + + + +```dart +final res = await supabase + .storage + .from('avatars') + .createSignedUrl('avatar1.png', 60); + +final signedURL = res.data; +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/storage-from-download.mdx b/apps/temp-docs/docs/dart/storage-from-download.mdx new file mode 100644 index 00000000000..f5173ee7804 --- /dev/null +++ b/apps/temp-docs/docs/dart/storage-from-download.mdx @@ -0,0 +1,75 @@ +--- +id: storage-from-download +title: "from.download()" +slug: storage-from-download +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Downloads a file. + + + + + + +```dart +final res = await supabase + .storage + .from('avatars') + .download('avatar1.png'); +``` + + + + + + + + + + +## Notes + +- Policy permissions required: + - `buckets` permissions: none + - `objects` permissions: `select` + + + + + + + + + + +## Examples + +### Download file + + + + + + + +```dart +final res = await supabase + .storage + .from('avatars') + .download('avatar1.png'); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/storage-from-getpublicurl.mdx b/apps/temp-docs/docs/dart/storage-from-getpublicurl.mdx new file mode 100644 index 00000000000..0629c3576bf --- /dev/null +++ b/apps/temp-docs/docs/dart/storage-from-getpublicurl.mdx @@ -0,0 +1,80 @@ +--- +id: storage-from-getpublicurl +title: "from.getPublicUrl()" +slug: storage-from-getpublicurl +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Retrieve URLs for assets in public buckets + + + + + + +```dart +final res = supabase + .storage + .from('public-bucket') + .getPublicUrl('avatar1.png'); + +final publicURL = res.data; +``` + + + + + + + + + + +## Notes + +- The bucket needs to be set to public, either via [updateBucket()](/docs/reference/javascript/storage-updatebucket) or by going to Storage on [app.supabase.io](https://app.supabase.io), clicking the overflow menu on a bucket and choosing "Make public" +- Policy permissions required: + - `buckets` permissions: none + - `objects` permissions: none + + + + + + + + + + +## Examples + +### Returns the URL for an asset in a public bucket + + + + + + + +```dart +final res = supabase + .storage + .from('public-bucket') + .getPublicUrl('avatar1.png'); + +final publicURL = res.data; +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/storage-from-list.mdx b/apps/temp-docs/docs/dart/storage-from-list.mdx new file mode 100644 index 00000000000..36c9dc50985 --- /dev/null +++ b/apps/temp-docs/docs/dart/storage-from-list.mdx @@ -0,0 +1,75 @@ +--- +id: storage-from-list +title: "from.list()" +slug: storage-from-list +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Lists all the files within a bucket. + + + + + + +```dart +final res = await supabase + .storage + .from('avatars') + .list(); +``` + + + + + + + + + + +## Notes + +- Policy permissions required: + - `buckets` permissions: none + - `objects` permissions: `select` + + + + + + + + + + +## Examples + +### List files in a bucket + + + + + + + +```dart +final res = await supabase + .storage + .from('avatars') + .list(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/storage-from-move.mdx b/apps/temp-docs/docs/dart/storage-from-move.mdx new file mode 100644 index 00000000000..7c14443d94a --- /dev/null +++ b/apps/temp-docs/docs/dart/storage-from-move.mdx @@ -0,0 +1,75 @@ +--- +id: storage-from-move +title: "from.move()" +slug: storage-from-move +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Moves an existing file, optionally renaming it at the same time. + + + + + + +```dart +final res = await supabase + .storage + .from('avatars') + .move('public/avatar1.png', 'private/avatar2.png'); +``` + + + + + + + + + + +## Notes + +- Policy permissions required: + - `buckets` permissions: none + - `objects` permissions: `update` and `select` + + + + + + + + + + +## Examples + +### Move file + + + + + + + +```dart +final res = await supabase + .storage + .from('avatars') + .move('public/avatar1.png', 'private/avatar2.png'); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/storage-from-remove.mdx b/apps/temp-docs/docs/dart/storage-from-remove.mdx new file mode 100644 index 00000000000..083be494c4e --- /dev/null +++ b/apps/temp-docs/docs/dart/storage-from-remove.mdx @@ -0,0 +1,75 @@ +--- +id: storage-from-remove +title: "from.remove()" +slug: storage-from-remove +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Deletes files within the same bucket + + + + + + +```dart +final res = await supabase + .storage + .from('avatars') + .remove(['avatar1.png']); +``` + + + + + + + + + + +## Notes + +- Policy permissions required: + - `buckets` permissions: none + - `objects` permissions: `delete` and `select` + + + + + + + + + + +## Examples + +### Delete file + + + + + + + +```dart +final res = await supabase + .storage + .from('avatars') + .remove(['avatar1.png']); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/storage-from-update.mdx b/apps/temp-docs/docs/dart/storage-from-update.mdx new file mode 100644 index 00000000000..cbe7ccccfd9 --- /dev/null +++ b/apps/temp-docs/docs/dart/storage-from-update.mdx @@ -0,0 +1,83 @@ +--- +id: storage-from-update +title: "from.update()" +slug: storage-from-update +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Replaces an existing file at the specified path with a new one. + + + + + + +```dart +final avatarFile = File('path/to/file'); +final res = await supabase + .storage + .from('avatars') + .update('public/avatar1.png', avatarFile, fileOptions: FileOptions( + cacheControl: '3600', + upsert: false + )); +``` + + + + + + + + + + +## Notes + +- Policy permissions required: + - `buckets` permissions: none + - `objects` permissions: `update` and `select` + + + + + + + + + + +## Examples + +### Update file + + + + + + + +```dart +final avatarFile = File('path/to/file'); +final res = await supabase + .storage + .from('avatars') + .update('public/avatar1.png', avatarFile, fileOptions: FileOptions( + cacheControl: '3600', + upsert: false + )); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/storage-from-upload.mdx b/apps/temp-docs/docs/dart/storage-from-upload.mdx new file mode 100644 index 00000000000..59b18350554 --- /dev/null +++ b/apps/temp-docs/docs/dart/storage-from-upload.mdx @@ -0,0 +1,152 @@ +--- +id: storage-from-upload +title: "from.upload()" +slug: storage-from-upload +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Uploads a file to an existing bucket. + + + + + + +```dart +final avatarFile = File('path/to/file'); +final res = await supabase + .storage + .from('avatars') + .upload('public/avatar1.png', avatarFile, fileOptions: FileOptions( + cacheControl: '3600', + upsert: false + )); +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + path + + + required + + + string + +

      +
      + +The relative file path. Should be of the format `folder/subfolder/filename.png`. The bucket must already exist before attempting to upload. + +
      + +
    • + + +
    • +

      + + fileBody + + + required + + + ArrayBuffer | ArrayBufferView | Blob | Buffer | File | FormData | ReadableStream | ReadableStream | URLSearchParams | string + +

      +
      + +The body of the file to be stored in the bucket. + +
      + +
    • + + +
    • +

      + + fileOptions + + + optional + + + FileOptions + +

      +
      + +HTTP headers. +`cacheControl`: string, the `Cache-Control: max-age=` seconds value. +`contentType`: string, the `Content-Type` header value. Should be specified if using a `fileBody` that is neither `Blob` nor `File` nor `FormData`, otherwise will default to `text/plain;charset=UTF-8`. +`upsert`: boolean, whether to perform an upsert. + +
      + +
    • + +
    + + +## Notes + +- Policy permissions required: + - `buckets` permissions: none + - `objects` permissions: `insert` + + + + + + + + + + +## Examples + +### Upload file + + + + + + + +```dart +final avatarFile = File('path/to/file'); +final res = await supabase + .storage + .from('avatars') + .upload('public/avatar1.png', avatarFile, fileOptions: FileOptions( + cacheControl: '3600', + upsert: false + )); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/storage-getbucket.mdx b/apps/temp-docs/docs/dart/storage-getbucket.mdx new file mode 100644 index 00000000000..77608338562 --- /dev/null +++ b/apps/temp-docs/docs/dart/storage-getbucket.mdx @@ -0,0 +1,97 @@ +--- +id: storage-getbucket +title: "getBucket()" +slug: storage-getbucket +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Retrieves the details of an existing Storage bucket. + + + + + + +```dart +final res = await supabase + .storage + .getBucket('avatars') +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + id + + + required + + + string + +

      +
      + +The unique identifier of the bucket you would like to retrieve. + +
      + +
    • + +
    + + +## Notes + +- Policy permissions required: + - `buckets` permissions: `select` + - `objects` permissions: none + + + + + + + + + + +## Examples + +### Get bucket + + + + + + + +```dart +final res = await supabase + .storage + .getBucket('avatars') +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/storage-listbuckets.mdx b/apps/temp-docs/docs/dart/storage-listbuckets.mdx new file mode 100644 index 00000000000..c6b8d028480 --- /dev/null +++ b/apps/temp-docs/docs/dart/storage-listbuckets.mdx @@ -0,0 +1,73 @@ +--- +id: storage-listbuckets +title: "listBuckets()" +slug: storage-listbuckets +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Retrieves the details of all Storage buckets within an existing product. + + + + + + +```dart +final res = await supabase + .storage + .listBuckets() +``` + + + + + + + + + + +## Notes + +- Policy permissions required: + - `buckets` permissions: `select` + - `objects` permissions: none + + + + + + + + + + +## Examples + +### List buckets + + + + + + + +```dart +final res = await supabase + .storage + .listBuckets() +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/storage-updatebucket.mdx b/apps/temp-docs/docs/dart/storage-updatebucket.mdx new file mode 100644 index 00000000000..c89037e2f2d --- /dev/null +++ b/apps/temp-docs/docs/dart/storage-updatebucket.mdx @@ -0,0 +1,73 @@ +--- +id: storage-updatebucket +title: "updateBucket()" +slug: storage-updatebucket +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Updates a new Storage bucket + + + + + + +```dart +final res = await supabase + .storage + .updateBucket('avatars', { public: false }); +``` + + + + + + + + + + +## Notes + +- Policy permissions required: + - `buckets` permissions: `update` + - `objects` permissions: none + + + + + + + + + + +## Examples + +### Update bucket + + + + + + + +```dart +final res = await supabase + .storage + .updateBucket('avatars', { public: false }); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/stream.mdx b/apps/temp-docs/docs/dart/stream.mdx new file mode 100644 index 00000000000..167b41e13c4 --- /dev/null +++ b/apps/temp-docs/docs/dart/stream.mdx @@ -0,0 +1,147 @@ +--- +id: stream +title: "stream()" +slug: stream +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Notifies of data at the queried table. + + + + + + +```dart +supabase + .from('countries') + .stream() + .execute(); +``` + + + + + + + + + + +## Notes + +- `stream()` will emit the initial data as well as any further change on the database as `Stream` of `List>` by combining Postgrest and Realtime. + + + + + + + + + + +## Examples + +### Listening to a specific table + + + + + + + +```dart +supabase + .from('countries') + .stream() + .execute(); +``` + + + + + + +### Listening to a specific rows within a table + +You can listen to individual rows using the format `{table}:{col}=eq.{val}` - where `{col}` is the column name, and `{val}` is the value which you want to match. +This syntax is the as how you can filter data in Realtime + + + + + + +```dart +supabase + .from('countries:id=eq.120') + .stream() + .execute(); +``` + + + + + + +### With `order()` + + + + + + + +```dart +supabase + .from('countries') + .stream() + .order('name', ascending: false) + .execute(); +``` + + + + + + +### With `limit()` + + + + + + + +```dart +supabase + .from('countries') + .stream() + .order('name', ascending: false) + .limit(10) + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/subscribe.mdx b/apps/temp-docs/docs/dart/subscribe.mdx new file mode 100644 index 00000000000..6c109f64659 --- /dev/null +++ b/apps/temp-docs/docs/dart/subscribe.mdx @@ -0,0 +1,237 @@ +--- +id: subscribe +title: "on().subscribe()" +slug: subscribe +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Subscribe to realtime changes in your database. + + + + + + +```dart +final mySubscription = supabase + .from('countries') + .on(SupabaseEventTypes.all, (payload) { + // Handle realtime payload + }) + .subscribe(); +``` + + + + + + + + + + +## Notes + +- Realtime is disabled by default for new Projects for better database performance and security. You can turn it on by [managing replication](/docs/guides/api#managing-realtime). +- If you want to receive the "previous" data for updates and deletes, you will need to set `REPLICA IDENTITY` to `FULL`, like this: `ALTER TABLE your_table REPLICA IDENTITY FULL;` + + + + + + + + + + +## Examples + +### Listen to all database changes + + + + + + + +```dart +final mySubscription = supabase + .from('countries') + .on(SupabaseEventTypes.all, (payload) { + // Handle realtime payload + }) + .subscribe(); +``` + + + + + + +### Listening to a specific table + + + + + + + +```dart +final mySubscription = supabase + .from('countries') + .on(SupabaseEventTypes.all, (payload) { + // Handle realtime payload + }) + .subscribe(); +``` + + + + + + +### Listening to inserts + + + + + + + +```dart +final mySubscription = supabase + .from('countries') + .on(SupabaseEventTypes.insert, (payload) { + // Handle realtime payload + }) + .subscribe(); +``` + + + + + + +### Listening to updates + +By default, Supabase will send only the updated record. If you want to receive the previous values as well you can +enable full replication for the table you are listening too: + +```sql +alter table "your_table" replica identity full; +``` + + + + + + +```dart +final mySubscription = supabase + .from('countries') + .on(SupabaseEventTypes.update, (payload) { + // Handle realtime payload + }) + .subscribe(); +``` + + + + + + +### Listening to deletes + +By default, Supabase does not send deleted records. If you want to receive the deleted record you can +enable full replication for the table you are listening too: + +```sql +alter table "your_table" replica identity full; +``` + + + + + + +```dart +final mySubscription = supabase + .from('countries') + .on(SupabaseEventTypes.delete, (payload) { + // Handle realtime payload + }) + .subscribe(); +``` + + + + + + +### Listening to multiple events + +You can chain listeners if you want to listen to multiple events for each table. + + + + + +```dart +final mySubscription = supabase + .from('countries') + .on(SupabaseEventTypes.insert, handleInsert) + .on(SupabaseEventTypes.delete, handleDelete) + .subscribe(); +``` + + + + + + +### Listening to row level changes + +You can listen to individual rows using the format `{table}:{col}=eq.{val}` - where `{col}` is the column name, and `{val}` is the value which you want to match. + + + + + +```dart +final mySubscription = supabase + .from('countries:id=eq.200') + .on(SupabaseEventTypes.update, handleRecordUpdated) + .subscribe(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/textsearch.mdx b/apps/temp-docs/docs/dart/textsearch.mdx new file mode 100644 index 00000000000..edda6a8dd14 --- /dev/null +++ b/apps/temp-docs/docs/dart/textsearch.mdx @@ -0,0 +1,147 @@ +--- +id: textsearch +title: ".textSearch()" +slug: textsearch +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose tsvector value on the stated `column` matches to_tsquery(query). + + + + + + + + + + + + + + + + + + + + +## Examples + +### Text search + + + + + + + +```dart +final res = await supabase + .from('quotes') + .select('catchphrase') + .textSearch('catchphrase', "'fat' & 'cat'", + config: 'english' + ) + .execute(); +``` + + + + + + +### Basic normalization + +Uses PostgreSQL's `plainto_tsquery` function. + + + + + +```dart +final res = await supabase + .from('quotes') + .select('catchphrase') + .textSearch('catchphrase', "'fat' & 'cat'", + type: TextSearchType.plain, + config: 'english' + ) + .execute(); +``` + + + + + + +### Full normalization + +Uses PostgreSQL's `phraseto_tsquery` function. + + + + + +```dart +final res = await supabase + .from('quotes') + .select('catchphrase') + .textSearch('catchphrase', "'fat' & 'cat'", + type: TextSearchType.phrase, + config: 'english' + ) + .execute(); +``` + + + + + + +### Full normalization + +Uses PostgreSQL's `websearch_to_tsquery` function. +This function will never raise syntax errors, which makes it possible to use raw user-supplied input for search, and can be used +with advanced operators. + +- `unquoted text`: text not inside quote marks will be converted to terms separated by & operators, as if processed by plainto_tsquery. +- `"quoted text"`: text inside quote marks will be converted to terms separated by <-> operators, as if processed by phraseto_tsquery. +- `OR`: the word “or” will be converted to the | operator. +- `-`: a dash will be converted to the ! operator. + + + + + + +```dart +final res = await supabase + .from('quotes') + .select('catchphrase') + .textSearch('catchphrase', "'fat or cat'", + type: TextSearchType.websearch, + config: 'english' + ) + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/update.mdx b/apps/temp-docs/docs/dart/update.mdx new file mode 100644 index 00000000000..18519852ff0 --- /dev/null +++ b/apps/temp-docs/docs/dart/update.mdx @@ -0,0 +1,109 @@ +--- +id: update +title: "Modify data: update()" +slug: update +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Performs an UPDATE on the table. + + + + + + +```dart +final res = await supabase + .from('cities') + .update({ 'name': 'Middle Earth' }) + .match({ 'name': 'Auckland' }) + .execute(); +``` + + + + + + + + + + +## Notes + +TODO update the link to dart +- `update()` should always be combined with [Filters](/docs/reference/javascript/using-filters) to target the item(s) you wish to update. + + + + + + + + + + +## Examples + +### Updating your data + + + + + + + +```dart +final res = await supabase + .from('cities') + .update({ 'name': 'Middle Earth' }) + .match({ 'name': 'Auckland' }) + .execute(); +``` + + + + + + +### Updating JSON data + +Postgres offers a +[number of operators](https://www.postgresql.org/docs/current/functions-json.html) +for working with JSON data. Right now it is only possible to update an entire JSON document, +but we are [working on ideas](https://github.com/PostgREST/postgrest/issues/465) for updating individual keys. + + + + + + +```dart +final res = await supabase + .from('users') + .update({ + 'address': { + 'street': 'Melrose Place', + 'postcode': 90210 + } + }) + .eq('address->postcode', 90210) + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/upsert.mdx b/apps/temp-docs/docs/dart/upsert.mdx new file mode 100644 index 00000000000..085eab75a02 --- /dev/null +++ b/apps/temp-docs/docs/dart/upsert.mdx @@ -0,0 +1,128 @@ +--- +id: upsert +title: "Upsert data: upsert()" +slug: upsert +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Performs an UPSERT into the table. + + + + + + +```dart +final res = await supabase + .from('messages') + .upsert({ 'id': 3, 'message': 'foo', 'username': 'supabot' }) + .execute(); +``` + + + + + + + + + + +## Notes + +- Primary keys should be included in the data payload in order for an update to work correctly. +- Primary keys must be natural, not surrogate. There are however, [workarounds](https://github.com/PostgREST/postgrest/issues/1118) for surrogate primary keys. + + + + + + + + + + +## Examples + +### Upsert your data + + + + + + + +```dart +final res = await supabase + .from('messages') + .upsert({ 'id': 3, 'message': 'foo', 'username': 'supabot' }) + .execute(); +``` + + + + + + +### Upserting into tables with constraints + +Running the following will cause supabase to upsert data into the `users` table. +If the username 'supabot' already exists, the `onConflict` argument tells supabase to overwrite that row +based on the column passed into `onConflict`. + + + + + + +```dart +final res = await supabase + .from('users') + .upsert({ 'username': 'supabot' }, { 'onConflict': 'username' }) + .execute(); +``` + + + + + + +### Return the exact number of rows + +Allowed values for count option are `exact`, `planned` and `estimated`. + + + + + + +```dart +final res = await supabase + .from('users') + .upsert({ + 'id': 3, + 'message': 'foo', + 'username': 'supabot' + }) + .execute(count: CountOption.exact); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/using-filters.mdx b/apps/temp-docs/docs/dart/using-filters.mdx new file mode 100644 index 00000000000..3296a3ee251 --- /dev/null +++ b/apps/temp-docs/docs/dart/using-filters.mdx @@ -0,0 +1,44 @@ +--- +id: using-filters +title: "Using Filters" +slug: using-filters +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Filters can be used on `select()`, `update()`, and `delete()` queries. + +If a Stored Procedure returns a table response, you can also apply filters. + +### Applying Filters + +You must apply your filters to the end of your query. For example: + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .eq('name', 'The Shire') // Correct + .execute(); + +final res = await supabase + .from('cities') + .eq('name', 'The Shire') // Incorrect + .select('name, country_id') + .execute(); +``` + +### Chaining + +Filters can be chained together to produce advanced queries. For example: + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .gte('population', 1000) + .lt('population', 10000) + .execute(); +``` \ No newline at end of file diff --git a/apps/temp-docs/docs/dart/using-modifiers.mdx b/apps/temp-docs/docs/dart/using-modifiers.mdx new file mode 100644 index 00000000000..8aefaf43501 --- /dev/null +++ b/apps/temp-docs/docs/dart/using-modifiers.mdx @@ -0,0 +1,13 @@ +--- +id: using-modifiers +title: "Using Modifiers" +slug: using-modifiers +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Modifiers can be used on `select()` queries. + +If a Stored Procedure returns a table response, you can also apply modifiers to the `rpc()` function. \ No newline at end of file diff --git a/apps/temp-docs/docs/faqs.mdx b/apps/temp-docs/docs/faqs.mdx new file mode 100644 index 00000000000..3131951766b --- /dev/null +++ b/apps/temp-docs/docs/faqs.mdx @@ -0,0 +1,28 @@ +--- +title: 'FAQs' +description: 'Supabase frequently asked questions' +--- + +# FAQs + +### Have you built `[Firebase feature]` yet? +We're building as fast as we can! And we are even adding a few things that Firebase doesn't have, as we go. Here are the features we have built: + +- A dashboard/UI for spinning up and managing your database in less than one minute. +- User authentication to sign up users and edit access rules on your database. +- Real-time database listeners. +- JavaScript library and APIs. +- Functions (kinda). These exist as database stored procedures, which can be written in SQL, JavaScript, Python, and Java. + +### How can you be a Firebase alternative if you're built with a relational database? + +We started Supabase because we love the functionality of Firebase, but we personally experienced the scaling issues that many others experienced. We chose Postgres because it's well-trusted and it has phenomenal scalability. Our goal is to make Postgres as easy to use as Firebase, so that you no longer have to choose between usability and scalability. Also, we're sure that once you start using Postgres, you'll love it more than any other database. + +### How do I host Supabase? +Supabase is an amalgamation of five open source tools (and growing). Some of these tools are made by Supabase (like our [Realtime Server](https://github.com/supabase/realtime)), some we support indirectly (like [PostgREST](http://postgrest.org/en/v7.0.0/)), and some are third-party tools (like [Kong](https://github.com/Kong/kong)). All of the tools we use in Supabase are MIT, Apache 2.0, or PostgreSQL licensed. You can use the docker-compose script [here](https://github.com/supabase/supabase/tree/master/docker) to build Supabase on your own environment, and find detailed instructions [here](https://supabase.com/docs/guides/hosting/overview). + +### Do you support `[some other database]`? +At the moment, we only support PostgreSQL. It's unlikely we'll ever move away from Postgres; however, you can [vote on a new database](https://github.com/supabase/supabase/issues/6) if you want us to start development. + +### Do you have a library for `[some other language]`? +We currently have a JavaScript library. You can [vote on a new client library](https://github.com/supabase/supabase/issues/5) for your favorite language. diff --git a/apps/temp-docs/docs/going-into-prod.mdx b/apps/temp-docs/docs/going-into-prod.mdx new file mode 100644 index 00000000000..9f93fe8a95d --- /dev/null +++ b/apps/temp-docs/docs/going-into-prod.mdx @@ -0,0 +1,53 @@ +--- +id: going-into-prod +title: Going into Prod Checklist +description: 'Things to do before making your app publicly available' +--- + +# Going into Prod Checklist + +After developing your project, and deciding it's time to Go Live With Real Users, you should run through this checklist to ensure that your project is: + +- secure +- won't falter under the expected load +- remains available whilst in production + +## Security + +- Ensure RLS is enabled + - Tables that do not have RLS enabled with reasonable policies allow any client to access and modify their data. This is unlikely to be what you want in the majority of cases. + - [Learn more about RLS](/docs/guides/auth/row-level-security) +- Ensure replication is disabled for tables containing sensitive data: + - Today, Realtime does not respect RLS policies and any client with your anon key can listen to changes on tables where replication is enabled. + - Go to the Database > Replication page in the Supabase Dashboard to manage these settings + - We are launching [RLS for realtime](https://github.com/supabase/walrus) soon, but in the meantime you should only use it for tables containing public data (scoreboards, blog posts, etc.) +- Enable 2FA on Github + - Since your Github account gives you administrative rights to your Supabase project, you should protect it with a strong password and 2FA using a U2F key or a TOTP app. +- Ensure email confirmations are enabled in the Auth > Settings page +- Use a custom SMTP server for auth emails so that your users can see that the mails are coming from a trusted domain (preferably the same domain that your app is hosted on). (grab SMTP credentials from any major email provider such as SendGrid, AWS SES, etc.) +- Think hard about how *you* would abuse your service as an attacker, and mitigate +- Review these [common cybersecurity threats](https://auth0.com/docs/security/prevent-threats) + +## Performance + +- Ensure that you have suitable indices to cater to your common query patterns + - [learn more about indexes in postgres](https://www.enterprisedb.com/postgres-tutorials/overview-postgresql-indexes) + - pg_stat_statements can help you [identify hot or slow queries](https://www.virtual-dba.com/blog/postgresql-performance-identifying-hot-and-slow-queries/) +- Perform load testing (preferably on a staging env) + - tools like [k6](https://k6.io/) can simulate traffic from many different users +- If you find you require more resources, contact support@supabase.io to upgrade to PAYG for bigger servers + +## Availability + +- Use your own SMTP credentials so that you have full control over the deliverability of your transactional auth emails (see Auth > Settings) + - you can grab SMTP credentials from any major email provider such as SendGrid, AWS SES, etc. + - the default rate limit for auth emails provided by Supabase is 30 new users per hour, if doing a major public announcement you will likely require more than this +- If your application is on the free tier and is **not** expected to be queried at least once every 7 days, then it may be paused by Supabase to save on server resources + - you can restore paused projects from the Supabase dashboard + - upgrade to Pro to guarantee that your project will not be paused for inactivity +- Database backups are not available for download on the free tier + - You can set up your own backup systems using tools like [pg_dump](https://www.postgresqltutorial.com/postgresql-backup-database/) or [wal-g](https://github.com/wal-g/wal-g) + - Nightly backups for Pro tier projects are available on the Supabase dashboard for up to 7 days +- upgrading to the Supabase Pro Tier will give you access to email support on support@supabase.io + +This checklist is always growing so be sure to check back frequently, and also feel free to suggest additions and amendments by making a PR on [Github](https://github.com/supabase/supabase). diff --git a/apps/temp-docs/docs/guides.mdx b/apps/temp-docs/docs/guides.mdx new file mode 100644 index 00000000000..cf29b36bd48 --- /dev/null +++ b/apps/temp-docs/docs/guides.mdx @@ -0,0 +1,17 @@ +--- +id: guides +title: Overview +description: Common task +--- + +## Guides + +### Database + +These guides help you unleash the power of PostgreSQL, the world's most advanced open source database. + +### Auth + +Authenticating users isn't the most exciting job for most developers, so Supabase makes it quick and simple, while maintaining security and performance. + + diff --git a/apps/temp-docs/docs/guides/apis.mdx b/apps/temp-docs/docs/guides/apis.mdx new file mode 100644 index 00000000000..cac8fc84f2c --- /dev/null +++ b/apps/temp-docs/docs/guides/apis.mdx @@ -0,0 +1,192 @@ +--- +title: 'APIs' +description: 'Supabase APIs' +--- + +# APIs + +## Overview + +Supabase generates APIs directly from your database schema. The API is: + +- Instant and auto-generated: as you update your database the changes are immediately accessible through your API. +- Self documenting: Supabase generates documentation in the Dashboard which updates as you make database changes. +- Secure: the API is configured to work with PostgreSQL's Row Level Security, provisioned behind an API gateway with key-auth enabled. +- Fast: our benchmarks for basic reads are more than 300% faster than Firebase. The API is a very thin layer on top of Postgres, which does most of the heavy lifting. +- Scalable: the API can serve thousands of simultaneous requests, and works well for Serverless workloads. + +### RESTful API + +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: + +- Basic CRUD operations +- Deeply nested joins, allowing you to fetch data from multiple tables in a single fetch +- Works with Postgres Views +- Works with Postgres Functions +- Works with the Postgres security model - including Row Level Security, Roles, and Grants. + + + +### Realtime API + +Supabase provides a [Realtime](https://github.com/supabase/realtime) API using Realtime. You can use this to listen to database changes over websockets. Realtime leverages PostgreSQL's built-in logical replication. You can manage your Realtime API simply by managing Postgres publications. + +## Getting started + +After you have added tables or functions to your database, you can use the API. + +### Creating API Routes + +API routes are automatically created when you create Postgres Tables, Views, or Functions. + +Let's create our first API route by creating a table called `todos` (which will store some public user information). This will create a corresponding route `todos` which can accept `GET`, `POST`, `PATCH`, & `DELETE` requests. + + + + + + +### API URL and Keys + +Every Supabase project has a unique API URL. Your API is secured behind an API gateway which requires an API Key for every request. + +You can find the Keys inside the Dashboard. + + +``` +1. Go to the "Settings" section. +2. Click "API" in the sidebar. +3. Find your API URL in this page. +4. Find your "anon" and "service_role" keys on this page. +``` + +**Details and links:** + +You are provided with two keys initially: + +- an `anon` key, which is safe to be used in a browser context. +- a `service_role` key, which should only be used on a server. This key can bypass Row Level Security. + +### Accessing the Docs + +Supabase generates documentation in the Dashboard which updates as you make database changes. + +Let's view the documentation for the todos table which we created in the first step. + + + +``` +1. Go to the "API" section. +2. Find "todos" in the "Tables and Views" section. +3. Switch between the Javascript and the cURL docs using the tabs. +``` + +### Using the API + +You can interact with your API directly via HTTP requests, or you can use the client libraries which we provide. + +Let's see how to make a request to the `todos` table which we created in the first step, using the API URL (`[SUPABASE_URL]`) and Key (`[SUPABASE_ANON_KEY]`) we provided: + + + + +**Details and links:** + +- When you create a table in Postgres, Row Level Security is disabled by default. Make sure you secure it by [enabling RLS](https://supabase.com/docs/guides/api#securing-your-routes). +- Never expose the service_role key in a browser or anywhere where a user can see it. +- JS Reference: [select()](https://supabase.com/docs/reference/javascript/select), [insert()](https://supabase.com/docs/reference/javascript/insert), [update()](https://supabase.com/docs/reference/javascript/update), [upsert()](https://supabase.com/docs/reference/javascript/upsert), [delete()](https://supabase.com/docs/reference/javascript/delete), [rpc()](https://supabase.com/docs/reference/javascript/rpc) (call Postgres functions). + +### Managing Realtime +The Realtime API works through PostgreSQL's replication functionality. Postgres sends database changes to a "publication" called `supabase_realtime`, and by managing this publication you can control which data is broadcast. + +By default Realtime is disabled on your database. Let's turn on Realtime for the `todos` table. + + + + +**Details and links:** + +- You should only turn on realtime for Public tables (where all data should be accessible). +- [JS Reference](https://supabase.com/docs/reference/javascript/subscribe): Subscribe to database changes using the realtime client + +### Securing your Routes + + + +**Details and links:** +- Your API is designed to work with Postgres Row Level Security. If you use Supabase [Auth](https://supabase.com/docs/guides/auth), you can restrict data based on the logged-in user. +- To control access to your data, you can use [Policies](https://supabase.com/docs/guides/auth#policies). + + + + diff --git a/apps/temp-docs/docs/guides/auth.mdx b/apps/temp-docs/docs/guides/auth.mdx new file mode 100644 index 00000000000..7f5e5be025e --- /dev/null +++ b/apps/temp-docs/docs/guides/auth.mdx @@ -0,0 +1,112 @@ +--- +title: 'Auth' +description: 'Supabase auth' +--- + +# Auth + + + +## User Management + +Supabase makes it simple to manage your users. + + + +When users sign up, Supabase assigns them a unique ID. You can reference this ID anywhere in your database. For example, you might create a '`profiles`' table referencing id in the `auth.users` table using a `user_id` field. + +Supabase provides the routes to [sign up](https://supabase.com/docs/reference/javascript/auth-signup), [log in](https://supabase.com/docs/reference/javascript/auth-signin), [log out](https://supabase.com/docs/reference/javascript/auth-signout), and manage users in your apps and websites. + +## Third Party Logins + +We currently support the following OAuth providers: + + + +You can enable providers by navigating to Authentication > Settings > External OAuth Providers and inputting your `Client ID` and `Secret` for each. + + + +## Row Level Security + +Authentication only gets you so far. When you need granular authorization rules, nothing beats PostgreSQL's [Row Level Security (RLS)](https://www.postgresql.org/docs/current/ddl-rowsecurity.html). Supabase makes it simple to turn RLS on and off. + + + +## Policies + +[Policies](https://www.postgresql.org/docs/current/sql-createpolicy.html) are PostgreSQL's rule engine. They are incredibly powerful and flexible, allowing you to write complex SQL rules which fit your unique business needs. + + + +With policies, your database becomes the rules engine. Instead of repetitively filtering your queries, like this... + +```Javascript +const loggedInUserId = 'd0714948' +let { data, error } = await supabase + .from('users') + .select('user_id, name') + .eq('user_id', loggedInUserId) + +// console.log(data) +// => { id: 'd0714948', name: 'Jane' } +``` +... you can simply define a rule on your database table, `auth.uid() = user_id`, and your request will return the rows which pass the rule, even when you remove the filter from your middleware: + +```Javascript +let user = await supabase.from('users').select('user_id, name') + +// console.log(data) +// Still => { id: 'd0714948', name: 'Jane' } +``` + +## How It Works + + +1. A user signs up. Supabase creates a new user in the `auth.users` table. +2. Supabase returns a new JWT, which contains the user's `UUID`. +3. Every request to your database also sends the JWT. +4. Postgres inspects the JWT to determine the user making the request. +5. The user's UID can be used in policies to restrict access to rows. + +Supabase provides a special function in Postgres, `auth.uid()`, which extracts the user's UID from the JWT. This is especially useful when creating policies. + +## Tips + +**Enable Realtime for database tables** + +Realtime server broadcasts database changes to authorized users depending on your Row Level Security (RLS) policies. We recommend that you enable row level security and set row security policies on tables that you add to the publication. However, you may choose to disable RLS on a table and have changes broadcast to all connected clients. + +```sql +/** + * REALTIME SUBSCRIPTIONS + * Realtime enables listening to any table in your public schema. + */ + +begin; + -- remove the realtime publication + drop publication if exists supabase_realtime; + + -- re-create the publication but don't enable it for any tables + create publication supabase_realtime; +commit; + +-- add a table to the publication +alter publication supabase_realtime add table products; + +-- add other tables to the publication +alter publication supabase_realtime add table posts; +``` + +## Next Steps +- Read more about Auth in the [Guides](https://supabase.com/docs/guides/auth/intro). +- Sign in: [app.supabase.io](https://app.supabase.io/) + + + diff --git a/apps/temp-docs/docs/guides/auth/auth-apple.mdx b/apps/temp-docs/docs/guides/auth/auth-apple.mdx new file mode 100644 index 00000000000..9f83c19fe0c --- /dev/null +++ b/apps/temp-docs/docs/guides/auth/auth-apple.mdx @@ -0,0 +1,214 @@ +--- +id: auth-apple +title: 'Login with Apple' +description: Add Apple OAuth to your Supabase project +--- + +import Tabs from '@theme/Tabs' +import TabsPanel from '@theme/TabsPanel' + +To enable Apple Auth for your project, you need to set up an Apple OAuth application and add the application credentials to your Supabase Dashboard. + +## Overview + +Apple OAuth consists of six broad steps: + +- Obtaining an `App Id` with “Sign In with Apple” capabilities. +- Obtaining a `Services Id` - this will serve as the `client_id`. +- Obtaining a `secret key` that will be used to get our `client_secret`. +- Generating the `client_secret` using the `secret key`. +- Add your `client id` and `client secret` keys to your [Supabase Project](https://supabase.com). +- Add the login code to your [Supabase JS Client App](https://github.com/supabase/supabase-js). + +## Steps + +### Access your Apple Developer account + +- Go to [developer.apple.com](https://developer.apple.com). +- Click on `Account` at the top right to log in. + +![Apple Developer Portal.](/docs/img/guides/apple-developer-portal.png) + +### Obtain an App ID + +- Go to `Certificates, Identifiers & Profiles`. +- Click on `Identifiers` at the left. +- Click on the `+` sign in the upper left next to `Identifiers`. +- Select `App IDs` and click `Continue`. +- Select type `App` and click `Continue`. +- Fill out your app information: + - App description. + - Bundle ID (Apple recommends reverse-domain name style, so if your domain is acme.com and your app is called roadrunner, use: "com.acme.roadrunner"). + - Scroll down and check `Sign In With Apple`. + - Click `Continue` at the top right. + - Click `Register` at the top right. + +### Obtain a Services ID + +This will serve as the `client_id` when you make API calls to authenticate the user. + +- Go to `Certificates, Identifiers & Profiles`. +- Click on `Identifiers` at the left. +- Click on the `+` sign in the upper left next to `Identifiers`. +- Select `Services IDs` and click `Continue`. +- Fill out your information: + - App description. + - Bundle ID (you can't use the same Bundle ID from the previous step, but you can just add something to the beginning, such as "app." to make it app.com.acme.roadrunner"). + - SAVE THIS ID -- this ID will become your `client_id` later. + - Click `Continue` at the top right. + - Click `Register` at the top right. + +### Find your callback URL + +The next step requires a callback URL, which looks like this: + +`https://.supabase.co/auth/v1/callback` + +- Go to your [Supabase Project Dashboard](https://supabase.com). +- Click on the `Settings` icon at the bottom of the left sidebar. +- Click on `API` in the list. +- Under Config / URL you'll find your API URL, you can click `Copy` to copy it to the clipboard. +- Now just add `/auth/v1/callback` to the end of that to get your full `OAuth Redirect URI`. + + + +### Configure your Services ID + +- Under `Identifiers`, click on your newly-created Services ID. +- Check the box next to `Sign In With Apple` to enable it. +- Click `Configure` to the right. +- Make sure your newly created Bundle ID is selected under `Primary App ID` +- Add your domain to the `Domains and Subdomains` box (do not add `https://`, just add the domain). +- In the `Return URLs` box, type the callback URL of your app which you found in the previous step and click `Next` at the bottom right. +- Click `Done` at the bottom. +- Click `Continue` at the top right. +- Click `Save` at the top right. + +### Download your secret key + +Now you'll need to download a `secret key` file from Apple that will be used to generate your `client_secret`. + +- Go to `Certificates, Identifiers & Profiles`. +- Click on `Keys` at the left. +- Click on the `+` sign in the upper left next to `Keys`. +- Enter a `Key Name`. +- Check `Sign In with Apple`. +- Click `Configure` to the right. +- Select your newly-created Services ID from the dropdown selector. +- Click `Save` at the top right. +- Click `Continue` at the top right. +- Click `Register` at the top right. +- Click `Download` at the top right. +- Save the downloaded file -- this contains your "secret key" that will be used to generate your `client_secret`. +- Click `Done` at the top right. + +### Generate a `client_secret` + +The `secret key` you downloaded is used to create the `client_secret` string you'll need to authenticate your users. + +According to the [Apple Docs](https://developer.apple.com/documentation/signinwithapplerestapi/generate_and_validate_tokens) it needs to be a JWT +token encrypted using the Elliptic Curve Digital Signature Algorithm (ECDSA) with the P-256 curve and the SHA-256 hash algorithm. + +At this time, the easiest way to generate this JWT token is with [Ruby](https://www.ruby-lang.org/en/). +If you don't have Ruby installed, you can [Download Ruby Here](https://www.ruby-lang.org/en/downloads). + +- Install Ruby (or check to make sure it's installed on your system). +- Install [ruby-jwt](https://github.com/jwt/ruby-jwt). +- From the command line, run: `sudo gem install jwt`. + +Create the script below using a text editor: `secret_gen.rb` + +```ruby +require "jwt" + +key_file = "Path to the private key" +team_id = "Your Team ID" +client_id = "The Service ID of the service you created" +key_id = "The Key ID of the private key" + +validity_period = 180 # In days. Max 180 (6 months) according to Apple docs. + +private_key = OpenSSL::PKey::EC.new IO.read key_file + +token = JWT.encode( + { + iss: team_id, + iat: Time.now.to_i, + exp: Time.now.to_i + 86400 * validity_period, + aud: "https://appleid.apple.com", + sub: client_id + }, + private_key, + "ES256", + header_fields= + { + kid: key_id + } +) +puts token +``` + +1. Edit the `secret_gen.rb` file: + +- `key_file` = "Path to the private key you downloaded from Apple". It should look like this: `AuthKey_XXXXXXXXXX.p8`. +- `team_id` = "Your Team ID". This is found at the top right of the Apple Developer site (next to your name). +- `client_id` = "The Service ID of the service you created". This is the `Services ID` you created in the above step `Obtain a Services ID`. If you've lost this ID, you can find it in the Apple Developer Site: + - Go to `Certificates, Identifiers & Profiles`. + - Click `Identifiers` at the left. + - At the top right drop-down, select `Services IDs`. + - Find your Identifier in the list (i.e. app.com.acme.roadrunner). +- `key_id` = "The Key ID of the private key". This can be found in the name of your downloaded secret file (For a file named `AuthKey_XXXXXXXXXX.p8` your key_id is `XXXXXXXXXX`). If you've lost this ID, you can find it in the Apple Developer Site: + - Go to `Certificates, Identifiers & Profiles`. + - Click `Keys` at the left. + - Click on your newly-created key in the list. + - Look under `Key ID` to find your key_id. + +2. From the command line, run: `ruby secret_gen.rb > client_secret.txt`. +3. Your `client_secret` is now stored in this `client_secret.txt` file. + +### Add your OAuth credentials to Supabase + +- Go to your [Supabase Dashboard](https://supabase.com). +- In the left sidebar, click the `Authentication` icon (near the top). +- Click `Settings` from the list to go to the `Authentication Settings` page. +- Enter the final (hosted) URL of your app under `Site URL` (this is important). +- Under `External OAuth Providers` turn `Apple Enabled` to ON. +- Enter your `client_id` and `client_secret` saved in the previous steps. +- Click `Save`. + +### Add login code to your client app + +The JavaScript client code is documented in the [Supabase OAuth Reference](/docs/reference/javascript/auth-signin#sign-in-using-third-party-providers). + +```js +const { user, session, error } = await supabase.auth.signIn({ + provider: 'apple', +}) +``` + +Add a function which you can call from a button, link, or UI element. + +```js +async function signInWithApple() { + const { user, session, error } = await supabase.auth.signIn({ + provider: 'apple', + }) +} +``` + +To log out: + +```js +async function signout() { + const { error } = await supabase.auth.signOut() +} +``` + +## Resources + +- [Apple Developer Account](https://developer.apple.com). +- [Ruby](https://www.ruby-lang.org/en/) Docs. +- [ruby-jwt](https://github.com/jwt/ruby-jwt) library. +- Thanks to [Janak Amarasena](https://medium.com/@janakda) who did all the heavy lifting in [How to configure Sign In with Apple](https://medium.com/identity-beyond-borders/how-to-configure-sign-in-with-apple-77c61e336003). diff --git a/apps/temp-docs/docs/guides/auth/auth-bitbucket.mdx b/apps/temp-docs/docs/guides/auth/auth-bitbucket.mdx new file mode 100644 index 00000000000..def7bf4cb22 --- /dev/null +++ b/apps/temp-docs/docs/guides/auth/auth-bitbucket.mdx @@ -0,0 +1,102 @@ +--- +id: auth-bitbucket +title: 'Login with Bitbucket' +description: Add Bitbucket OAuth to your Supabase project +--- + +import Tabs from '@theme/Tabs' +import TabsPanel from '@theme/TabsPanel' + +To enable Bitbucket Auth for your project, you need to set up a BitBucket OAuth application and add the application credentials to your Supabase Dashboard. + +## Overview + +Setting up Bitbucket logins for your application consists of 3 parts: + +- Create and configure a Bitbucket OAuth Consumer on [Bitbucket](https://bitbucket.org) +- Add your Bitbucket OAuth Consumer keys to your [Supabase Project](https://supabase.com) +- Add the login code to your [Supabase JS Client App](https://github.com/supabase/supabase-js) + +## Steps + +### Access your Bitbucket account + +- Go to [bitbucket.org](https://bitbucket.org/). +- Click on `Login` at the top right to log in. + +![Bitbucket Developer Portal.](/docs/img/guides/bitbucket-portal.png) + +### Find your callback URL + +The next step requires a callback URL, which looks like this: + +`https://.supabase.co/auth/v1/callback` + +- Go to your [Supabase Project Dashboard](https://supabase.com). +- Click on the `Settings` icon at the bottom of the left sidebar. +- Click on `API` in the list. +- Under Config / URL you'll find your API URL, you can click `Copy` to copy it to the clipboard. +- Now just add `/auth/v1/callback` to the end of that to get your full `OAuth Redirect URI`. + + + +### Create a Bitbucket OAuth app + +- Click on your profile icon at the bottom left +- Click on `All Workspaces` +- Select a workspace and click on it to select it +- Click on `Settings` on the left +- Click on `OAuth consumers` on the left under `Apps and Features` (near the bottom) +- Click `Add Consumer` at the top +- Enter the name of your app under `Name` +- In `Callback URL`, type the callback URL of your app +- Check the permissions you need (Email, Read should be enough) +- Click `Save` at the bottom +- Click on your app name (the name of your new OAuth Consumer) +- Copy your `Key` (`client_key`) and `Secret` (`client_secret`) codes + +### Add your Bitbucket credentials into your Supabase Project + +- Go to your [Supabase Project Dashboard](https://supabase.com) +- In the left sidebar, click the `Authentication` icon (near the top) +- Click `Settings` from the list to go to the `Authentication Settings` page +- Enter the final (hosted) URL of your app under `Site URL` (this is important) +- Under `External OAuth Providers` turn `Bitbucket Enabled` to ON +- Enter your `client_id` and `client_secret` saved in the previous step +- Click `Save` + +### Add login code to your client app + +The JavaScript client code is documented here: [Supabase OAuth Client Code](/docs/reference/javascript/auth-signin#sign-in-using-third-party-providers) + +```js +const { user, session, error } = await supabase.auth.signIn({ + provider: 'bitbucket', +}) +``` + +Add this function which you can call from a button, link, or UI element. + +```js +async function signInWithBitbucket() { + const { user, session, error } = await supabase.auth.signIn({ + provider: 'bitbucket', + }) +} +``` + +To log out: + +```js +async function signout() { + const { error } = await supabase.auth.signOut() +} +``` + +## Resources + +- [Supabase Account - Free Tier OK](https://supabase.com) +- [Supabase JS Client](https://github.com/supabase/supabase-js) +- [Bitbucket Account](https://bitbucket.org) diff --git a/apps/temp-docs/docs/guides/auth/auth-discord.mdx b/apps/temp-docs/docs/guides/auth/auth-discord.mdx new file mode 100644 index 00000000000..45d22b63e9a --- /dev/null +++ b/apps/temp-docs/docs/guides/auth/auth-discord.mdx @@ -0,0 +1,102 @@ +--- +id: auth-discord +title: 'Login with Discord' +description: Add Discord OAuth to your Supabase project +--- + +import Tabs from '@theme/Tabs' +import TabsPanel from '@theme/TabsPanel' + +To enable Discord Auth for your project, you need to set up a Discord Application and add the Application OAuth credentials to your Supabase Dashboard. + +## Overview + +Setting up Discord logins for your application consists of 3 parts: + +- Create and configure a Discord Application [Discord Developer Portal](https://discord.com/developers) +- Add your Discord OAuth Consumer keys to your [Supabase Project](https://supabase.com) +- Add the login code to your [Supabase JS Client App](https://github.com/supabase/supabase-js) + +## Steps + +### Access your Discord account + +- Go to [discord.com](https://discord.com/). +- Click on `Login` at the top right to log in. + +![Discord Portal.](/docs/img/guides/discord-portal.png) + +- Once logged in, go to [discord.com/developers](https://discord.com/developers). + +![Discord Portal.](/docs/img/guides/discord-developer-portal.png) + +### Find your callback URL + +In the next step you require a callback URL, which looks like this: + +`https://.supabase.co/auth/v1/callback` + +- Go to your [Supabase Project Dashboard](https://supabase.com). +- Click on the `Settings` icon at the bottom of the left sidebar. +- Click on `API` in the list. +- Under Config / URL you'll find your API URL, you can click `Copy` to copy it to the clipboard. +- Now just add `/auth/v1/callback` to the end of that to get your full `OAuth Redirect URI`. + + + +### Create a Discord Application + +- Click on `New Application` at the top right. +- Enter the name of your application and click `Create`. +- Click on `OAuth2` under `Settings` in the left side panel. +- Click `Add Redirect` under `Redirects`. +- Type or paste your `callback URL` into the `Redirects` box. +- Click `Save Changes` at the bottom. +- Copy your `Client ID` and `Client Secret` under `Client information`. + +### Add your Discord credentials into your Supabase Project + +- Go to your [Supabase Project Dashboard](https://supabase.com) +- In the left sidebar, click the `Authentication` icon (near the top) +- Click `Settings` from the list to go to the `Authentication Settings` page +- Enter the final (hosted) URL of your app under `Site URL` (this is important) +- Under `External OAuth Providers` turn `Discord Enabled` to ON +- Enter your `client_id` and `client_secret` saved in the previous step +- Click `Save` + +### Add login code to your client app + +The JavaScript client code is documented here: [Supabase OAuth Client Code](/docs/reference/javascript/auth-signin#sign-in-using-third-party-providers) + +```js +const { user, session, error } = await supabase.auth.signIn({ + provider: 'discord', +}) +``` + +Add this function which you can call from a button, link, or UI element. + +```js +async function signInWithDiscord() { + const { user, session, error } = await supabase.auth.signIn({ + provider: 'discord', + }) +} +``` + +To log out: + +```js +async function signout() { + const { error } = await supabase.auth.signOut() +} +``` + +## Resources + +- [Supabase Account - Free Tier OK](https://supabase.com) +- [Supabase JS Client](https://github.com/supabase/supabase-js) +- [Discord Account](https://discord.com) +- [Discord Developer Portal](https://discord.com/developers) diff --git a/apps/temp-docs/docs/guides/auth/auth-email.mdx b/apps/temp-docs/docs/guides/auth/auth-email.mdx new file mode 100644 index 00000000000..1cb151ae6e6 --- /dev/null +++ b/apps/temp-docs/docs/guides/auth/auth-email.mdx @@ -0,0 +1,133 @@ +--- +id: auth-email +title: 'Login With Email' +description: Use Supabase to Authenticate and Authorize your users using email. +--- + +import Tabs from '@theme/Tabs' +import TabsPanel from '@theme/TabsPanel' + +## Overview + +Setting up Email logins for your Supabase application. + +- Add Email authenticator to your [Supabase Project](https://app.supabase.io) +- Add the login code to your application - [Javascript](https://github.com/supabase/supabase-js) | [Dart](https://github.com/supabase/supabase-dart) + +## Add Email into your Supabase Project + +- Go to your [Supabase Project Dashboard](https://app.supabase.io) +- In the left sidebar, click the `Authentication` icon (near the top) +- Click `Settings` from the list to go to the `Authentication Settings` page +- Enter the final (hosted) URL of your app under `Site URL` (this is important) +- Under `Email Auth` turn `Enable Email Signup` to ON +- Click `Save` + +### Add login code to your client app + +The JavaScript client code is documented here: [Supabase OAuth Client Code](/docs/reference/javascript/auth-signin#sign-in-using-third-party-providers) + + + + + +```js +const { user, error } = await supabase.auth.signIn({ + email: 'example@email.com', + password: 'example-password', +}) +``` + + + + + +```dart +final res = await supabase.auth.signIn( + email: 'example@email.com', + password: 'example-password' +); + +final user = res.data?.user; +final error = res.error; +``` + + + + + +Add this function which you can call from a button, link, or UI element. + + + + + +```js +async function signInWithEmail() { + const { user, error } = await supabase.auth.signIn({ + email: 'example@email.com', + password: 'example-password', + }) +} +``` + + + + + +```dart +function SignInWithEmail() { + await supabase.auth.signIn( + email: 'example@email.com', + password: 'example-password' + ); +} +``` + + + + + +To log out: + + + + + +```js +async function signOut() { + const { error } = await supabase.auth.signOut() +} +``` + + + + + +```dart +function SignOut() { + await supabase.auth.signOut(); +} +``` + + + + + +## Resources + +- [Supabase Account - Free Tier OK](https://supabase.com) +- [Supabase JS Client](https://github.com/supabase/supabase-js) +- [Supabase Dart Client](https://github.com/supabase/supabase-dart) diff --git a/apps/temp-docs/docs/guides/auth/auth-facebook.mdx b/apps/temp-docs/docs/guides/auth/auth-facebook.mdx new file mode 100644 index 00000000000..07e46c04301 --- /dev/null +++ b/apps/temp-docs/docs/guides/auth/auth-facebook.mdx @@ -0,0 +1,119 @@ +--- +id: auth-facebook +title: 'Login with Facebook' +description: Add Facebook OAuth to your Supabase project +--- + +import Tabs from '@theme/Tabs' +import TabsPanel from '@theme/TabsPanel' + +To enable Facebook Auth for your project, you need to set up a Facebook OAuth application and add the application credentials to your Supabase Dashboard. + +## Overview + +Setting up Facebook logins for your application consists of 3 parts: + +- Create and configure a Facebook Application on the [Facebook Developers Site](https://developers.facebook.com) +- Add your Facebook keys to your [Supabase Project](https://supabase.com) +- Add the login code to your [Supabase JS Client App](https://github.com/supabase/supabase-js) + +## Steps + +### Access your Facebook Developer account + +- Go to [developers.facebook.com](https://developers.facebook.com). +- Click on `Log In` at the top right to log in. + +![Facebook Developer Portal.](/docs/img/guides/facebook-portal.png) + +### Create a Facebook App + +- Click on `My Apps` at the top right. +- Click `Create App` near the top right. +- Select your app type and click `Continue`. +- Fill in your app information, then click `Create App`. +- This should bring you to the screen: `Add Products to Your App`. (Alternatively you can click on `Add Product` in the left sidebar to get to this screen.) + +### Find your callback URI + +The next step requires a callback URI, which looks like this: + +`https://.supabase.co/auth/v1/callback` + +- Go to your [Supabase Project Dashboard](https://supabase.com). +- Click on the `Settings` icon at the bottom of the left sidebar. +- Click on `API` in the list. +- Under Config / URL you'll find your API URL, you can click `Copy` to copy it to the clipboard. +- Now just add `/auth/v1/callback` to the end of that to get your full `OAuth Redirect URI`. + + + +### Set up FaceBook Login for your Facebook App + +From the `Add Products to your App` screen: + +- Click `Setup` under `Facebook Login` +- Skip the Quickstart screen, instead, in the left sidebar, click `Settings` under `Facebook Login` +- Enter your callback URI under `Valid OAuth Redirect URIs` on the `Facebook Login Settings` page +- Enter this in the `Valid OAuth Redirect URIs` box +- Click `Save Changes` at the bottom right + +Be aware that you have to set the right access levels on your Facebook App to enable 3rd party applications to read the email address. +From the `App Review -> Permissions and Features` screen: + +- Click the button `Request Advanced Access` on the right side of `public_profile` and `email` + +You can read more about access levels [here](https://developers.facebook.com/docs/graph-api/overview/access-levels/) + +### Copy your Facebook App ID and Secret + +- Click `Settings / Basic` in the left sidebar +- Copy your App ID from the top of the `Basic Settings` page +- Under `App Secret` click `Show` then copy your secret +- Make sure all required fields are completed on this screen. + +### Enter your Facebook App ID and Secret into your Supabase Project + +- Go to your [Supabase Project Dashboard](https://supabase.com) +- In the left sidebar, click the `Authentication` icon (near the top) +- Click `Settings` from the list to go to the `Authentication Settings` page +- Enter the final (hosted) URL of your app under `Site URL` (this is important) +- Under `External OAuth Providers` turn `Facebook Enabled` to ON +- Enter your `Facebook client ID` and `Facebook secret` saved in the previous step +- Click `Save` + +### Add login code to your client app + +The JavaScript client code is documented here: [Supabase OAuth Client Code](/docs/reference/javascript/auth-signin#sign-in-using-third-party-providers) + +```js +const { user, session, error } = await supabase.auth.signIn({ + provider: 'facebook', +}) +``` + +Add this function which you can call from a button, link, or UI element. + +```js +async function signInWithFacebook() { + const { user, session, error } = await supabase.auth.signIn({ + provider: 'facebook', + }) +} +``` + +To log out: + +```js +async function signout() { + const { error } = await supabase.auth.signOut() +} +``` + +## Resources + +- [Supabase Account - Free Tier OK](https://supabase.com) +- [Supabase JS Client](https://github.com/supabase/supabase-js) +- [Facebook Developers Dashboard](https://developers.facebook.com/) diff --git a/apps/temp-docs/docs/guides/auth/auth-github.mdx b/apps/temp-docs/docs/guides/auth/auth-github.mdx new file mode 100644 index 00000000000..12e0d207806 --- /dev/null +++ b/apps/temp-docs/docs/guides/auth/auth-github.mdx @@ -0,0 +1,112 @@ +--- +id: auth-github +title: 'Login with GitHub' +description: Add GitHub OAuth to your Supabase project +--- + +import Tabs from '@theme/Tabs' +import TabsPanel from '@theme/TabsPanel' + +To enable GitHub Auth for your project, you need to set up a GitHub OAuth application and add the application credentials to your Supabase Dashboard. + +## Overview + +Setting up GitHub logins for your application consists of 3 parts: + +- Create and configure a GitHub OAuth App on [GitHub](https://github.com) +- Add your GitHub OAuth keys to your [Supabase Project](https://supabase.com) +- Add the login code to your [Supabase JS Client App](https://github.com/supabase/supabase-js) + +## Steps + +### Access your GitHub account + +- Go to [github.com](https://github.com). +- Click on `Sign In` at the top right to log in. + +![GitHub Developer Portal.](/docs/img/guides/github-portal.png) + +### Create a GitHub Oauth App + +Go to the [GitHub Developer Settings](https://github.com/settings/developers) page: + +- Click on your profile photo at the top right +- Click Settings near the bottom of the menu +- In the left sidebar, click `Developer settings` (near the bottom) +- In the left sidebar, click `OAuth Apps` + +### Find your callback URL + +The next step requires a callback URL, which looks like this: + +`https://.supabase.co/auth/v1/callback` + +- Go to your [Supabase Project Dashboard](https://supabase.com). +- Click on the `Settings` icon at the bottom of the left sidebar. +- Click on `API` in the list. +- Under Config / URL you'll find your API URL, you can click `Copy` to copy it to the clipboard. +- Now just add `/auth/v1/callback` to the end of that to get your full `OAuth Redirect URI`. + + + +### Register a new OAuth application + +- Click `Register a new application`. If you've created an app before, click `New OAuth App` here. +- In `Application name`, type the name of your app. +- In `Homepage URL`, type the full URL to your app's website. +- In `Authorization callback URL`, type the callback URL of your app. +- Enter the URL in the `Valid OAuth Redirect URIs` box. +- Click `Save Changes` at the bottom right. +- Click `Register Application`. + +Copy your new OAuth credentials + +- Copy and save your `Client ID`. +- Click `Generate a new client secret`. +- Copy and save your `Client secret`. + +### Enter your GitHub credentials into your Supabase Project + +- Go to your [Supabase Project Dashboard](https://supabase.com) +- In the left sidebar, click the `Authentication` icon (near the top) +- Click `Settings` from the list to go to the `Authentication Settings` page +- Enter the final (hosted) URL of your app under `Site URL` (this is important) +- Under `External OAuth Providers` turn `GitHub Enabled` to ON +- Enter your `GitHub Client ID` and `GitHub Client Secret` saved in the previous step +- Click `Save` + +### Add login code to your client app + +The JavaScript client code is documented here: [Supabase OAuth Client Code](/docs/reference/javascript/auth-signin#sign-in-using-third-party-providers) + +```js +const { user, session, error } = await supabase.auth.signIn({ + provider: 'github', +}) +``` + +Add this function which you can call from a button, link, or UI element. + +```js +async function signInWithGithub() { + const { user, session, error } = await supabase.auth.signIn({ + provider: 'github', + }) +} +``` + +To log out: + +```js +async function signout() { + const { error } = await supabase.auth.signOut() +} +``` + +## Resources + +- [Supabase Account - Free Tier OK](https://supabase.com) +- [Supabase JS Client](https://github.com/supabase/supabase-js) +- [GitHub Developer Settings](https://github.com/settings/developers) diff --git a/apps/temp-docs/docs/guides/auth/auth-gitlab.mdx b/apps/temp-docs/docs/guides/auth/auth-gitlab.mdx new file mode 100644 index 00000000000..71718e6b031 --- /dev/null +++ b/apps/temp-docs/docs/guides/auth/auth-gitlab.mdx @@ -0,0 +1,99 @@ +--- +id: auth-gitlab +title: 'Login with GitLab' +description: Add GitLab OAuth to your Supabase project +--- + +import Tabs from '@theme/Tabs' +import TabsPanel from '@theme/TabsPanel' + +To enable GitLab Auth for your project, you need to set up a GitLab OAuth application and add the application credentials to your Supabase Dashboard. + +## Overview + +Setting up GitLab logins for your application consists of 3 parts: + +- Create and configure a GitLab Application on [GitLab](https://gitlab.com) +- Add your GitLab Application keys to your [Supabase Project](https://supabase.com) +- Add the login code to your [Supabase JS Client App](https://github.com/supabase/supabase-js) + +## Steps + +### Access your GitLab account + +- Go to [gitlab.com](https://gitlab.com). +- Click on `Login` at the top right to log in. + +![GitLab Developer Portal.](/docs/img/guides/gitlab-portal.png) + +### Find your callback URL + +The next step requires a callback URL, which looks like this: + +`https://.supabase.co/auth/v1/callback` + +- Go to your [Supabase Project Dashboard](https://supabase.com). +- Click on the `Settings` icon at the bottom of the left sidebar. +- Click on `API` in the list. +- Under Config / URL you'll find your API URL, you can click `Copy` to copy it to the clipboard. +- Now just add `/auth/v1/callback` to the end of that to get your full `OAuth Redirect URI`. + + + +### Create your GitLab Application + +- Click on your `profile logo` (avatar) in the top-right corner. +- Select `Edit profile`. +- In the left sidebar, select Applications. +- Enter the name of the application. +- In the `Redirect URI` box, type the callback URL of your app. +- Check the box next to `Confidential` (make sure it is checked). +- Check the scope named `read_user` (this is the only required scope). +- Click `Save Application` at the bottom. +- Copy and save your `Application ID` (`client_id`) and `Secret` (`client_secret`) which you'll need later. + +### Add your GitLab credentials into your Supabase Project + +- Go to your [Supabase Project Dashboard](https://supabase.com). +- In the left sidebar, click the `Authentication` icon (near the top). +- Click `Settings` from the list to go to the `Authentication Settings` page. +- Enter the final (hosted) URL of your app under `Site URL` (this is important). +- Under `External OAuth Providers` turn `GitLab Enabled` to ON. +- Enter your `client_id` and `client_secret` saved in the previous step. +- Click `Save`. + +### Add login code to your client app + +The JavaScript client code is documented here: [Supabase OAuth Client Code](/docs/reference/javascript/auth-signin#sign-in-using-third-party-providers) + +```js +const { user, session, error } = await supabase.auth.signIn({ + provider: 'gitlab', +}) +``` + +Add this function which you can call from a button, link, or UI element. + +```js +async function signInWithGitLab() { + const { user, session, error } = await supabase.auth.signIn({ + provider: 'gitlab', + }) +} +``` + +To log out: + +```js +async function signout() { + const { error } = await supabase.auth.signOut() +} +``` + +## Resources + +- [Supabase Account - Free Tier OK](https://supabase.com) +- [Supabase JS Client](https://github.com/supabase/supabase-js) +- [GitLab Account](https://gitlab.com) diff --git a/apps/temp-docs/docs/guides/auth/auth-google.mdx b/apps/temp-docs/docs/guides/auth/auth-google.mdx new file mode 100644 index 00000000000..4e55dc324b6 --- /dev/null +++ b/apps/temp-docs/docs/guides/auth/auth-google.mdx @@ -0,0 +1,127 @@ +--- +id: auth-google +title: 'Login with Google' +description: Add Google OAuth to your Supabase project +--- + +import Tabs from '@theme/Tabs' +import TabsPanel from '@theme/TabsPanel' + +To enable Google Auth for your project, you need to set up a Google OAuth application and add the application credentials to your Supabase Dashboard. + +## Overview + +Setting up Google logins for your application consists of 3 parts: + +- Create and configure a Google Project on the [Google Cloud Platform Console](https://console.cloud.google.com/home/dashboard) +- Add your Google OAuth keys to your [Supabase Project](https://supabase.com) +- Add the login code to your [Supabase JS Client App](https://github.com/supabase/supabase-js) + +## Steps + +### Access your Google Cloud Platform account + +- Go to [cloud.google.com](https://cloud.google.com). +- Click on `Sign in` at the top right to log in. + +![Google Developer Portal.](/docs/img/guides/google-portal.png) + +### Create a Google Cloud Platform Project + +- Click on `Select a Project` at the top left. + - (Or, if a project is currently selected, click on the current project name at the top left.) +- Click `New Project` at the top right. +- Fill in your app information, then click `Create`. + - (This can take a few minutes.) +- This should bring you to the dashboard for your new project. + +### Create the OAuth Keys for your project + +From your project's dashboard screen: + +- In the search bar at the top labeled `Search products and resources` type `OAuth`. +- Click on `OAuth consent screen` from the list of results. +- On the `OAuth consent screen` page select `External`. +- Click `Create`. + +### Edit your app information + +- On the `Edit app registration` page fill out your app information. +- Click `Save and continue` at the bottom. + +### Find your callback URL + +The next step requires a callback URL, which looks like this: + +`https://.supabase.co/auth/v1/callback` + +- Go to your [Supabase Project Dashboard](https://supabase.com). +- Click on the `Settings` icon at the bottom of the left sidebar. +- Click on `API` in the list. +- Under Config / URL you'll find your API URL, you can click `Copy` to copy it to the clipboard. +- Now just add `/auth/v1/callback` to the end of that to get your full `OAuth Redirect URI`. + + + +### Create your credentials + +- Click `Credentials` at the left to go to the `Credentials` page +- Click `Create Credentials` near the top then select `OAuth client ID` +- On the `Create OAuth client ID` page, select your application type. If you're not sure, choose `Web application`. +- Fill in your app name. +- At the bottom, under `Authorized redirect URIs` click `Add URI`. +- Enter your callback URI under `Authorized redirect URIs` at the bottom. +- Enter your callback URI in the `Valid OAuth Redirect URIs` box. +- Click `Save Changes` at the bottom right. +- Click `Create`. + +Copy your new OAuth credentials + +- A box will appear called `OAuth client created`. +- Copy and save the values under `Your Client ID` and `Your Client Secret`. + +### Enter your Google credentials into your Supabase Project + +- Go to your [Supabase Project Dashboard](https://supabase.com) +- In the left sidebar, click the `Authentication` icon (near the top) +- Click `Settings` from the list to go to the `Authentication Settings` page +- Enter the final (hosted) URL of your app under `Site URL` (this is important) +- Under `External OAuth Providers` turn `Google Enabled` to ON +- Enter your `Google Client ID` and `Google Client Secret` saved in the previous step +- Click `Save` + +### Add login code to your client app + +The JavaScript client code is documented here: [Supabase OAuth Client Code](/docs/reference/javascript/auth-signin#sign-in-using-third-party-providers) + +```js +const { user, session, error } = await supabase.auth.signIn({ + provider: 'google', +}) +``` + +Add this function which you can call from a button, link, or UI element. + +```js +async function signInWithGoogle() { + const { user, session, error } = await supabase.auth.signIn({ + provider: 'google', + }) +} +``` + +To log out: + +```js +async function signout() { + const { error } = await supabase.auth.signOut() +} +``` + +## Resources + +- [Supabase Account - Free Tier OK](https://supabase.com) +- [Supabase JS Client](https://github.com/supabase/supabase-js) +- [Google Cloud Platform Console](https://console.cloud.google.com/home/dashboard) diff --git a/apps/temp-docs/docs/guides/auth/auth-magic-link.mdx b/apps/temp-docs/docs/guides/auth/auth-magic-link.mdx new file mode 100644 index 00000000000..e9784ec4fab --- /dev/null +++ b/apps/temp-docs/docs/guides/auth/auth-magic-link.mdx @@ -0,0 +1,131 @@ +--- +id: auth-magic-link +title: 'Login With Magic Link' +description: Use Supabase to Authenticate and Authorize your users using Magic Link. +--- + +import Tabs from '@theme/Tabs' +import TabsPanel from '@theme/TabsPanel' + +By default, if no password is provided, the user will be sent a "magic link" to their email address, which they can click to open your application with a valid session. By default, a given user can only request a Magic Link once every 60 seconds. + +## Overview + +Setting up Magic Link logins for your Supabase application. + +- Add Magic Link authenticator to your [Supabase Project](https://app.supabase.io) +- Add the login code to your application - [Javascript](https://github.com/supabase/supabase-js) | [Dart](https://github.com/supabase/supabase-dart) + +## Add Magic Link into your Supabase Project + +- Go to your [Supabase Project Dashboard](https://app.supabase.io) +- In the left sidebar, click the `Authentication` icon (near the top) +- Click `Settings` from the list to go to the `Authentication Settings` page +- Enter the final (hosted) URL of your app under `Site URL` (this is important) +- Under `Email Auth` turn `Enable Email Signup` to ON +- Click `Save` + +### Add login code to your client app + +The JavaScript client code is documented here: [Supabase OAuth Client Code](/docs/reference/javascript/auth-signin#sign-in-using-third-party-providers) + + + + + +```js +const { user, error } = await supabase.auth.signIn({ + email: 'example@email.com', +}) +``` + + + + + +```dart +final res = await supabase.auth.signIn( + email: 'example@email.com' +); + +final user = res.data?.user; +final error = res.error; +``` + + + + + +Add this function which you can call from a button, link, or UI element. + + + + + +```js +async function signInWithEmail() { + const { user, error } = await supabase.auth.signIn({ + email: 'example@email.com', + }) +} +``` + + + + + +```dart +function SignInWithEmail() { + await supabase.auth.signIn( + email: 'example@email.com' + ); +} +``` + + + + + +To log out: + + + + + +```js +async function signOut() { + const { error } = await supabase.auth.signOut() +} +``` + + + + + +```dart +function SignOut() { + await supabase.auth.signOut(); +} +``` + + + + + +## Resources + +- [Supabase Account - Free Tier OK](https://supabase.com) +- [Supabase JS Client](https://github.com/supabase/supabase-js) +- [Supabase Dart Client](https://github.com/supabase/supabase-dart) diff --git a/apps/temp-docs/docs/guides/auth/auth-messagebird.mdx b/apps/temp-docs/docs/guides/auth/auth-messagebird.mdx new file mode 100644 index 00000000000..88a41645c60 --- /dev/null +++ b/apps/temp-docs/docs/guides/auth/auth-messagebird.mdx @@ -0,0 +1,282 @@ +--- +id: auth-messagebird +title: Phone Auth with MessageBird +description: How to set up and use Mobile OTP with MessageBird and Supabase. +--- + +import Tabs from '@theme/Tabs' +import TabsPanel from '@theme/TabsPanel' + +## Overview + +In this guide we'll show you how to authenticate your users with SMS based OTP (One-Time Password) tokens. + +There are two reasons to use Supabase SMS OTP tokens: + +- You want users to log in with mobile + password, and the mobile should be verified via SMS +- You want users to log in with mobile ONLY (i.e. passwordless login) + +We'll cover: + +- [Finding your MessageBird credentials](#finding-your-messagebird-credentials) +- [Using OTP with password based logins](#using-otp-with-password-based-logins) +- [Using OTP as a passwordless sign-in mechanism](#using-otp-as-a-passwordless-sign-in-mechanism) + +What you'll need: + +- A MessageBird account (sign up here: https://dashboard.messagebird.com/en/sign-up) +- A Supabase project (create one here: https://app.supabase.io) +- A mobile phone capable of receiving SMS + +## Steps + +### Finding your MessageBird credentials + +Start by logging into your MessageBird account and verify the mobile number you'll be using to test with: https://dashboard.messagebird.com/en/getting-started/sms + +This is the number that will be receiving the SMS OTPs. + +![Verify your own phone number](/docs/img/guides/auth-messagebird/1.png) + +![Get your API Keys](/docs/img/guides/auth-messagebird/2.png) + +Navigate to the [dashboard settings](https://dashboard.messagebird.com/en/settings/sms) to set the default originator. The messagebird originator is the name or number from which the message is sent. +For more information, you can refer to the messagebird article on choosing an originator [here](https://support.messagebird.com/hc/en-us/articles/115002628665-Choosing-an-originator) + +![Set the default originator](/docs/img/guides/auth-messagebird/3.png) + +You will need the following values to get started: + +- Live API Key / Test API Key +- MessageBird originator + +Now go to the Auth > Settings page in the Supabase dashboard (https://app.supabase.io/project/YOUR-PROJECT-REF/auth/settings). + +You should see an option to enable Phone Signup. + +![Enable Phone Sign-Up](/docs/img/guides/auth-twilio/7.png) + +Toggle it on, and copy the 2 values over from the messagebird dashboard. Click save. + +Note: If you use the Test API Key, the OTP will not be delivered to the mobile number specified but messagebird will log the response in the dashboard. +If the Live API Key is used instead, the OTP will be delivered and there will be a deduction in your free credits. + + +Plugin MessageBird credentials + +Now the backend should be setup, we can proceed to add our client-side code! + +#### SMS custom template + +The SMS message sent to a phone containing an OTP code can be customized. This is useful if you need to mention a brand name or display a website address. + +Go to Auth > Templates page in the Supabase dashboard (https://app.supabase.io/project/YOUR-PROJECT-REF/auth/templates). + +Use the variable `.Code` in the template to display the code. + +### Using OTP with password based logins + +In this use scenario we'll be using the user's mobile phone number as an alternative to an email address when signing up along with a password. You may want to think hard about the permanency of this however. It is not uncommon for mobile phone numbers to be recycled by phone networks when users cancel their phone contracts or move countries, therefore granting access to the user's account to whoever takes over the phone number in the future. Soon we'll add multi-factor auth, which will mitigate this risk, but for now you may want to give some thought to allowing your users to recover their account by some other means in an emergency. + +Using supabase-js on the client you'll want to use the same `signUp` method that you'd use for email based sign ups, but with the `phone` param instead of the `email param`: + + + + +```js +let { user, error } = await supabase.auth.signUp({ + phone: '+13334445555', + password: 'some-password', +}) +``` + + + + +```bash +curl -X POST 'https://cvwawazfelidkloqmbma.supabase.co/auth/v1/signup' \ +-H "apikey: SUPABASE_KEY" \ +-H "Content-Type: application/json" \ +-d '{ + "phone": "+13334445555", + "password": "some-password" +}' +``` + + + + +The user will now receive an SMS with a 6-digit pin that you will need to receive from them within 60-seconds before they can login to their account. + +You should present a form to the user so they can input the 6 digit pin, then send it along with the phone number to `verifyOTP`: + + + + +```js +let { session, error } = await supabase.auth.verifyOTP({ + phone: '+13334445555', + token: '123456', +}) +``` + + + + +```bash +curl -X POST 'https://cvwawazfelidkloqmbma.supabase.co/auth/v1/verify' \ +-H "apikey: SUPABASE_KEY" \ +-H "Content-Type: application/json" \ +-d '{ + "type": "sms", + "phone": "+13334445555", + "token": "123456" +}' +``` + + + + +If successful the user will now be logged in and you should receive a valid session like: + +```json +{ + "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZXhwIjoxNjI3MjkxNTc3LCJzdWIiOiJmYTA2NTQ1Zi1kYmI1LTQxY2EtYjk1NC1kOGUyOTg4YzcxOTEiLCJlbWFpbCI6IiIsInBob25lIjoiNjU4NzUyMjAyOSIsImFwcF9tZXRhZGF0YSI6eyJwcm92aWRlciI6InBob25lIn0sInVzZXJfbWV0YWRhdGEiOnt9LCJyb2xlIjoiYXV0aGVudGljYXRlZCJ9.1BqRi0NbS_yr1f6hnr4q3s1ylMR3c1vkiJ4e_N55dhM", + "token_type": "bearer", + "expires_in": 3600, + "refresh_token": "LSp8LglPPvf0DxGMSj-vaQ" +} +``` + +The access token can be sent in the Authorization header as a Bearer token for any CRUD operations on supabase-js. See our guide on [Row Level Security](/docs/guides/auth#row-level-security) for more info on restricting access on a user basis. + +Also now that the mobile has been verified, the user can use the number and password to sign in without needing to verify their number each time: + + + + +```js +let { user, error } = await supabase.auth.signIn({ + phone: '+13334445555', + password: 'some-password', +}) +``` + + + + +```bash +curl -X POST 'https://cvwawazfelidkloqmbma.supabase.co/auth/v1/token?grant_type=password' \ +-H "apikey: SUPABASE_KEY" \ +-H "Content-Type: application/json" \ +-d '{ + "phone": "+13334445555", + "password": "some-password" +}' +``` + + + + +### Using OTP as a passwordless sign-in mechanism + +In this scenario you are granting your user's the ability to login to their account without needing to set a password on their account, all they have to do to log in is verify their mobile each time using the OTP. + +In javascript we can use the `signIn` method with a single parameter: `phone` + + + + +```js +let { user, error } = await supabase.auth.signIn({ + phone: '+13334445555', +}) +``` + + + + +```bash +curl -X POST 'https://cvwawazfelidkloqmbma.supabase.co/auth/v1/otp' \ +-H "apikey: SUPABASE_KEY" \ +-H "Content-Type: application/json" \ +-d '{ + "phone": "+13334445555" +}' +``` + + + + +The second step is the same as the previous section, you need to collect the 6-digit pin from the user and pass it along with their phone number to the verify method: + + + + +```js +let { session, error } = await supabase.auth.verifyOTP({ + phone: '+13334445555', + token: '123456', +}) +``` + + + + +```bash +curl -X POST 'https://cvwawazfelidkloqmbma.supabase.co/auth/v1/verify' \ +-H "apikey: SUPABASE_KEY" \ +-H "Content-Type: application/json" \ +-d '{ + "type": "sms", + "phone": "+13334445555", + "token": "123456" +}' +``` + + + + +and the response should also be the same as above: + +```json +{ + "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZXhwIjoxNjI3MjkxNTc3LCJzdWIiOiJmYTA2NTQ1Zi1kYmI1LTQxY2EtYjk1NC1kOGUyOTg4YzcxOTEiLCJlbWFpbCI6IiIsInBob25lIjoiNjU4NzUyMjAyOSIsImFwcF9tZXRhZGF0YSI6eyJwcm92aWRlciI6InBob25lIn0sInVzZXJfbWV0YWRhdGEiOnt9LCJyb2xlIjoiYXV0aGVudGljYXRlZCJ9.1BqRi0NbS_yr1f6hnr4q3s1ylMR3c1vkiJ4e_N55dhM", + "token_type": "bearer", + "expires_in": 3600, + "refresh_token": "LSp8LglPPvf0DxGMSj-vaQ" +} +``` + +The user does not have a password therefore will need to sign in via this method each time they want to access your service. + +## Resources + +- [MessageBird Signup](https://dashboard.messagebird.com/en/sign-up) +- [Supabase Dashboard](https://app.supabase.io) +- [Supabase Row Level Security](/docs/guides/auth#row-level-security) diff --git a/apps/temp-docs/docs/guides/auth/auth-slack.mdx b/apps/temp-docs/docs/guides/auth/auth-slack.mdx new file mode 100644 index 00000000000..cecc8ad6cd7 --- /dev/null +++ b/apps/temp-docs/docs/guides/auth/auth-slack.mdx @@ -0,0 +1,111 @@ +--- +id: auth-slack +title: 'Login with Slack' +description: Add Slack OAuth to your Supabase project +--- + +import Tabs from '@theme/Tabs' +import TabsPanel from '@theme/TabsPanel' + +To enable Slack Auth for your project, you need to set up a Slack OAuth application and add the application credentials to your Supabase Dashboard. + +## Overview + +Setting up Slack logins for your application consists of 3 parts: + +- Create and configure a Slack Project and App on the [Slack Developer Dashboard](https://api.slack.com/apps). +- Add your Slack `API Key` and `API Secret Key` to your [Supabase Project](https://supabase.com). +- Add the login code to your [Supabase JS Client App](https://github.com/supabase/supabase-js). + +## Steps + +### Access your Slack Developer account + +- Go to [api.slack.com](https://api.slack.com/apps). +- Click on `Your Apps` at the top right to log in. + +![Slack Developer Portal.](/docs/img/guides/slack-portal.png) + +### Find your callback URL + +The next step requires a callback URL, which looks like this: + +`https://.supabase.co/auth/v1/callback` + +- Go to your [Supabase Project Dashboard](https://supabase.com). +- Click on the `Settings` icon at the bottom of the left sidebar. +- Click on `API` in the list. +- Under Config / URL you'll find your API URL, you can click `Copy` to copy it to the clipboard. +- Now just add `/auth/v1/callback` to the end of that to get your full `OAuth Redirect URI`. + + + +### Create a Slack OAuth app + +- Go to [api.slack.com](https://api.slack.com/apps). +- Click on `Create an App` + +Under `Create an app...`: + +- Click `From scratch` +- Type the name of your app +- Select your `Slack Workspace` +- Click `Create App` + +Under `App Credentials`: + +- Copy and save your newly-generated `Client ID` +- Copy and save your newly-generated `Client Secret` +- Click `Permissions` + +Under `Redirect URLs`: + +- Click `Add New Redirect URL` +- Paste your `Callback URL` then click `Add` +- Click `Save URLs` + +### Enter your Slack credentials into your Supabase Project + +- Go to your [Supabase Project Dashboard](https://supabase.com). +- In the left sidebar, click the `Authentication` icon (near the top). +- Click `Settings` from the list to go to the `Authentication Settings` page. +- Enter the final (hosted) URL of your app under `Site URL` (this is important). +- Under `External OAuth Providers` turn `Slack Enabled` to ON. +- Enter your `API Key` (`client_id`) and `API Secret Key` (`client_secret`) saved in the previous step. +- Click `Save`. + +### Add login code to your client app + +The JavaScript client code is documented here: [Supabase OAuth Client Code](/docs/reference/javascript/auth-signin#sign-in-using-third-party-providers). + +```js +const { user, session, error } = await supabase.auth.signIn({ + provider: 'slack', +}) +``` + +Add this function which you can call from a button, link, or UI element. + +```js +async function signInWithSlack() { + const { user, session, error } = await supabase.auth.signIn({ + provider: 'slack', + }) +} +``` + +To log out: + +```js +async function signout() { + const { error } = await supabase.auth.signOut() +} +``` + +## Resources + +- [Supabase Account - Free Tier OK](https://supabase.com) +- [Supabase JS Client](https://github.com/supabase/supabase-js) +- [Slack Developer Dashboard](https://api.slack.com/apps) diff --git a/apps/temp-docs/docs/guides/auth/auth-spotify.mdx b/apps/temp-docs/docs/guides/auth/auth-spotify.mdx new file mode 100644 index 00000000000..9b4a4642bc4 --- /dev/null +++ b/apps/temp-docs/docs/guides/auth/auth-spotify.mdx @@ -0,0 +1,106 @@ +--- +id: auth-spotify +title: 'Login with Spotify' +description: Add Spotify OAuth to your Supabase project +--- + +import Tabs from '@theme/Tabs' +import TabsPanel from '@theme/TabsPanel' + +To enable Spotify Auth for your project, you need to set up a Spotify OAuth application and add the application credentials to your Supabase Dashboard. + +## Overview + +Setting up Spotify logins for your application consists of 3 parts: + +- Create and configure a Spotify Project and App on the [Spotify Developer Dashboard](https://developer.spotify.com/dashboard/). +- Add your Spotify `API Key` and `API Secret Key` to your [Supabase Project](https://supabase.com). +- Add the login code to your [Supabase JS Client App](https://github.com/supabase/supabase-js). + +## Steps + +### Access your Spotify Developer account + +- Log into [Spotify](https://spotify.com) +- Access the [Spotify Developer Dashboard](https://developer.spotify.com/dashboard) + +![Spotify Developer Portal.](/docs/img/guides/spotify-portal.png) + +### Find your callback URL + +The next step requires a callback URL, which looks like this: + +`https://.supabase.co/auth/v1/callback` + +- Go to your [Supabase Project Dashboard](https://supabase.com). +- Click on the `Settings` icon at the bottom of the left sidebar. +- Click on `API` in the list. +- Under Config / URL you'll find your API URL, you can click `Copy` to copy it to the clipboard. +- Now just add `/auth/v1/callback` to the end of that to get your full `OAuth Redirect URI`. + + + +### Create a Spotify OAuth app + +- Log into [Spotify](https://spotify.com). +- Go to the [Spotify Developer Dashboard](https://developer.spotify.com/dashboard) +- Click `Create an App` +- Type your `App name` +- Type your `App description` +- Check the box to agree with the `Developer TOS and Branding Guidelines` +- Click `Create` +- Save your `Client ID` +- Save your `Client Secret` +- Click `Edit Settings` + +Under `Redirect URIs`: + +- Paste your Supabase Callback URL in the box +- Click `Add` +- Click `Save` at the bottom + +### Enter your Spotify credentials into your Supabase Project + +- Go to your [Supabase Project Dashboard](https://supabase.com). +- In the left sidebar, click the `Authentication` icon (near the top). +- Click `Settings` from the list to go to the `Authentication Settings` page. +- Enter the final (hosted) URL of your app under `Site URL` (this is important). +- Under `External OAuth Providers` turn `Spotify Enabled` to ON. +- Enter your `API Key` (`client_id`) and `API Secret Key` (`client_secret`) saved in the previous step. +- Click `Save`. + +### Add login code to your client app + +The JavaScript client code is documented here: [Supabase OAuth Client Code](/docs/reference/javascript/auth-signin#sign-in-using-third-party-providers). + +```js +const { user, session, error } = await supabase.auth.signIn({ + provider: 'spotify', +}) +``` + +Add this function which you can call from a button, link, or UI element. + +```js +async function signInWithSpotify() { + const { user, session, error } = await supabase.auth.signIn({ + provider: 'spotify', + }) +} +``` + +To log out: + +```js +async function signout() { + const { error } = await supabase.auth.signOut() +} +``` + +## Resources + +- [Supabase Account - Free Tier OK](https://supabase.com) +- [Supabase JS Client](https://github.com/supabase/supabase-js) +- [Spotify Developer Dashboard](https://developer.spotify.com/dashboard/) diff --git a/apps/temp-docs/docs/guides/auth/auth-twilio.mdx b/apps/temp-docs/docs/guides/auth/auth-twilio.mdx new file mode 100644 index 00000000000..820a68bdbc1 --- /dev/null +++ b/apps/temp-docs/docs/guides/auth/auth-twilio.mdx @@ -0,0 +1,299 @@ +--- +id: auth-twilio +title: Phone Auth with Twilio +description: How to set up and use Mobile OTP with Twilio and Supabase. +--- + +import Tabs from '@theme/Tabs' +import TabsPanel from '@theme/TabsPanel' + +## Overview + +In this guide we'll show you how to authenticate your users with SMS based OTP (One-Time Password) tokens. + +There are two reasons to use Supabase SMS OTP tokens: + +- You want users to log in with mobile + password, and the mobile should be verified via SMS +- You want users to log in with mobile ONLY (i.e. passwordless login) + +We'll cover: + +- [Finding your Twilio credentials](#finding-your-twilio-credentials) +- [Using OTP with password based logins](#using-otp-with-password-based-logins) +- [Using OTP as a passwordless sign-in mechanism](#using-otp-as-a-passwordless-sign-in-mechanism) + +What you'll need: + +- A twilio account (sign up here: https://www.twilio.com/try-twilio) +- A Supabase project (create one here: https://app.supabase.io) +- A mobile phone capable of receiving SMS + +## Video + + + +## Steps + +### Finding your Twilio credentials + +Start by logging into your Twilio account and starting a new project: https://www.twilio.com/console/projects/create + +Give your project a name and verify the mobile number you'll be using to test with. This is the number that will be receiving the SMS OTPs. + +![Name your twilio project](/docs/img/guides/auth-twilio/1.png) +![verify your own phone number](/docs/img/guides/auth-twilio/2.png) + +Select 'SMS', 'Identity & Verification', and 'With code' as options on the welcome form. + +![Form Fields](/docs/img/guides/auth-twilio/3.png) + +When you're back on the https://www.twilio.com/console screen, you need to scroll down and click 'Get a trial phone number' - this is the number that you'll be sending SMSs from. + +![Get a trial phone number](/docs/img/guides/auth-twilio/4.png) + +![Successful phone number](/docs/img/guides/auth-twilio/5.png) + +You should now be able to see all three values you'll need to get started: + +- Account SID +- Auth Token +- Sender Phone Number + +![All the credentials you'll need](/docs/img/guides/auth-twilio/6.png) + +Now go to the Auth > Settings page in the Supabase dashboard (https://app.supabase.io/project/YOUR-PROJECT-REF/auth/settings). + +You should see an option to enable Phone Signup. + +![Enable Phone Sign-Up](/docs/img/guides/auth-twilio/7.png) + +Toggle it on, and copy the 3 values over from the twilio dashboard. Click save. + +Note: for "Twilio Message Service SID" you can use the Sender Phone Number generated above. + +![Plug in Twilio credentials](/docs/img/guides/auth-twilio/8.png) + +Now the backend should be setup, we can proceed to add our client-side code! + +#### SMS custom template + +The SMS message sent to a phone containing an OTP code can be customized. This is useful if you need to mention a brand name or display a website address. + +Go to Auth > Templates page in the Supabase dashboard (https://app.supabase.io/project/YOUR-PROJECT-REF/auth/templates). + +Use the variable `.Code` in the template to display the code. + +### Using OTP with password based logins + +In this use scenario we'll be using the user's mobile phone number as an alternative to an email address when signing up along with a password. You may want to think hard about the permanency of this however. It is not uncommon for mobile phone numbers to be recycled by phone networks when users cancel their phone contracts or move countries, therefore granting access to the user's account to whoever takes over the phone number in the future. Soon we'll add multi-factor auth, which will mitigate this risk, but for now you may want to give some thought to allowing your users to recover their account by some other means in an emergency. + +Using supabase-js on the client you'll want to use the same `signUp` method that you'd use for email based sign ups, but with the `phone` param instead of the `email param`: + + + + +```js +let { user, error } = await supabase.auth.signUp({ + phone: '+13334445555', + password: 'some-password', +}) +``` + + + + +```bash +curl -X POST 'https://cvwawazfelidkloqmbma.supabase.co/auth/v1/signup' \ +-H "apikey: SUPABASE_KEY" \ +-H "Content-Type: application/json" \ +-d '{ + "phone": "+13334445555", + "password": "some-password" +}' +``` + + + + +The user will now receive an SMS with a 6-digit pin that you will need to receive from them within 60-seconds before they can login to their account. + +You should present a form to the user so they can input the 6 digit pin, then send it along with the phone number to `verifyOTP`: + + + + +```js +let { session, error } = await supabase.auth.verifyOTP({ + phone: '+13334445555', + token: '123456', +}) +``` + + + + +```bash +curl -X POST 'https://cvwawazfelidkloqmbma.supabase.co/auth/v1/verify' \ +-H "apikey: SUPABASE_KEY" \ +-H "Content-Type: application/json" \ +-d '{ + "type": "sms", + "phone": "+13334445555", + "token": "123456" +}' +``` + + + + +If successful the user will now be logged in and you should receive a valid session like: + +```json +{ + "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZXhwIjoxNjI3MjkxNTc3LCJzdWIiOiJmYTA2NTQ1Zi1kYmI1LTQxY2EtYjk1NC1kOGUyOTg4YzcxOTEiLCJlbWFpbCI6IiIsInBob25lIjoiNjU4NzUyMjAyOSIsImFwcF9tZXRhZGF0YSI6eyJwcm92aWRlciI6InBob25lIn0sInVzZXJfbWV0YWRhdGEiOnt9LCJyb2xlIjoiYXV0aGVudGljYXRlZCJ9.1BqRi0NbS_yr1f6hnr4q3s1ylMR3c1vkiJ4e_N55dhM", + "token_type": "bearer", + "expires_in": 3600, + "refresh_token": "LSp8LglPPvf0DxGMSj-vaQ" +} +``` + +The access token can be sent in the Authorization header as a Bearer token for any CRUD operations on supabase-js. See our guide on [Row Level Security](/docs/guides/auth#row-level-security) for more info on restricting access on a user basis. + +Also now that the mobile has been verified, the user can use the number and password to sign in without needing to verify their number each time: + + + + +```js +let { user, error } = await supabase.auth.signIn({ + phone: '+13334445555', + password: 'some-password', +}) +``` + + + + +```bash +curl -X POST 'https://cvwawazfelidkloqmbma.supabase.co/auth/v1/token?grant_type=password' \ +-H "apikey: SUPABASE_KEY" \ +-H "Content-Type: application/json" \ +-d '{ + "phone": "+13334445555", + "password": "some-password" +}' +``` + + + + +### Using OTP as a passwordless sign-in mechanism + +In this scenario you are granting your user's the ability to login to their account without needing to set a password on their account, all they have to do to log in is verify their mobile each time using the OTP. + +In javascript we can use the `signIn` method with a single parameter: `phone` + + + + +```js +let { user, error } = await supabase.auth.signIn({ + phone: '+13334445555', +}) +``` + + + + +```bash +curl -X POST 'https://cvwawazfelidkloqmbma.supabase.co/auth/v1/otp' \ +-H "apikey: SUPABASE_KEY" \ +-H "Content-Type: application/json" \ +-d '{ + "phone": "+13334445555" +}' +``` + + + + +The second step is the same as the previous section, you need to collect the 6-digit pin from the user and pass it along with their phone number to the verify method: + + + + +```js +let { session, error } = await supabase.auth.verifyOTP({ + phone: '+13334445555', + token: '123456', +}) +``` + + + + +```bash +curl -X POST 'https://cvwawazfelidkloqmbma.supabase.co/auth/v1/verify' \ +-H "apikey: SUPABASE_KEY" \ +-H "Content-Type: application/json" \ +-d '{ + "type": "sms", + "phone": "+13334445555", + "token": "123456" +}' +``` + + + + +and the response should also be the same as above: + +```json +{ + "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZXhwIjoxNjI3MjkxNTc3LCJzdWIiOiJmYTA2NTQ1Zi1kYmI1LTQxY2EtYjk1NC1kOGUyOTg4YzcxOTEiLCJlbWFpbCI6IiIsInBob25lIjoiNjU4NzUyMjAyOSIsImFwcF9tZXRhZGF0YSI6eyJwcm92aWRlciI6InBob25lIn0sInVzZXJfbWV0YWRhdGEiOnt9LCJyb2xlIjoiYXV0aGVudGljYXRlZCJ9.1BqRi0NbS_yr1f6hnr4q3s1ylMR3c1vkiJ4e_N55dhM", + "token_type": "bearer", + "expires_in": 3600, + "refresh_token": "LSp8LglPPvf0DxGMSj-vaQ" +} +``` + +The user does not have a password therefore will need to sign in via this method each time they want to access your service. + +## Resources + +- [Twilio Signup](https://www.twilio.com/try-twilio) +- [Supabase Dashboard](https://app.supabase.io) +- [Supabase Row Level Security](/docs/guides/auth#row-level-security) diff --git a/apps/temp-docs/docs/guides/auth/auth-twitch.mdx b/apps/temp-docs/docs/guides/auth/auth-twitch.mdx new file mode 100644 index 00000000000..c2071c3c22d --- /dev/null +++ b/apps/temp-docs/docs/guides/auth/auth-twitch.mdx @@ -0,0 +1,118 @@ +--- +id: auth-twitch +title: 'Login with Twitch' +description: Add Twitch OAuth to your Supabase project +--- + +import Tabs from '@theme/Tabs' +import TabsPanel from '@theme/TabsPanel' + +To enable Twitch Auth for your project, you need to set up a Twitch Application and add the Application OAuth credentials to your Supabase Dashboard. + +## Overview + +Setting up Twitch logins for your application consists of 3 parts: + +- Create and configure a Twitch Application [Twitch Developer Console](https://dev.twitch.tv/console) +- Add your Twitch OAuth Consumer keys to your [Supabase Project](https://supabase.com) +- Add the login code to your [Supabase JS Client App](https://github.com/supabase/supabase-js) + +## Steps + +### Access your Twitch Developer account + +- Go to [dev.twitch.tv](https://dev.twitch.tv). +- Click on `Log in with Twitch` at the top right to log in. +- If you have not already enabled 2-Factor Authentication for your Twitch Account, you will need to do that at [Twitch Security Settings](https://www.twitch.tv/settings/security) before you can continue. + +![Twitch Developer Page](/docs/img/guides/twitch-developer-page.png) + +- Once logged in, go to the [Twitch Developer Console](https://dev.twitch.tv/console). + +![Twitch Developer Console](/docs/img/guides/twitch-console.png) + +### Find your callback URL + +In the next step you require a callback URL, which looks like this: + +`https://.supabase.co/auth/v1/callback` + +- Go to your [Supabase Project Dashboard](https://supabase.com). +- Click on the `Settings` icon at the bottom of the left sidebar. +- Click on `API` in the list. +- Under Config / URL you'll find your API URL, you can click `Copy` to copy it to the clipboard. +- Now just add `/auth/v1/callback` to the end of that to get your full `OAuth Redirect URI`. + + + +### Create a Twitch Application + +![Twitch Developer Console](/docs/img/guides/twitch-console.png) + +- Click on `+ Register Your Application` at the top right. + +![Register Application](/docs/img/guides/twitch-register-your-application.png) + +- Enter the name of your application. +- Type or paste your `OAuth Redirect URL` (the callback URL from the previous step.) +- Select a category for your app. +- Check the Captcha box and click `Create`. + +### Retrieve your Twitch OAuth Client ID and Client Secret + +- Click `Manage` at the right of your application entry in the list. + +![Twitch Applications List](/docs/img/guides/twitch-applications-list.png) + +- Copy your Client ID. +- Click `New Secret` to create a new Client Secret. +- Copy your Client Secret. + +![Get Client ID and Secret](/docs/img/guides/twitch-get-keys.png) + +### Add your Twitch credentials into your Supabase Project + +- Go to your [Supabase Project Dashboard](https://supabase.com) +- In the left sidebar, click the `Authentication` icon (near the top) +- Click `Settings` from the list to go to the `Authentication Settings` page +- Enter the final (hosted) URL of your app under `Site URL` (this is important) +- Under `External OAuth Providers` turn `Twitch Enabled` to ON +- Enter your `client_id` and `client_secret` saved in the previous step +- Click `Save` + +### Add login code to your client app + +The JavaScript client code is documented here: [Supabase OAuth Client Code](/docs/reference/javascript/auth-signin#sign-in-using-third-party-providers) + +```js +const { user, session, error } = await supabase.auth.signIn({ + provider: 'twitch', +}) +``` + +Add this function which you can call from a button, link, or UI element. + +```js +async function signInWithTwitch() { + const { user, session, error } = await supabase.auth.signIn({ + provider: 'twitch', + }) +} +``` + +To log out: + +```js +async function signout() { + const { error } = await supabase.auth.signOut() +} +``` + +## Resources + +- [Supabase Account - Free Tier OK](https://supabase.com) +- [Supabase JS Client](https://github.com/supabase/supabase-js) +- [Twitch Account](https://twitch.tv) +- [Twitch Developer Console](https://dev.twitch.tv/console) diff --git a/apps/temp-docs/docs/guides/auth/auth-twitter.mdx b/apps/temp-docs/docs/guides/auth/auth-twitter.mdx new file mode 100644 index 00000000000..7be907d29e0 --- /dev/null +++ b/apps/temp-docs/docs/guides/auth/auth-twitter.mdx @@ -0,0 +1,107 @@ +--- +id: auth-twitter +title: 'Login with Twitter' +description: Add Twitter OAuth to your Supabase project +--- + +import Tabs from '@theme/Tabs' +import TabsPanel from '@theme/TabsPanel' + +To enable Twitter Auth for your project, you need to set up a Twitter OAuth application and add the application credentials to your Supabase Dashboard. + +## Overview + +Setting up Twitter logins for your application consists of 3 parts: + +- Create and configure a Twitter Project and App on the [Twitter Developer Dashboard](https://developer.twitter.com/en/portal/dashboard). +- Add your Twitter `API Key` and `API Secret Key` to your [Supabase Project](https://supabase.com). +- Add the login code to your [Supabase JS Client App](https://github.com/supabase/supabase-js). + +## Steps + +### Access your Twitter Developer account + +- Go to [developer.twitter.com](https://developer.twitter.com). +- Click on `Sign in` at the top right to log in. + +![Twitter Developer Portal.](/docs/img/guides/twitter-portal.png) + +### Find your callback URL + +The next step requires a callback URL, which looks like this: + +`https://.supabase.co/auth/v1/callback` + +- Go to your [Supabase Project Dashboard](https://supabase.com). +- Click on the `Settings` icon at the bottom of the left sidebar. +- Click on `API` in the list. +- Under Config / URL you'll find your API URL, you can click `Copy` to copy it to the clipboard. +- Now just add `/auth/v1/callback` to the end of that to get your full `OAuth Redirect URI`. + + + +### Create a Twitter OAuth app + +- Click `+ Create Project`. + - Enter your project name, click `Next`. + - Select your use case, click `Next`. + - Enter a description for your project, click `Next`. + - Enter a name for your app, click `Complete`. + - Copy and save your `API Key` (this is your `client_id`). + - Copy and save your `API Secret Key` (this is your `client_secret`). +- At the bottom, under `Next, setup your App` click the link `enable 3rd party authentication`. +- Under `App Settings`, click on the gear icon next to your app name to go to `App Settings`. +- At the bottom, next to `Authentication settings`, click `Edit`. +- Turn `Enable 3-legged OAuth` ON. +- Turn `Request email address from users` ON. +- Enter your `Callback URL`. +- Enter your `Website URL`. +- Enter your `Terms of service URL`. +- Enter your `Privacy policy URL`. +- Click `Save`. + +### Enter your Twitter credentials into your Supabase Project + +- Go to your [Supabase Project Dashboard](https://supabase.com). +- In the left sidebar, click the `Authentication` icon (near the top). +- Click `Settings` from the list to go to the `Authentication Settings` page. +- Enter the final (hosted) URL of your app under `Site URL` (this is important). +- Under `External OAuth Providers` turn `Twitter Enabled` to ON. +- Enter your `API Key` (`client_id`) and `API Secret Key` (`client_secret`) saved in the previous step. +- Click `Save`. + +### Add login code to your client app + +The JavaScript client code is documented here: [Supabase OAuth Client Code](/docs/reference/javascript/auth-signin#sign-in-using-third-party-providers). + +```js +const { user, session, error } = await supabase.auth.signIn({ + provider: 'twitter', +}) +``` + +Add this function which you can call from a button, link, or UI element. + +```js +async function signInWithTwitter() { + const { user, session, error } = await supabase.auth.signIn({ + provider: 'twitter', + }) +} +``` + +To log out: + +```js +async function signout() { + const { error } = await supabase.auth.signOut() +} +``` + +## Resources + +- [Supabase Account - Free Tier OK](https://supabase.com) +- [Supabase JS Client](https://github.com/supabase/supabase-js) +- [Twitter Developer Dashboard](https://developer.twitter.com/en/portal/dashboard) diff --git a/apps/temp-docs/docs/guides/auth/intro.mdx b/apps/temp-docs/docs/guides/auth/intro.mdx new file mode 100644 index 00000000000..a4b0dabf47a --- /dev/null +++ b/apps/temp-docs/docs/guides/auth/intro.mdx @@ -0,0 +1,50 @@ +--- +id: intro +title: Supabase Auth +sidebar_label: Introduction +description: Use Supabase to Authenticate and Authorize your users. +# hide_table_of_contents: true +--- + + + + +## Introduction + +Supabase Auth is designed to work with Postgres. There are two parts to every Auth system: + +- **Authentication:** should this person be allowed in? If yes, who are they? +- **Authorization:** once they are in, what are they allowed to do? + +## Authentication + +You can authenticate your users in several ways: + +- Email & password. +- Magic links (one-click logins). +- Social providers. +- Phone logins. + +
    +
    + +
    +
    + + +## Authorization + + +When you need granular authorization rules, nothing beats PostgreSQL's Row Level Security (RLS). + +Policies are PostgreSQL's rule engine. They are incredibly powerful and flexible, allowing you to write complex SQL rules which fit your unique business needs. + +Get started with our [Row Level Security Guides](/docs/guides/auth/row-level-security). diff --git a/apps/temp-docs/docs/guides/auth/managing-user-data.mdx b/apps/temp-docs/docs/guides/auth/managing-user-data.mdx new file mode 100644 index 00000000000..d0affd2a189 --- /dev/null +++ b/apps/temp-docs/docs/guides/auth/managing-user-data.mdx @@ -0,0 +1,109 @@ +--- +id: managing-user-data +title: Managing User Data +description: Securing your user data with Row Level Security. +--- + +For security purposes, the `auth` schema is not exposed on the auto-generated API. + +Even though Supabase provides an `auth.users` table, it can be helpful to create tables in the `public` schema for storing user data that you want to access via the API. + +## Creating user tables + +When you create tables to store user data, it's helpful to reference the `auth.users` table in the primary key. This ensures data integrity. + +For example, a `public.profiles` table might look like this: + +```sql +create table public.profiles ( + id uuid references auth.users not null, + first_name text, + last_name text, + + primary key (id) +); + +alter table public.profiles enable row level security; +``` + + +## Public access + +Since Row Level Security is enabled, this table is accessible via the API but no data will be returned unless we set up some Policies. +If we wanted the data to be _readable_ by everyone but only allow logged-in users to update their own data, the Policies would look like this: + +```sql +create policy "Public profiles are viewable by everyone." + on profiles for select + using ( true ); + +create policy "Users can insert their own profile." + on profiles for insert + with check ( auth.uid() = id ); + +create policy "Users can update own profile." + on profiles for update + using ( auth.uid() = id ); +``` + +## Private access + +If the data should only be _readable_ by the user who owns the data, we just need to change the `for select` query above. + +```sql +create policy "Profiles are viewable by users who created them." + on profiles for select + using ( auth.uid() = id ); +``` + +The nice thing about this pattern? We can now query this table via the API and we don't need to include data filters in our API queries - the Policies will handle that for us: + +```js +// This will return nothing while the user is logged out +const { data } = await supabase + .from('profiles') + .select('id, username, avatar_url, website') + +// After the user is logged in, this will only return +// the logged-in user's data - in this case a single row +const { error } = await supabase.auth.signIn({ email }) +const { data: profile } = await supabase + .from('profiles') + .select('id, username, avatar_url, website') +``` + +## Bypassing Row Level Security + +If you need to fetch a full list of user profiles, we supply a `service_key` which you can use with your API and Client Libraries to bypass Row Level Security. + +Make sure you _NEVER_ expose this publicly. But it can be used on the server-side to fetch all of the profiles. + + +## Advanced techniques + +### Using triggers + +If you want to add a row to your `public.profiles` table every time a user signs up, you can use triggers. +If the trigger fails however, it could block the user sign ups - so make sure that the code is well-tested. + +For example: + +```sql +-- inserts a row into public.users +create function public.handle_new_user() +returns trigger +language plpgsql +security definer set search_path = public +as $$ +begin + insert into public.profiles (id) + values (new.id); + return new; +end; +$$; + +-- trigger the function every time a user is created +create trigger on_auth_user_created + after insert on auth.users + for each row execute procedure public.handle_new_user(); +``` diff --git a/apps/temp-docs/docs/guides/auth/row-level-security.mdx b/apps/temp-docs/docs/guides/auth/row-level-security.mdx new file mode 100644 index 00000000000..5ee6a1a7ff0 --- /dev/null +++ b/apps/temp-docs/docs/guides/auth/row-level-security.mdx @@ -0,0 +1,315 @@ +--- +id: row-level-security +title: Row Level Security +description: Secure your data using Postgres Row Level Security. +--- + +When you need granular authorization rules, nothing beats PostgreSQL's [Row Level Security (RLS)](https://www.postgresql.org/docs/current/ddl-rowsecurity.html). + +[Policies](https://www.postgresql.org/docs/current/sql-createpolicy.html) are PostgreSQL's rule engine. They are incredibly powerful and flexible, allowing you to write complex SQL rules which fit your unique business needs. + + + + +## Policies + +Policies are easy to understand once you get the hang of them. Each policy is attached to a table, and the policy is executed +every time a table is accessed. +You can just think of them as adding a `WHERE` clause to every query. For example a policy like this ... + +```sql +create policy "Individuals can view their own todos." + on todos for select + using ( auth.uid() = user_id ); +``` + +.. would translate to this whenever a user tries to select from the todos table: + +```sql +select * +from todos +where auth.uid() = todos.user_id; -- Policy is implicitly added. +``` + +## Helper Functions + +Supabase provides you with a few easy functions that you can use with your policies. + + +### `auth.uid()` + +Returns the ID of the user making the request. + +### `auth.role()` + +Returns the role of the user making the request. In most cases this is either `authenticated` or `anon`. + +### `auth.email()` + +Returns the email of the user making the request. + +## Examples + +Here are some examples to show you the power of PostgreSQL's RLS. + +### Allow read access + +```sql +-- 1. Create table +create table profiles ( + id uuid references auth.users, + avatar_url text +); + +-- 2. Enable RLS +alter table profiles + enable row level security; + +-- 3. Create Policy +create policy "Public profiles are viewable by everyone." + on profiles for select using ( + true + ); +``` + +1. Creates a table called `profiles` in the public schema (default schema). +2. Enables Row Level Security. +3. Creates a policy which allows all `select` queries to run. + +### Restrict updates + +```sql +-- 1. Create table +create table profiles ( + id uuid references auth.users, + avatar_url text +); + +-- 2. Enable RLS +alter table profiles + enable row level security; + +-- 3. Create Policy +create policy "Users can update their own profiles." + on profiles for update using ( + auth.uid() = id + ); +``` + +1. Creates a table called `profiles` in the public schema (default schema). +2. Enables RLS. +3. Creates a policy which allows logged in users to update their own data. + +### Policies with joins + +Policies can even include table joins. This example shows how you can query "external" tables to build more advanced rules. + +```sql +create table teams ( + id serial primary key, + name text +); + +-- 2. Create many to many join +create table members ( + team_id bigint references teams, + user_id uuid references auth.users +); + +-- 3. Enable RLS +alter table teams + enable row level security; + +-- 4. Create Policy +create policy "Team members can update team details if they belong to the team." + on teams + for update using ( + auth.uid() in ( + select user_id from members + where team_id = id + ) + ); +``` + +**Note:** If RLS is also enabled for _members_, the user must also have read (_select_) access to _members_. Otherwise the joined query will not yield any results. + +### Policies with security definer functions + +Policies can also make use of `security definer functions`. This is useful in a many-to-many relationship where you want to restrict access to the linking table. Following the `teams` and `members` example from above, this example shows how you can use the security definer function in combination with a policy to control access to the `members` table. + +```sql +-- 1. Follow example for 'Policies with joins' above + +-- 2. Enable RLS +alter table members + enable row level security + +-- 3. Create security definer function +create or replace function get_teams_for_authenticated_user() +returns setof bigint +language sql +security definer +set search_path = public +stable +as $$ + select team_id + from members + where user_id = auth.uid() +$$; + +-- 4. Create Policy +create policy "Team members can update team members if they belong to the team." + on members + for all using ( + team_id in ( + select get_teams_for_authenticated_user() + ) + ); + +``` + +### Verifying email domains + +Postgres has a function `right(string, n)` that returns the rightmost n characters of a string. +You could use this to match staff member's email domains. + +```sql +-- 1. Create table +create table leaderboard ( + id uuid references auth.users, + high_score bigint +); + +-- 2. Enable RLS +alter table leaderboard + enable row level security; + +-- 3. Create Policy +create policy "Only Blizzard staff can update leaderboard" + on leaderboard + for update using ( + right(auth.email(), 13) = '@blizzard.com' + ); +``` + +### Time to live for rows + +Policies can also be used to implement TTL or time to live feature that you see in Instagram stories or Snapchat. +In the following example, rows of `stories` table are available only if they have been created within the last 24 hours. + +```sql +-- 1. Create table +create table if not exists stories ( + id uuid not null primary key DEFAULT uuid_generate_v4(), + created_at timestamp with time zone default timezone('utc' :: text, now()) not null, + content text not null +); + +-- 2. Enable RLS +alter table stories + enable row level security; + +-- 3. Create Policy +create policy "Stories are live for a day" + on stories + for select using ( + created_at > (current_timestamp - interval '1 day') + ); +``` + +### Advanced policies + +Use the full power of SQL to build extremely advanced rules. + +In this example, we will create a `posts` and `comments` tables and then create a policy that depends on another policy. +(In this case, the comments policy depends on the posts policy.) + +```sql +create table posts ( + id serial primary key, + creator_id uuid not null references auth.users(id), + title text not null, + body text not null, + publish_date date not null default now(), + audience uuid[] null -- many to many table omitted for brevity +); + +create table comments ( + id serial primary key, + post_id int not null references posts(id) on delete cascade, + user_id uuid not null references auth.users(id), + body text not null, + comment_date date not null default now() +); + +create policy "Creator can see their own posts" +on posts +for select +using ( + auth.uid() = posts.creator_id +); + +create policy "Logged in users can see the posts if they belong to the post 'audience'." +on posts +for select +using ( + auth.uid() = any (posts.audience) +); + +create policy "Users can see all comments for posts they have access to." +on comments +for select +using ( + exists ( + select 1 from posts + where posts.id = comments.post_id + ) +); +``` + + +## Tips + +### Disable realtime for private tables + +Our realtime server doesn't provide per-user security. Until we build a more robust auth system for WebSockets, you can disable realtime functionality for any private tables. To do this, you can manage the underlying Postgres replication publication: + +```sql +/** + * REALTIME SUBSCRIPTIONS + * Only allow realtime listening on public tables. + */ + +begin; + -- remove the realtime publication + drop publication if exists supabase_realtime; + + -- re-create the publication but don't enable it for any tables + create publication supabase_realtime; +commit; + +-- add a table to the publication +alter publication supabase_realtime add table products; + +-- add other tables to the publication +alter publication supabase_realtime add table posts; +``` + +We're in the process of building [enhanced realtime security](https://github.com/supabase/walrus). + +### You don't have to use policies + +You can also put your authorization rules in your middleware, similar to how you would create security rules with any other `backend <-> middleware <-> frontend` architecture. + +Policies are a tool. In the case of "serverless/Jamstack" setups, they are especially effective because you don't have to deploy any middleware at all. + +However, if you want to use another authorization method for your applications, that's also fine. Supabase is "just Postgres", so if your application +works with Postgres, then it also works with Supabase. + +Tip: Make sure to enable RLS for all your tables, so that your tables are inaccessible. Then use the "Service" which we provide, which is designed to bypass RLS. + + +### Never use a service key on the client + +Supabase provides special "Service" keys, which can be used to bypass all RLS. +These should never be used in the browser or exposed to customers, but they are useful for administrative tasks. diff --git a/apps/temp-docs/docs/guides/client-libraries.mdx b/apps/temp-docs/docs/guides/client-libraries.mdx new file mode 100755 index 00000000000..c391ef27835 --- /dev/null +++ b/apps/temp-docs/docs/guides/client-libraries.mdx @@ -0,0 +1,525 @@ +--- +id: client-libraries +title: Client Libraries +description: 'Supabase provides client libraries in several languages.' +--- + + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + + +The [Supabase Client](/docs/reference/javascript/supabase-client) makes it simple for developers to build secure and scalable products. + +## Auth + + +Create new users using [`signUp()`](/docs/reference/javascript/auth-signup). By default, the user will need to verify their email address before logging in.
    +If confirmations are disabled the response will contain an access token and also a confirmed_at value, otherwise it will just contain a confirmation_sent_at attribute. + + + + + +```js +const { error, data } = await supabase.auth.signUp({ + email: 'example@email.com', + password: 'example-password', +}) +``` + + + + + +```py +import os +from supabase_py import create_client, Client + +url: str = os.environ.get("SUPABASE_TEST_URL") +key: str = os.environ.get("SUPABASE_TEST_KEY") +supabase: Client = create_client(url, key) +user = supabase.auth.sign_up( + email='example@email.com', + password='example-password', +) +``` + + + + + + +```dart +import 'package:supabase/supabase.dart'; + +void main() async { + final client = SupabaseClient('supabaseUrl', 'supabaseKey'); + + // Sign up user with email and password + final response = await client + .auth + .signUp('example@email.com', 'example-password'); +} +``` + + + + + + + +Existing users can log in using [`signIn()`](/docs/reference/javascript/auth-signin). + + + + + +```js +const { error, data } = await supabase.auth.signIn({ + email: 'example@email.com', + password: 'example-password' +}) +``` + + + + + +```py +import os +from supabase_py import create_client, Client + +url: str = os.environ.get("SUPABASE_TEST_URL") +key: str = os.environ.get("SUPABASE_TEST_KEY") +supabase: Client = create_client(url, key) +user = supabase.auth.sign_in( + email='example@email.com', + password='example-password' +) +``` + + + + + + +```dart +import 'package:supabase/supabase.dart'; + +void main() async { + final client = SupabaseClient('supabaseUrl', 'supabaseKey'); + + // Sign in user with email and password + final response = await client + .auth + .signIn(email: 'example@email.com', password: 'example-password'); +} +``` + + + + + + +If there is an email, but no password passed to [`signIn()`](/docs/reference/javascript/auth-signin), the user will receive a magic link. + + + + + +```js +const { error, data } = await supabase.auth.signIn({ + email: 'example@email.com' +}) +``` + + + + + +```py +import os +from supabase_py import create_client, Client + +url: str = os.environ.get("SUPABASE_TEST_URL") +key: str = os.environ.get("SUPABASE_TEST_KEY") +supabase: Client = create_client(url, key) +user = supabase.auth.sign_in( + email='example@email.com' +) +``` + + + + + + +```dart +import 'package:supabase/supabase.dart'; + +void main() async { + final client = SupabaseClient('supabaseUrl', 'supabaseKey'); + + // Sign in user with email and magic link + final response = await client + .auth + .signIn(email: 'example@email.com'); +} +``` + + + + + + +Third party logins are also handled through [`signIn()`](/docs/reference/javascript/auth-signin). + + + + + + +```js +const { user, error } = await supabase.auth.signIn({ + // provider can be 'github', 'google', 'gitlab', or 'bitbucket' + provider: 'github' +}) +``` + + + + + +```py +# Not yet implemented +``` + + + + + + +```dart +import 'package:supabase/supabase.dart'; + +void main() async { + final client = SupabaseClient('supabaseUrl', 'supabaseKey'); + + final response = await client + .auth + .signIn(provider: Provider.github); +} +``` + + + + + +## Managing data + +Since Postgres is a Relational database, the client makes it simple to query tables and fetch related data in one round-trip, using [`select()`](/docs/reference/javascript/select). + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .select(` + name, + cities ( + name + ) + `) +``` + + + + + +```py +import os +from supabase_py import create_client, Client + +url: str = os.environ.get("SUPABASE_TEST_URL") +key: str = os.environ.get("SUPABASE_TEST_KEY") +supabase: Client = create_client(url, key) + +data = supabase.table('countries').select('name').execute() +``` + + + + + + +```dart +import 'package:supabase/supabase.dart'; + +void main() async { + final client = SupabaseClient('supabaseUrl', 'supabaseKey'); + + // Query tables and fetch related data in one round-trip, using select() + final response = await client + .from('countries') + .select('name') + .execute(); +} +``` + + + + + + +You can do advanced [filtering](/docs/reference/javascript/using-filters) to extract only the data that you need. + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .lt('country_id', 100) + .limit(10) +``` + + + + + +```py +data = supabase.table('cities').select('name, country_id').eq('name', 'Germany').execute() +# Assert we pulled real data. +assert len(data.get("data", [])) > 0 +``` + + + + + + +```dart +import 'package:supabase/supabase.dart'; + +void main() async { + final client = SupabaseClient('supabaseUrl', 'supabaseKey'); + + // When fetching data, use advanced filtering to only extract data, that you need. + final response = await client + .from('cities') + .select('name,country_id') + .lt('country_id', 100) + .limit(10) + .execute(); +} +``` + + + + + + +You can create data easily using [`insert()`](/docs/reference/javascript/insert). + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .insert([ + { name: 'The Shire', country_id: 554 }, + { name: 'Rohan', country_id: 555 }, + ]) +``` + + + + + +```py +data = supabase.table('cities').insert({'name': 'Gotham', 'country_id': 556 }).execute() +# assert if insert response is a success +assert data.get("status_code") in (200, 201) + +# bulk insert +data = supabase.table('cities').insert([ +{'name': 'Gotham', 'country_id': 556 }, +{'name': 'The Shire', 'country_id': 557 } +]).execute() + +``` + + + + + + +```dart +import 'package:supabase/supabase.dart'; + +void main() async { + final client = SupabaseClient('supabaseUrl', 'supabaseKey'); + + // Create data easily, using insert() + final response = await client + .from('cities') + .insert([ + { 'name': 'The Shire', 'country_id': 554 }, + { 'name': 'Rohan', 'country_id': 555 }, + ]) + .execute(); +} +``` + + + + + + +## Realtime Changes + +The Supabase client makes it simple to listen to realtime database changes, using [`subscribe()`](/docs/reference/javascript/subscribe). + + + + + + +```js +const mySubscription = supabase + .from('countries') + .on('*', payload => { + console.log('Change received!', payload) + }) + .subscribe() +``` + + + + + +```py +# Not yet implemented +``` + + + + + + +```dart +import 'package:supabase/supabase.dart'; + +void main() async { + final client = SupabaseClient('supabaseUrl', 'supabaseKey'); + + // Listen to realtime database changes, using subscribe() + final response = await client + .from('countries') + .on(SupabaseEventTypes.all, (payload) { + print('Something happened: ${payload.eventType}'); + }) + .subscribe((String event, {String? errorMsg}) { + print('event: $event error: $errorMsg'); + }); +} +``` + + + + + + +You can even [listen to Row Level changes](/docs/reference/javascript/subscribe#listening-to-row-level-changes). + + + + + + +```js +const mySubscription = supabase + .from('countries:id.eq.200') + .on('UPDATE', handleRecordUpdated) + .subscribe() +``` + + + + + +```py +# Not yet implemented +``` + + + + + + +```dart +import 'package:supabase/supabase.dart'; + +void main() async { + final client = SupabaseClient('supabaseUrl', 'supabaseKey'); + + // You can even listen to Row Level changes + final response = await client + .from('countries:id.eq.200') + .on(SupabaseEventTypes.update, (payload) { + print('Something happened: ${payload.eventType}'); + }) + .subscribe((String event, {String? errorMsg}) { + print('event: $event error: $errorMsg'); + }); +} +``` + + + + + + + +## Next steps + +- View the [Client Docs](/docs/reference/javascript/supabase-client) +- Sign in: [app.supabase.io](https://app.supabase.io) diff --git a/apps/temp-docs/docs/guides/database.mdx b/apps/temp-docs/docs/guides/database.mdx new file mode 100755 index 00000000000..8694b616dc0 --- /dev/null +++ b/apps/temp-docs/docs/guides/database.mdx @@ -0,0 +1,176 @@ +--- +title: 'Database' +description: 'Supabase is built on top of Postgres, an extremely scalable Relational Database.' +--- + +# Database + +Supabase is built on top of Postgres, an extremely scalable Relational Database. + +## Features + +### Table View + +You don't have to be a database expert to start using Supabase. Our table view makes Postgres as easy to use as a spreadsheet. + +![Table view](https://supabase.com/docs/assets/images/table-view-827aa3e2958fda01517f0a47474827b0.png) + +### Relationships + +Dig into the relationships within your data. + + + + +### Clone tables +You can duplicate your tables, just like you would inside a spreadsheet. + + + +### The SQL Editor +Supabase comes with a SQL Editor. You can also save your favorite queries to run later! + + + +### Additional features + +- Supabase extends Postgres with realtime functionality using our [Realtime Server](https://github.com/supabase/realtime). +- Every project is a full Postgres database, with postgres level access. +- Managed backups - Supabase handles all your database [backups](https://supabase.com/docs/guides/database#fn-backups).backups +- Data imports - import directly from a CSV or excel spreadsheet. + +Database backups do NOT include objects stored via the Storage API, as the database only includes metadata about these objects. Restoring an old backup will not restore objects that have been deleted since then. + + +### Extensions +To expand the functionality of your Postgres database, you can use extensions. You can enable Postgres extensions with the click of a button within the Supabase dashboard. + + + +## Tips + +### Realtime + +Supabase provides a realtime engine on top of Postgres, so that you can listen to changes as they happen. Our realtime engine uses the built-in replication functionality of Postgres. + +Realtime server broadcasts database changes to authorized users depending on your Row Level Security (RLS) policies. We recommend that you enable row level security and set row security policies on tables that you add to the publication. However, you may choose to disable RLS on a table and have changes broadcast to all connected clients. + +You can manage the realtime system, simply by [updating](https://supabase.com/docs/guides/database/replication) the `supabase_realtime` publication. + +For example to enable realtime only for individual tables: + +```sql +begin; + -- remove the realtime publication + drop publication if exists supabase_realtime; + + -- re-create the publication but don't enable it for any tables + create publication supabase_realtime; +commit; + +-- add a table to the publication +alter publication supabase_realtime add table products; + +-- add other tables to the publication +alter publication supabase_realtime add table posts; +``` +By default only "new" values are sent, but if you want to receive the old record (previous values) whenever you update or delete a record, you can update the replica identity of your tables, setting it to `full`: + +```sql +alter table your_table replica identity full; +``` + + +### Migrating between projects# + +If you have an existing Supabase Project and you want to migrate it into a new (fresh) Project, you can simply follow these steps: + +**Before you begin** + +- Make sure Realtime is disabled. This will improve the performance of inserts on your new database. +- Make sure you have psql installed on your computer so that you can run pg_dump. + +**Migrate the database** +First we want to grab the database structure only: +```bash +pg_dump \ +-h db.PROJECT_REF.supabase.co \ +-U postgres \ +--clean \ +--schema-only \ +> supabase_schema.sql +``` + +This command creates a file on your computer called `supabase_schema.sql`. + +After creating a new Supabase project we can use it to restore the database structure: + +```bash +psql \ +-h db.NEW_PROJECT_REF.supabase.co \ +-U postgres \ +< supabase_schema.sql +``` +You may see some errors - the restore will attempt to drop any tables if they are present, and if they aren't present then an error will be displayed. These errors are informative only and nothing to worry about. + + +**(Optionally) Migrate the data** + +We can migrate everything in our database, however we don't want to migrate the data in our storage schema because the files exist outside of the database. For now, we can just get all the data inside the public and auth schemas: + +```bash +pg_dump \ +-h db.PROJECT_REF.supabase.co \ +-U postgres \ +--data-only \ +-n public \ +-n auth \ +> supabase_data.sql +``` +This command creates a file on your computer called supabase_data.sql. We can use this file to restore the data in our new database: +```bash +psql \ +-h db.NEW_PROJECT_REF.supabase.co \ +-U postgres \ +< supabase_data.sql +``` + +### Resetting your project password + +When you create a new project in Supabase we ask for a password. You can use this password to connect directly to your Postgres database. + +If you forget your password, you can reset it from the Dashboard SQL editor: + +For example: + +```sql +alter user postgres +with password 'new_password'; +``` + +Read more in [Database Configuration](https://supabase.com/docs/guides/database/managing-passwords). + +###Changing the timezone of your server. + + +Your database is initialized with the UTC timezone. We recommend keeping it this way, as it is helpful for time calculations. If, however, you want to update the timezone, you can do so using any of the [database timezones](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones). + +For example: + +```sql +alter database postgres set timezone to 'America/New_York'; +``` +Read more in [Database Configuration](https://supabase.com/docs/guides/database/managing-timezones). + +## Next steps +- Read more about [Postgres](https://supabase.com/docs/postgres/server/about) +- Sign in: [app.supabase.io](https://app.supabase.io/) + diff --git a/apps/temp-docs/docs/guides/database/arrays.mdx b/apps/temp-docs/docs/guides/database/arrays.mdx new file mode 100644 index 00000000000..dc83d8b48e4 --- /dev/null +++ b/apps/temp-docs/docs/guides/database/arrays.mdx @@ -0,0 +1,185 @@ +--- +id: arrays +title: 'Working With Arrays' +description: How to use arrays in PostgreSQL and the Supabase API. +--- + +import Tabs from '@theme/Tabs' +import TabsPanel from '@theme/TabsPanel' + +PostgreSQL supports flexible [array types](https://www.postgresql.org/docs/12/arrays.html). +These arrays are also supported in the Supabase dashboard and in the Javascript API. + +## Steps + +### Create a table with an array column + +Create a test table with a text array (an array of strings): + + + + + +```bash +1. Got the Table Editor +2. Create a New Table +3. Create a new table named `arraytest` and save the table + - New Column + - Name the new column `textarray` + - Make it type `text` + - Check the box labelled `Define as array` + - Save the new column +``` + + + + + +```sql +CREATE TABLE arraytest (id integer NOT NULL, textarray text ARRAY); +``` + + + + +### Insert a record with an array value + + + + + +```bash +- Table Editor +- Select `arraytest` +- Insert Row + - In the `textarray` field input, paste: + - `["Harry", "Larry", "Moe"]` + - Save the new row +``` + + + + + +```sql +INSERT INTO arraytest (id, textarray) VALUES (1, ARRAY['Harry', 'Larry', 'Moe']); +``` + + + + +To insert a record from the Javascript client: + +```js +const { data, error } = await supabase + .from('arraytest') + .insert([{ id: 2, textarray: ['one', 'two', 'three', 'four'] }]) +``` + + + + + +### View the results + + + + + +```bash +- Table Editor +- Select `arraytest` +``` + +Your first array data! + +| id | textarray | +| --- | ----------------------- | +| 1 | ["Harry","Larry","Moe"] | + + + + +```sql +SELECT * FROM arraytest; +``` + +Your first array data! + +| id | textarray | +| --- | ----------------------- | +| 1 | ["Harry","Larry","Moe"] | + + + + +### Query Array Data + +To query an array, PostgreSQL uses 1-based arrays, so be careful, since you're probably used to 0-based arrays in Javascript. + + + + + +To select the first item from the array and get the total length of the array: + +```js +SELECT textarray[1], array_length(textarray, 1) FROM arraytest; +``` + +returns: + +| textarray | array_length | +| --------- | ------------ | +| Harry | 3 | + + + + +This returns the entire array field: + +```js +const { data, error } = await supabase.from('arraytest').select('textarray[]') +console.log(JSON.stringify(data, null, 2)) +``` + +returns: + +```js +;[ + { + textarray: ['Harry', 'Larry', 'Moe'], + }, +] +``` + + + + + +## Resources + +- [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) diff --git a/apps/temp-docs/docs/guides/database/connecting/connecting-to-postgres.mdx b/apps/temp-docs/docs/guides/database/connecting/connecting-to-postgres.mdx new file mode 100644 index 00000000000..b7fa505608e --- /dev/null +++ b/apps/temp-docs/docs/guides/database/connecting/connecting-to-postgres.mdx @@ -0,0 +1,37 @@ +--- +id: connecting-to-postgres +title: "Overview" +description: There are various ways to connect to your Postgres database. +--- + +# Overview + +Supabase provides several options for connection to your Postgres database: + +- HTTP connections using the API. +- Direct connections using Postgres' standard connection system. +- Connection pooling using PgBouncer. + +## HTTP + +Supabase provides an auto-updating API. This is the easiest way to get started if you are managing data (fetching, inserting, updating). However you cannot manage the database schema +via the API (for security reasons). To do that you can either use the dashboard we provide or connect directly to your database. + +## Direct vs Connection Pooling + +A "direct connection" is when a connection is made to the database using Postgres' native connection implementation. + +A "connection pool" is a system (external to Postgres) +which manage connections, rather than Postgres' native system. + +Why would you use a connection pool? Primarily because the way that Postgres handles connections isn't very scalable for a large number of _temporary_ connections. +You can use these simple questions to determine which connection method to use: + +- Are you connecting to a database and _maintaining_ a connection? If yes, use a direct connection. +- Are you connecting to your database and then _disconnecting_ immediately (e.g. a serverless environment)? If yes, use a connection pool. + +## Resources + +- [Direct Connections](/docs/guides/database/connecting/direct-connections). +- [Connection Pooling](/docs/guides/database/connecting/connection-pooling). + diff --git a/apps/temp-docs/docs/guides/database/connecting/connection-pooling.mdx b/apps/temp-docs/docs/guides/database/connecting/connection-pooling.mdx new file mode 100644 index 00000000000..7b67315f0a5 --- /dev/null +++ b/apps/temp-docs/docs/guides/database/connecting/connection-pooling.mdx @@ -0,0 +1,67 @@ +--- +id: connection-pooling +title: "Connection Pooling" +description: Connecting to your Supabase database using PgBouncer. +--- + +Connection pools are useful for managing a large number of _temporary_ connections. + +## How connection pooling works + +A "connection pool" is a system (external to Postgres) which manage connections, rather than PostgreSQL's native system. Supabase uses [PgBouncer](https://www.pgbouncer.org/) for connection pooling. + +When a client makes a request, PgBouncer "allocates" and available connection to the client. +When the client transaction or session is completed the connection is returned to the pool and is free to be used by another client. + + +![Connection pooling](/docs/img/guides/connection-pool.png) + + +## Pool modes + +Pool Mode determines how PgBouncer handles a connection. + +### Session + +When a new client connects, a connection is assigned to the client until it disconnects. Afterward, the connection is returned back to the pool. + +All PostgreSQL features can be used with this option. + +### Transaction + +This is the suggested option for serverless functions. A connection is only assigned to the client for the duration of a transaction. Two consecutive transactions from the same client +could be executed over two different connections. + +Some session-based PostgreSQL features such as prepared statements are not available with this option. +A comprehensive list of incompatible features can be found [here](https://www.pgbouncer.org/features.html). + +### Statement + +This is the most granular option. Connections are returned to the pool after every statement. Transactions with multiple statements are not allowed. This is best used when `AUTOCOMMIT` is in use. + +## Finding your connection string + + + + +```sh +1. Go to the "Database" section. +2. Click "Connection Pooling". +3. Find your Connection Info and Connection String. +``` + + + + + + + + +## Resources + +- [Direct Connections](/docs/guides/database/connecting/direct-connections). +- [Connection Pooling](/docs/guides/database/connecting/connection-pooling). diff --git a/apps/temp-docs/docs/guides/database/connecting/direct-connections.mdx b/apps/temp-docs/docs/guides/database/connecting/direct-connections.mdx new file mode 100644 index 00000000000..55916996d6a --- /dev/null +++ b/apps/temp-docs/docs/guides/database/connecting/direct-connections.mdx @@ -0,0 +1,36 @@ +--- +id: direct-connections +title: "Direct Connections" +description: Connecting to your Supabase database. +--- + +# Direct Connections + +Every Supabase project provides a full Postgres database. You can connect to the database using any tool which supports Postgres. + +## Finding your connection string + + + + +```sh +1. Go to the "Settings" section. +2. Click "Database". +3. Find your Connection Info and Connection String. +``` + + + + + + +## Resources + +- [Direct Connections](/docs/guides/database/connecting/direct-connections). +- [Connection Pooling](/docs/guides/database/connecting/connection-pooling). + + diff --git a/apps/temp-docs/docs/guides/database/extensions.mdx b/apps/temp-docs/docs/guides/database/extensions.mdx new file mode 100644 index 00000000000..d8c7fe258c2 --- /dev/null +++ b/apps/temp-docs/docs/guides/database/extensions.mdx @@ -0,0 +1,66 @@ +--- +id: extensions +title: Overview +description: Using Postgres extensions. +--- + +import ExtensionsComponent from '@site/src/components/Extensions' +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Extensions are exactly as they sound - they "extend" the database with functionality which isn't part of the Postgres core. +Supabase has pre-installed some of the most useful open source extensions. + + +### Enable and disable extensions + + + + + + +```sh +1. Go to the Database page +2. Click on "Extensions" in the sidebar +3. Find the extension you would like to enable/disable +4. Click the toggle. +``` + + + + + + + + + +```sql + +-- Example: enable the "pgtap" extension +create extension pgtap; + +-- Example: disable the "pgtap" extension +drop extension pgtap; + +``` + +Even though the SQL code is `create extension`, this is the equivalent of "enabling the extension". +To disable an extension you can call `drop extension`. + + + + + + +### Full list of extensions + +Supabase is pre-configured with over 50 extensions. You can also install your own SQL extensions directly into the database through our SQL editor. + + diff --git a/apps/temp-docs/docs/guides/database/extensions/http.mdx b/apps/temp-docs/docs/guides/database/extensions/http.mdx new file mode 100644 index 00000000000..7ab2d07aefe --- /dev/null +++ b/apps/temp-docs/docs/guides/database/extensions/http.mdx @@ -0,0 +1,113 @@ +--- +id: http +title: "http: RESTful Client" +description: An HTTP Client for PostgreSQL Functions. +--- + +# http: RESTful Client + +The `http` extension allows you to call RESTful endpoints within Postgres. + +## Overview + +Let's cover some basic concepts: + +- REST: stands for REpresentational State Transfer. It's simply a way to request data from external services. +- RESTful APIs are servers which accept HTTP "calls". The calls are typically: + - `GET` − Read only access to a resource. + - `POST` − Creates a new resource. + - `DELETE` − Removes a resource. + - `PUT` − Updates an existing resource or creates a new resource. + +You can use the `http` extension to make these network requests from Postgres. + + +## Usage + + +### Enabling + + + + +```sh +1. Go to the Database page. +2. Click on "Extensions" in the sidebar. +3. Search for "http". +4. Click the toggle. +``` + + + + + + +```sql + +-- Example: enable the "http" extension +create extension http with schema extensions; + +-- Example: disable the "http" extension +drop extension if exists http; + +``` + +Even though the SQL code is `create extension`, this is the equivalent of "enabling the extension". +To disable an extension you can call `drop extension`. + +It's good practice to create the extension within a separate schema (like `extensions`) to keep your database clean. + + + + + +### Available functions + +While the main usage is simply `http('http_request')`, there are 5 wrapper functions for specific functionality: + +- `http_get()` +- `http_post()` +- `http_put()` +- `http_delete()` +- `http_head()` + +### Returned values + +A successful call to a web URL from the `http` extension returns a record with the following fields: + +- `status`: integer +- `content_type`: character varying +- `headers`: http_header[] +- `content`: character varying. Typically you would want to cast this to `jsonb` using the format `content::jsonb` + +## Examples + +### Simple `GET` example + +```sql +select + "status", "content"::jsonb +from + http_get('https://jsonplaceholder.typicode.com/todos/1'); +``` + + +### Simple `POST` example + +```sql +select + "status", "content"::jsonb +from + http_post( + 'https://jsonplaceholder.typicode.com/posts', + '{ "title": "foo", "body": "bar", "userId": 1 }', + 'application/json' + ); +``` + + +## Resources + +- Official [`http` Github Repository](https://github.com/pramsey/pgsql-http). diff --git a/apps/temp-docs/docs/guides/database/extensions/pgtap.mdx b/apps/temp-docs/docs/guides/database/extensions/pgtap.mdx new file mode 100644 index 00000000000..3ba365416cf --- /dev/null +++ b/apps/temp-docs/docs/guides/database/extensions/pgtap.mdx @@ -0,0 +1,129 @@ +--- +id: pgtap +title: "pgTAP: Unit Testing" +description: Unit testing in PostgreSQL. +--- + +# pgTAP: Unit Testing + +`pgTAP` is a unit testing extension for PostgreSQL. + +## Overview + +Let's cover some basic concepts: + +- Unit tests: allow you to test small parts of a system (like a database table!). +- TAP: stands for [Test Anything Protocol](http://testanything.org/). It is an framework which aims to simplify the error reporting during testing. + + + +## Usage + + +### Enabling + + + + +```sh +1. Go to the Database page. +2. Click on "Extensions" in the sidebar. +3. Search for "pgtap". +4. Click the toggle. +``` + + + + + + +```sql + +-- Enable the "pgtap" extension +create extension pgtap with schema extensions; + +-- Disable the "pgtap" extension +drop extension if exists pgtap; + +``` + +Even though the SQL code is `create extension`, this is the equivalent of "enabling the extension". +To disable an extension you can call `drop extension`. + +It's good practice to create the extension within a separate schema (like `extensions`) to keep your database clean. + + + + + +### Managing tests + +It's a good practice to keep all your tests in a separate schema. + +```sql +create schema tests; +``` + +### Creating a test + + +@TODO + +- Create a plan +- We should come up with a recommendation on how to run the tests. Via a function? External scripts? +- Eventually this can be done via our CLI + + +### Running a test + +@TODO + + +## Examples + +Let's look at a few different tests which could be helpful in your project. + + +### Testing tables + + +```sql +begin; +select plan( 1 ); + +select has_table( 'profiles' ); + +select * from finish(); +rollback; +``` + +API: + +- [`hasTable()`](https://pgtap.org/documentation.html#has_table) + + +### Testing columns + +```sql +begin; +select plan( 1 ); + +select has_column( 'profiles', 'id' ); +select col_is_pk( 'profiles', 'id' ); + +select * from finish(); +rollback; +``` + +API: + +- [`has_column()`](https://pgtap.org/documentation.html#has_column) +- [`col_is_pk()`](https://pgtap.org/documentation.html#col_is_pk) + +## Resources + +- Official [`pgTAP` documentation](https://pgtap.org/). diff --git a/apps/temp-docs/docs/guides/database/extensions/plv8.mdx b/apps/temp-docs/docs/guides/database/extensions/plv8.mdx new file mode 100644 index 00000000000..6ffaf6de5c6 --- /dev/null +++ b/apps/temp-docs/docs/guides/database/extensions/plv8.mdx @@ -0,0 +1,150 @@ +--- +id: plv8 +title: "plv8: Javascript Language" +description: Javascript language for PostgreSQL. +--- + +# plv8: Javascript Language + +The `plv8` extension allows you use Javascript within Postgres. + +## Overview + +While Postgres natively runs SQL, it can also run other "procedural languages". +`plv8` allows you to run Javascript code - specifically any code that runs on the [V8 Javascript engine](https://v8.dev). + +It can be used for database functions, triggers, queries and more. + +## Usage + + +### Enabling + + + + + +```sh +1. Go to the Database page. +2. Click on "Extensions" in the sidebar. +3. Search for "plv8". +4. Click the toggle. +``` + + + + +```sql + +-- Example: enable the "plv8" extension +create extension plv8; + +-- Example: disable the "plv8" extension +drop extension if exists plv8; + +``` + +Even though the SQL code is `create extension`, this is the equivalent of "enabling the extension". +To disable an extension you can call `drop extension`. + +Procedural languages are automatically installed within `pg_catalog`, so you don't need to specify a schema. + + + + +### Creating `plv8` functions + +Functions written in `plv8` are written just like any other PostgreSQL functions, only +with the `language` identifier set to `plv8`. + +```sql +create or replace function function_name() +returns void as $$ + // V8 Javascript + // code + // here +$$ language plv8; +``` + +You can call `plv8` functions like any other Postgres function: + + + + + + + +```sql +select function_name(); +``` + + + + +```js + +const { data, error } = supabase.rpc('function_name') + +``` + + + + +## Examples + +### Scalar Functions + +A [scalar function](https://plv8.github.io/#scalar-function-calls) is anything that takes in some user input and returns a single result. + +```sql +create or replace function hello_world(name text) +returns text as $$ + + let output = `Hello, ${name}!`; + return output; + +$$ language plv8; +``` + +### Executing SQL + +You can execute SQL within `plv8` code using the [`plv8.execute` function](https://plv8.github.io/#plv8-execute). + +```sql +create or replace function update_user(id bigint, first_name text) +returns smallint as $$ + + var num_affected = plv8.execute( + 'update profiles set first_name = $1 where id = $2', + [first_name, id] + ); + + return num_affected; +$$ language plv8; +``` + +### Set-returning Functions + +A [set-returning function](https://plv8.github.io/#set-returning-function-calls) is anything that returns a full set of results - for example, rows in a table. + +```sql +create or replace function get_messages() +returns setof messages as $$ + + var json_result = plv8.execute( + 'select * from messages' + ); + + return json_result; +$$ language plv8; +``` + + +## Resources + +- Official [`plv8` documentation](https://plv8.github.io/). +- [plv8 Github Repository](https://github.com/plv8/plv8). diff --git a/apps/temp-docs/docs/guides/database/extensions/uuid-ossp.mdx b/apps/temp-docs/docs/guides/database/extensions/uuid-ossp.mdx new file mode 100644 index 00000000000..790edf961db --- /dev/null +++ b/apps/temp-docs/docs/guides/database/extensions/uuid-ossp.mdx @@ -0,0 +1,98 @@ +--- +id: uuid-ossp +title: "uuid-ossp: Unique Identifiers" +description: A UUID generator for PostgreSQL. +--- + +# uuid-ossp: Unique Identifiers + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +The `uuid-ossp` extension can be used to generate a `UUID`. + + +## Overview + +A `UUID` is a "Universally Unique Identifer" and it is, for practical purposes, unique. +This makes them particularly well suited as Primary Keys. It is occasionally referred to as a `GUID`, which stands for "Globally Unique Identifer". + +## Usage + +### Enabling + + + + +```sh +1. Go to the Database page. +2. Click on "Extensions" in the sidebar. +3. Search for "uuid-ossp". +4. Click the toggle. +``` + + + + +```sql + +-- Example: enable the "uuid-ossp" extension +create extension "uuid-ossp" with schema extensions; + +-- Example: disable the "uuid-ossp" extension +drop extension if exists "uuid-ossp"; + +``` + +Even though the SQL code is `create extension`, this is the equivalent of "enabling the extension". +To disable an extension you can call `drop extension`. + +It's good practice to create the extension within a separate schema (like `extensions`) to keep your database clean. + + + + + +### The `uuid` type + +Once the extension is enabled, you now have access to a `uuid` type. + +### `uuid_generate_v1()` + +Creates a UUID value based on the combination of computer’s MAC address, current timestamp, and a random value. + +### `uuid_generate_v4()` + +Creates UUID values based solely on random numbers. + +## Examples + +### Within a query + +```sql +select uuid_generate_v4(); +``` + +### As a Primary Key + +Automatically create a unique, random ID in a table: + +```sql +create table contacts ( + id uuid default uuid_generate_v4(), + first_name text, + last_name text, + + primary key (id) +); +``` + + +## Resources + +- [The Basics Of PostgreSQL `UUID` Data Type](https://www.postgresqltutorial.com/postgresql-uuid/). diff --git a/apps/temp-docs/docs/guides/database/full-text-search.mdx b/apps/temp-docs/docs/guides/database/full-text-search.mdx new file mode 100644 index 00000000000..609eb3ad7b7 --- /dev/null +++ b/apps/temp-docs/docs/guides/database/full-text-search.mdx @@ -0,0 +1,630 @@ +--- +id: full-text-search +title: "Full Text Search" +description: How to use full text search in PostgreSQL. +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + + +Postgres has built-in functions to handle `Full Text Search` queries. This is like a "search engine" within Postgres. + + +## Preparation + +For this guide we'll use the following example data: + + + + + + +```sql +create table books ( + id serial primary key, + title text, + author text, + description text +); + +insert into books (title, author, description) +values + ('The Poky Little Puppy','Janette Sebring Lowrey','Puppy is slower than other, bigger animals.'), + ('The Tale of Peter Rabbit','Beatrix Potter','Rabbit eats some vegetables.'), + ('Tootle','Gertrude Crampton','Little toy train has big dreams.'), + ('Green Eggs and Ham','Dr. Seuss','Sam has changing food preferences and eats unusually colored food.'), + ('Harry Potter and the Goblet of Fire','J.K. Rowling','Fourth year of school starts, big drama ensues.'); +``` + + + + +| id | title | author | description | +| ---- | ---- | ---- | ----------- | +| 1 | The Poky Little Puppy | Janette Sebring Lowrey | Puppy is slower than other, bigger animals. | +| 2 | The Tale of Peter Rabbit | Beatrix Potter | Rabbit eats some vegetables. | +| 3 | Tootle | Gertrude Crampton | Little toy train has big dreams. | +| 4 | Green Eggs and Ham | Dr. Seuss | Sam has changing food preferences and eats unusually colored food. | +| 5 | Harry Potter and the Goblet of Fire | J.K. Rowling | Fourth year of school starts, big drama ensues. | + + + + + +## Usage + +The functions we'll cover in this guide are: + +### `to_tsvector()` + +Converts your data into searchable "tokens". `to_tsvector()` stands for "to text search vector". For example: + +```sql +select to_tsvector("green eggs and ham") + +-- Returns 'egg':2 'green':1 'ham':4 +``` + +Collectively these tokens are called a "document" which Postgres can use for comparisons. + +### `to_tsquery()` + +Converts a query string into "tokens" to match. `to_tsquery()` stands for "to text search query". + +This conversion step is important because we will want to "fuzzy match" on keywords. +For example if a user searches for "eggs", and a column has the value "egg", we probably still want to return a match. + + +### Match: `@@` + +The `@@` symbol is the "match" symbol for Full Text Search. It returns any matches between a `to_tsvector` result and a `to_tsquery` result. + +Take the following example: + + + + +```sql +select * +from books +where name = 'Harry'; +``` + + + + +```js +const { data, error } = await supabase + .from('books') + .select() + .eq('name', 'Harry') +``` + + + + + +```dart +final result = await client + .from('books') + .select() + .eq('name', 'Harry') + .execute(); +``` + + + + + +The equality symbol above (`=`) is very "strict" on what it matches. In a full text search context, we might want to find all "Harry Potter" books and so we can rewrite the +example above: + + + + +```sql +select * +from books +where to_tsvector(name) @@ to_tsquery('Harry'); +``` + + + + +```js +const { data, error } = await supabase + .from('books') + .select() + .textSearch('name', `'Harry'`) +``` + + + + +```dart +final result = await client + .from('books') + .select() + .textSearch('name', "'Harry'") + .execute(); +``` + + + + +## Basic Full Text Queries + +### Search a single column + +To find all `books` where the `description` contain the word `big`: + + + + +```sql +select + * +from + books +where + to_tsvector(description) + @@ to_tsquery('big'); +``` + + + + +```js +const { data, error } = await supabase + .from('books') + .select() + .textSearch('description', `'big'`) +``` + + + + +```dart +final result = await client + .from('books') + .select() + .textSearch('description', "'big'") + .execute(); +``` + + + + +| id | title | author | description | +| -- | ----------------------------------- | ----------------- | ----------------------------------------------- | +| 3 | Tootle | Gertrude Crampton | Little toy train has big dreams. | +| 5 | Harry Potter and the Goblet of Fire | J.K. Rowling | Fourth year of school starts, big drama ensues. | + + + + +### Search multiple columns + +To find all `books` where `description` or `title` contain the word `little`: + + + + +```sql +select + * +from + books +where + to_tsvector(description || ' ' || title) -- concat columns, but be sure to include a space to separate them! + @@ to_tsquery('little'); +``` + + + + +| id | title | author | description | +| -- | --------------------- | ---------------------- | ------------------------------------------- | +| 1 | The Poky Little Puppy | Janette Sebring Lowrey | Puppy is slower than other, bigger animals. | +| 3 | Tootle | Gertrude Crampton | Little toy train has big dreams. | + + + + +### Match all search words + +To find all `books` where `description` contains BOTH of the words `little` and `big`, we can use the `&` symbol: + + + + +```sql +select + * +from + books +where + to_tsvector(description) + @@ to_tsquery('little & big'); -- use & for AND in the search query +``` + + + + +```js +const { data, error } = await supabase + .from('books') + .select() + .textSearch('description', `'little' & 'big'`) +``` + + + + +```dart +final result = await client + .from('books') + .select() + .textSearch('description', "'little' & 'big'") + .execute(); +``` + + + + +| id | title | author | description | +| -- | ------ | ----------------- | -------------------------------- | +| 3 | Tootle | Gertrude Crampton | Little toy train has big dreams. | + + + + +### Match any search words + +To find all `books` where `description` contain ANY of the words `little` or `big`, use the `|` symbol: + + + + +```sql +select + * +from + books +where + to_tsvector(description) + @@ to_tsquery('little | big'); -- use | for OR in the search query +``` + + + + +```js +const { data, error } = await supabase + .from('books') + .select() + .textSearch('description', `'little' | 'big'`) +``` + + + + +```dart +final result = await client + .from('books') + .select() + .textSearch('description', "'little' | 'big'") + .execute(); +``` + + + + +| id | title | author | description | +| -- | --------------------- | ---------------------- | ------------------------------------------- | +| 1 | The Poky Little Puppy | Janette Sebring Lowrey | Puppy is slower than other, bigger animals. | +| 3 | Tootle | Gertrude Crampton | Little toy train has big dreams. | + + + + +Notice how searching for `big` includes results with the word `bigger` (or `biggest`, etc). + +## Creating Indexes + +Now that we have Full Text Search working, let's create an `index`. This will allow Postgres to "build" the documents pre-emptively so that they +don't need to be created at the time we execute the query. This will make our queries much faster. + +### Searchable columns + +Let's create a new column `fts` inside the `books` table to store the searchable index of the `title` and `description` columns. + +We can use a special feature of Postgres called +[Generated Columns](https://www.postgresql.org/docs/current/ddl-generated-columns.html) +to ensure that the index is updated any time the values in the `title` and `description` columns change. + + + + +```sql +alter table + books +add column + fts tsvector generated always as (to_tsvector('english', description || ' ' || title)) stored; + +create index books_fts on books using gin (fts); -- generate the index + +select id, fts +from books; +``` + + + + +| id | fts | +| -- | --------------------------------------------------------------------------------------------------------------- | +| 1 | 'anim':7 'bigger':6 'littl':10 'poki':9 'puppi':1,11 'slower':3 | +| 2 | 'eat':2 'peter':8 'rabbit':1,9 'tale':6 'veget':4 | +| 3 | 'big':5 'dream':6 'littl':1 'tootl':7 'toy':2 'train':3 | +| 4 | 'chang':3 'color':9 'eat':7 'egg':12 'food':4,10 'green':11 'ham':14 'prefer':5 'sam':1 'unus':8 | +| 5 | 'big':6 'drama':7 'ensu':8 'fire':15 'fourth':1 'goblet':13 'harri':9 'potter':10 'school':4 'start':5 'year':2 | + + + + +### Search using the new column + +Now that we've created and populated our index, we can search it using the same techniques as before: + + + + +```sql +select + * +from + books +where + fts @@ to_tsquery('little & big'); +``` + + + + +```js +const { data, error } = await supabase + .from('books') + .select() + .textSearch('fts', `'little' & 'big'`) +``` + + + + +```dart +final result = await client + .from('books') + .select() + .textSearch('fts', "'little' & 'big'") + .execute(); +``` + + + + +| id | title | author | description | fts | +| -- | ------ | ----------------- | -------------------------------- | ------------------------------------------------------- | +| 3 | Tootle | Gertrude Crampton | Little toy train has big dreams. | 'big':5 'dream':6 'littl':1 'tootl':7 'toy':2 'train':3 | + + + + +## Query Operators + +Visit [PostgreSQL: Text Search Functions and Operators](https://www.postgresql.org/docs/current/functions-textsearch.html) +to learn about additional query operators you can use to do more advanced `full text queries`, such as: + +### Proximity: `<->` + +The proximity symbol is useful for searching for terms that are a certain "distance" apart. +For example, to find the phrase `big dreams`, where the a match for "big" is followed immediately by a match for "dreams": + + + + + +```sql +select + * +from + books +where + to_tsvector(description) @@ to_tsquery('big <-> dreams'); +``` + + + + +```js +const { data, error } = await supabase + .from('books') + .select() + .textSearch('description', `'big' <-> 'dreams'`) +``` + + + + +```dart +final result = await client + .from('books') + .select() + .textSearch('description', "'big' <-> 'dreams'") + .execute(); +``` + + + + + +We can also use the `<->` to find words within a certain distance of eachother. For example to find `year` and `school` within 2 words of each other: + + + + +```sql +select + * +from + books +where + to_tsvector(description) @@ to_tsquery('year <2> school'); +``` + + + + +```js +const { data, error } = await supabase + .from('books') + .select() + .textSearch('description', `'year' <2> 'school'`) +``` + + + + +```dart +final result = await client + .from('books') + .select() + .textSearch('description', "'year' <2> 'school'") + .execute(); +``` + + + + + +### Negation: `!` + +The negation symbol can be used to find phrases which _don't_ contain a search term. +For example, to find records that have the word `big` but not `little`: + + + + +```sql +select + * +from + books +where + to_tsvector(description) @@ to_tsquery('big & !little'); +``` + + + + +```js +const { data, error } = await supabase + .from('books') + .select() + .textSearch('description', `'big' & !'little'`) +``` + + + + +```dart +final result = await client + .from('books') + .select() + .textSearch('description', "'big' & !'little'") + .execute(); +``` + + + + + +## Resources + +* [PostgreSQL: Text Search Functions and Operators](https://www.postgresql.org/docs/12/functions-textsearch.html) + + + diff --git a/apps/temp-docs/docs/guides/database/functions.mdx b/apps/temp-docs/docs/guides/database/functions.mdx new file mode 100644 index 00000000000..9065663cb7b --- /dev/null +++ b/apps/temp-docs/docs/guides/database/functions.mdx @@ -0,0 +1,303 @@ +--- +id: functions +title: Functions +description: Creating and using Postgres functions. +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + + +Postgres has built-in support for [SQL functions](https://www.postgresql.org/docs/current/sql-createfunction.html). +These functions live inside your database, and they can be [used with the API](/docs/reference/javascript/rpc). + +## Quick demo + + + +## Creating Functions + +Supabase provides several options for creating database functions. You can use the Dashboard or create them directly using SQL. +We provide a SQL editor within the Dashboard, or you can [connect](/docs/guides/database/connecting/connecting-to-postgres) to your database +and run the SQL queries yourself. + + +1. Go to the "SQL editor" section. +2. Click "New Query". +3. Enter the SQL to create or replace your Database function. +4. Click "Run" or cmd+enter (ctrl+enter). + +## Examples + +### Data set + +For this guide we'll use the following example data: + + + + + + +```sql +create table planets ( + id serial primary key, + name text +); + +insert into planets (id, name) +values + (1, 'Tattoine'), + (2, 'Alderaan'), + (3, 'Kashyyyk'); + +create table people ( + id serial primary key, + name text, + planet_id bigint references planets +); + +insert into people (id, name, planet_id) +values + (1, 'Anakin Skywalker', 1), + (2, 'Luke Skywalker', 1), + (3, 'Princess Leia', 2), + (4, 'Chewbacca', 3); +``` + + + + +

    Planets

    + +| id | name | +| ---- | ---- | +| 1 | Tattoine | +| 2 | Alderaan | +| 3 | Kashyyyk | + +

    People

    + +| id | name | planet_id | +| ---- | ---- | ---- | +| 1 | Anakin Skywalker | 1 | +| 2 | Luke Skywalker | 1 | +| 3 | Princess Leia | 2 | +| 4 | Chewbacca | 3 | + +
    + +
    + +### Basic function + +A basic example which returns a string "hello world". + +```sql +create or replace function hello_world() -- 1 +returns text -- 2 +language sql -- 3 +as $$ -- 4 + select 'hello world'; -- 5 +$$; --6 + +``` + +
    +Show/Hide Details + +At it's most basic a function has the following parts: + +1. `create or replace function hello_world()`: The function declaration, where `hello_world` is the name of the function. You can use either `create` when creating a new function or `replace` when replacing an existing function. Or you can use `create or replace` together to handle either. +2. `returns text`: The type of data that the function returns. If it returns nothing, you can `returns void`. +3. `language sql`: The language used inside the function body. This can also be a procedural language: `plpgsql`, `plv8`, `plpython`, etc. +4. `as $$`: The function wrapper. Anything enclosed inside the `$$` symbols will be part of the function body. +5. `select 'hello world';`: A simple function body. The final `select` statement inside a function body will be returned if there are no statements following it. +6. `$$;`: The closing symbols of the funciton wrapper. + +
    + +#### Execute + + + + + +```sql +select hello_world(); +``` + + + + +```js +const { data, error } = supabase + .rpc('hello_world') +``` + +Reference: [rpc()](/docs/reference/javascript/rpc) + + + + +```dart +final res = await supabase + .rpc('hello_world') + .execute(); +``` + +Reference: [rpc()](/docs/reference/dart/rpc) + + + + + + +### Return table sets + +A basic example which return all the `planets` in our example data set. + +```sql +create or replace function get_planets() +returns setof planets +language sql +as $$ + select * from planets; +$$; +``` + +#### Execute + +Because this function returns a table set, we can also apply filters and selectors. For example, if we only wanted the first planet: + + + + + +```sql +select * +from get_planets() +where id = 1; +``` + + + + +```js +const { data, error } = supabase + .rpc('get_planets') + .eq('id', 1) +``` + +Reference: [rpc()](/docs/reference/javascript/rpc) + + + + +```dart +final res = await supabase + .rpc('get_planets') + .eq('id', 1) + .execute(); +``` + +Reference: [rpc()](/docs/reference/dart/rpc) + + + + + + +### With parameters + +A basic example which will insert a new planet into the `planets` and return the new ID. Note that this time we're using the `plpgsql` language. + +```sql +create or replace function add_planet(name text) +returns bigint +language plpgsql +as $$ +declare + new_row bigint; +begin + insert into planets(name) + values (add_planet.name) + returning id into new_row; + + return new_row; +end; +$$; +``` + +#### Execute + +Because this function returns a table set, we can also apply filters and selectors. For example, if we only wanted the `name` of the first planet: + + + + + +```sql +select * from add_planet('Jakku'); +``` + + + + +```js +const { data, error } = supabase + .rpc('add_planet', { name: 'Jakku' }) +``` + +Reference: [rpc()](/docs/reference/javascript/rpc) + + + + +```dart +final res = await supabase + .rpc('add_planet', params: { 'name': 'Jakku' }) + .execute(); +``` + +Reference: [rpc()](/docs/reference/dart/rpc) + + + + + + +## Resources + +- PostgreSQL Official Docs: [Chapter 9. Functions and Operators](https://www.postgresql.org/docs/current/functions.html) +- PostgreSQL Reference: [CREATE FUNCTION](https://www.postgresql.org/docs/9.1/sql-createfunction.html) diff --git a/apps/temp-docs/docs/guides/database/introduction.mdx b/apps/temp-docs/docs/guides/database/introduction.mdx new file mode 100644 index 00000000000..697a1afa767 --- /dev/null +++ b/apps/temp-docs/docs/guides/database/introduction.mdx @@ -0,0 +1,37 @@ +--- +id: introduction +title: "Introduction" +slug: introduction +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Every Supabase project comes with a full Postgres database, a free and open source +database which is considered one of the world's most stable and advanced databases. + + +## Postgres or PostgreSQL? + + +The database was derived from the POSTGRES Project, a package written at the University of California at Berkeley in 1986. +This package included a query language called "PostQUEL". + +In 1994, Postgres95 was built on top of POSTGRES code, adding an SQL language interpreter as a replacement for PostQUEL. +Eventually, Postgres95 was renamed to PostgreSQL to reflect the SQL query capability. + +After this, many people referred to it as Postgres since it's less prone to confusion. Supabase is all about +simplicity, so we also refer to it as Postgres. + + \ No newline at end of file diff --git a/apps/temp-docs/docs/guides/database/json.mdx b/apps/temp-docs/docs/guides/database/json.mdx new file mode 100644 index 00000000000..ab54768fba9 --- /dev/null +++ b/apps/temp-docs/docs/guides/database/json.mdx @@ -0,0 +1,312 @@ +--- +id: json +title: 'JSON' +description: Using the JSON data type in PostgreSQL. +--- + +import Tabs from '@theme/Tabs' +import TabsPanel from '@theme/TabsPanel' + +PostgreSQL supports [JSON functions and operators](https://www.postgresql.org/docs/current/functions-json.html) which gives flexibility when storing data inside a database column. + +PostgreSQL supports two types of JSON columns: `JSON` and `JSONB`. + +The recommended type is `JSONB` for almost all cases. +When you use the `JSONB` format, the data is parsed when it's put into the database so it's faster when querying and also it can be indexed. + +## Steps + +### Create a table with a JSON column. + + + + +```sql +create table books ( + id serial primary key, + title text, + author text, + metadata jsonb +); +``` + + + + +```sh +Create the table: + +1. Go to the Table Editor +2. Click "New Table" +3. Name the table "books" +4. Include a primary key with the following properties: + - Name: "id" + - Type: "int8" + - Default value: "Automatically generate as indentity" +5. Click "Save" + + +Click "New Column" and 3 new columns with the following properties: + +1. title column: + - Name: "title" + - Type: "text" + +2. author column: + - Name: "author" + - Type: "text" + +3. metadata column: + - Name: "metadata" + - Type: "jsonb" +``` + + + + +### Insert data into the table. + + + + +| id | title | author | metadata | +| --- | ----------------------------------- | ---------------------- | -------------------------------------------------------------------------------------------------------------- | +| 1 | The Poky Little Puppy | Janette Sebring Lowrey | {"ages":[3,6],"price":5.95,"description":"Puppy is slower than other, bigger animals."} | +| 2 | The Tale of Peter Rabbit | Beatrix Potter | {"ages":[2,5],"price":4.49,"description":"Rabbit eats some vegetables."} | +| 3 | Tootle | Gertrude Crampton | {"ages":[2,5],"price":3.99,"description":"Little toy train has big dreams."} | +| 4 | Green Eggs and Ham | Dr. Seuss | {"ages":[4,8],"price":7.49,"description":"Sam has changing food preferences and eats unusually colored food."} | +| 5 | Harry Potter and the Goblet of Fire | J.K. Rowling | {"ages":[10,99],"price":24.95,"description":"Fourth year of school starts, big drama ensues."} | + + + + +```sql +insert into books + (title, author, metadata) +values + ( + 'The Poky Little Puppy', + 'Janette Sebring Lowrey', + '{"description":"Puppy is slower than other, bigger animals.","price":5.95,"ages":[3,6]}' + ), + ( + 'The Tale of Peter Rabbit', + 'Beatrix Potter', + '{"description":"Rabbit eats some vegetables.","price":4.49,"ages":[2,5]}' + ), + ( + 'Tootle', + 'Gertrude Crampton', + '{"description":"Little toy train has big dreams.","price":3.99,"ages":[2,5]}' + ), + ( + 'Green Eggs and Ham', + 'Dr. Seuss', + '{"description":"Sam has changing food preferences and eats unusually colored food.","price":7.49,"ages":[4,8]}' + ), + ( + 'Harry Potter and the Goblet of Fire', + 'J.K. Rowling', + '{"description":"Fourth year of school starts, big drama ensues.","price":24.95,"ages":[10,99]}' + ); +``` + + + + +```bash +- click `Table Editor` +- click `books` +- click `+ Insert Row` + - `title`: `The Poky Little Puppy` + - `author`: 'Janette Sebring Lowrey' + - `metadata`: {"description":"Puppy is slower than other, bigger animals.","price":5.95,"ages":[3,6]} + - click `Save` +- click `+ Insert Row` + - `title`: `The Tale of Peter Rabbit` + - `author`: 'Beatrix Potter' + - `metadata`: {"ages":[2,5],"price":4.49,"description":"Rabbit eats some vegetables."} + - click `Save` +- click `+ Insert Row` + - `title`: `Tootle` + - `author`: 'Gertrude Crampton' + - `metadata`: {"ages":[2,5],"price":3.99,"description":"Little toy train has big dreams."} + - click `Save` +- click `+ Insert Row` + - `title`: `Green Eggs and Ham` + - `author`: 'Dr. Seuss' + - `metadata`: {"ages":[4,8],"price":7.49,"description":"Sam has changing food preferences and eats unusually colored food."} + - click `Save` +- click `+ Insert Row` + - `title`: `Harry Potter and the Goblet of Fire` + - `author`: 'J.K. Rowling' + - `metadata`: {"ages":[10,99],"price":24.95,"description":"Fourth year of school starts, big drama ensues."} + - click `Save` +``` + + + + +```js +const { data, error } = await supabase.from('books').insert([ + { + title: 'The Poky Little Puppy', + author: 'Janette Sebring Lowrey', + metadata: { + description: 'Puppy is slower than other, bigger animals.', + price: 5.95, + ages: [3, 6], + }, + }, + { + title: 'The Tale of Peter Rabbit', + author: 'Beatrix Potter', + metadata: { description: 'Rabbit eats some vegetables.', price: 4.49, ages: [2, 5] }, + }, + { + title: 'Tootle', + author: 'Gertrude Crampton', + metadata: { description: 'Little toy train has big dreams.', price: 3.99, ages: [2, 5] }, + }, + { + title: 'Green Eggs and Ham', + author: 'Dr. Seuss', + metadata: { + description: 'Sam has changing food preferences and eats unusually colored food.', + price: 7.49, + ages: [4, 8], + }, + }, + { + title: 'Harry Potter and the Goblet of Fire', + author: 'J.K. Rowling', + metadata: { + description: 'Fourth year of school starts, big drama ensues.', + price: 24.95, + ages: [10, 99], + }, + }, +]) +``` + + + + +### View the data. + + + + +```sql +select * +from books; +``` + + + + +```js +const { data, error } = await supabase.from('books').select('*') +console.log(JSON.stringify(data, null, 2)) +``` + + + + +| id | title | author | metadata | +| --- | ----------------------------------- | ---------------------- | -------------------------------------------------------------------------------------------------------------- | +| 1 | The Poky Little Puppy | Janette Sebring Lowrey | {"ages":[3,6],"price":5.95,"description":"Puppy is slower than other, bigger animals."} | +| 2 | The Tale of Peter Rabbit | Beatrix Potter | {"ages":[2,5],"price":4.49,"description":"Rabbit eats some vegetables."} | +| 3 | Tootle | Gertrude Crampton | {"ages":[2,5],"price":3.99,"description":"Little toy train has big dreams."} | +| 4 | Green Eggs and Ham | Dr. Seuss | {"ages":[4,8],"price":7.49,"description":"Sam has changing food preferences and eats unusually colored food."} | +| 5 | Harry Potter and the Goblet of Fire | J.K. Rowling | {"ages":[10,99],"price":24.95,"description":"Fourth year of school starts, big drama ensues."} | + +NOTICE: The data as it appears here will have the `JSONB` fields in a different order than when we inserted them. +As we said earlier about the differences between the `JSON` and `JSONB` fields: + +> When you use the `JSONB` format, the data is parsed when it's put into the database... + + + + +### Query the `JSONB` data. + +#### Select title, description, price, and age range for each book. + + + + +```sql +select + title, + metadata -> 'description' AS description, + metadata -> 'price' as price, + metadata -> 'ages' -> 0 as low_age, + metadata -> 'ages' -> 1 as high_age +from + books; +``` + + + + +```js +const { data, error } = await supabase + .from('books') + .select( + 'title,description:metadata->description,price:metadata->price,low_age:metadata->ages->0,high_age:metadata->ages->1' + ) +console.log(JSON.stringify(data, null, 2)) +``` + + + + +| title | description | price | low_age | high_age | +| ----------------------------------- | ------------------------------------------------------------------ | ----- | ------- | -------- | +| The Poky Little Puppy | Puppy is slower than other, bigger animals. | 5.95 | 3 | 6 | +| The Tale of Peter Rabbit | Rabbit eats some vegetables. | 4.49 | 2 | 5 | +| Tootle | Little toy train has big dreams. | 3.99 | 2 | 5 | +| Green Eggs and Ham | Sam has changing food preferences and eats unusually colored food. | 7.49 | 4 | 8 | +| Harry Potter and the Goblet of Fire | Fourth year of school starts, big drama ensues. | 24.95 | 10 | 99 | + + + + +#### Data Types + +One last thing to note: the -> operator returns JSONB data. If you want TEXT/STRING data returned, you need to use the ->> operator. + +- metadata -> 'description' (this returns a JSON object) +- metadata ->> 'description' (this returns STRING/TEXT data) + +## Resources + +- [Supabase Account - Free Tier OK](https://supabase.com) +- [Supabase JS Client](https://github.com/supabase/supabase-js) +- [PostgreSQL: JSON Functions and Operators](https://www.postgresql.org/docs/12/functions-json.html) +- [PostgreSQL JSON types](https://www.postgresql.org/docs/12/datatype-json.html) diff --git a/apps/temp-docs/docs/guides/database/managing-passwords.mdx b/apps/temp-docs/docs/guides/database/managing-passwords.mdx new file mode 100644 index 00000000000..3cf0df757ec --- /dev/null +++ b/apps/temp-docs/docs/guides/database/managing-passwords.mdx @@ -0,0 +1,43 @@ +--- +id: managing-passwords +title: "Passwords" +description: How to change your PostgreSQL database password. +--- + +# Passwords + +Your PostgreSQL database is the core of your Supabase project, so it's important that it has a strong, secure password at all times. + +If you use special symbols in your postgres password, you must remember to [percent-encode](https://en.wikipedia.org/wiki/Percent-encoding) your password later if using the postgres connection string e.g. `postgresql://postgres:p%3Dword@db.cvwawazfelidkloqmbma.supabase.co:5432/postgres` + + +### Changing your project password + +When you created your project you were also asked to enter a password. This is actually the password for your database, specifically for the `postgres` user. +You can update this using SQL: + + + + +```sql +alter user postgres + with password 'new_password'; +``` + + + + + +## Creating a secure password + +It's absolutely critical that you store your customers' data safely. Here are some tips for creating a secure password. + +- Use a password manager to generate it. +- Make a long password (12 characters at least). +- Don't use any common dictionary words. +- Use both upper and lower case characters, numbers, and special symbols. + +## Resources + +- [PostgreSQL `ALTER USER` Documentation](https://www.postgresql.org/docs/12/sql-alteruser.html) + diff --git a/apps/temp-docs/docs/guides/database/managing-timezones.mdx b/apps/temp-docs/docs/guides/database/managing-timezones.mdx new file mode 100644 index 00000000000..69047fb060d --- /dev/null +++ b/apps/temp-docs/docs/guides/database/managing-timezones.mdx @@ -0,0 +1,73 @@ +--- +id: managing-timezones +title: "Timezones" +slug: managing-timezones +description: How to change your database timezone. +--- + +# Timezones + +Every Supabase database is set to UTC timezone by default. We strongly recommend keeping it this way, even if your users are in a different location. +This is because it makes it much easier to calculate differences between timezones if you adopt the mental model that "everything in my database is in UTC time". + + +### Change timezone + + + + + + + +```sql +alter database postgres +set timezone to 'America/New_York'; +``` + + + + + + +### Full list of timezones + +Get a full list of timezones supported by your database. This will return the following columns: + +- `name`: Time zone name +- `abbrev`: Time zone abbreviation +- `utc_offset`: Offset from UTC (positive means east of Greenwich) +- `is_dst`: True if currently observing daylight savings + + + + + + +```sql +select name, abbrev, utc_offset, is_dst +from pg_timezone_names() +order by name; +``` + + + + + + +### Search for a specific timezone + +Use `ilike` (case insensitive search) to find specific timezones. + + + + + +```sql +select * +from pg_timezone_names() +where name ilike '%york%'; +``` + + + diff --git a/apps/temp-docs/docs/guides/database/replication.mdx b/apps/temp-docs/docs/guides/database/replication.mdx new file mode 100644 index 00000000000..5fe1ac12440 --- /dev/null +++ b/apps/temp-docs/docs/guides/database/replication.mdx @@ -0,0 +1,229 @@ +--- +id: replication +title: "Replication" +slug: replication +--- + +# Replication + +Replication is technique for copying the data from one database to another. This is useful for: + +- Spreading out the "load". For example, if your database has a lot of reads, you might want to split it between two databases. +- Reducing latency. For example, you may want one database in London to serve your European customers, and one in New York to serve the US. +- In Supabase's case, we use the built-in replication functionality to provide a real-time API. + + +## Publications + +Publications are a way of choosing which changes should be sent to other systems (usually another Postgres database). + + +### Managing Publications + +Supabase provides an interface for managing your publications, or you can use SQL. + + + + +```sh +1. Go to the "Database" section. +2. Click on "Replication" in the sidebar. +3. Control which database events are sent by toggling the Insert/Update/Delete toggles. +4. Control which tables broadcast changes by clicking into the "Source" and toggling the tables. +``` + + + + + + +```sql +alter publication supabase_realtime add table products; +``` + + + + +### Create a Publication + +This publication will contain all changes to all tables. + + + + + + +```sql +create publication publication_name +for all tables; +``` + + + + + + +### Create a Publication which listens to individual tables + + + + + + + +```sql +create publication publication_name +for table table_one, table_two; +``` + + + + + + +### Add tables to an existing publication + + + + + + + +```sql +alter publication publication_name +add table table_name; +``` + + + + + + +### Listen to `insert` + + + + + + + +```sql +create publication publication_name +for all tables +with (publish = 'insert'); +``` + + + + + + +### Listen to `update` + + + + + + + +```sql +create publication publication_name +for all tables +with (publish = 'update'); +``` + + + + + + +### Listen to `delete` + + + + + + + +```sql +create publication publication_name +for all tables +with (publish = 'delete'); +``` + + + + + + +### Remove a Publication + + + + + + + +```sql +drop publication if exists publication_name; +``` + + + + + + +### Recreate a Publication + +If you are planning to re-create a publication, it's best to do it in a transaction to ensure the operation succeeds. + + + + + + +```sql +begin; + -- remove the realtime publication + drop publication if exists publication_name; + + -- re-create the publication but don't enable it for any tables + create publication publication_name; +commit; +``` + + + + + diff --git a/apps/temp-docs/docs/guides/database/sql-to-api.mdx b/apps/temp-docs/docs/guides/database/sql-to-api.mdx new file mode 100644 index 00000000000..715d9caabc5 --- /dev/null +++ b/apps/temp-docs/docs/guides/database/sql-to-api.mdx @@ -0,0 +1,83 @@ +--- +id: sql-to-api +title: 'Converting SQL to Javascript API' +description: Implementing common SQL patterns in the Javascript API +--- + +import Tabs from '@theme/Tabs' +import TabsPanel from '@theme/TabsPanel' + + + +Select a set of columns from a single table with where, order by, and limit clauses. + +```sql +select first_name, last_name, team_id, age from players +where age between 20 and 24 and team_id <> 'STL' +order by last_name, first_name desc +limit 20 +``` + +```js +const { data, error } = await supabase + .from('players') + .select('first_name,last_name,team_id,age') + .gte('age', 20) + .lte('age', 24) + .not('team_id', 'eq', 'STL') + .order('last_name', { ascending: true }) // or just .order('last_name') + .order('first_name', { ascending: false }) + .limit(20) +``` + +Select all columns from a single table with a complex where clause: OR AND OR + +```sql +select * from players +where ((team_id = 'CHN' or team_id is null) and (age > 35 or age is null)) +``` + +```js +const { data, error } = await supabase + .from('players') + .select() // or .select('*') + .or('team_id.eq.CHN,team_id.is.null') + .or('age.gt.35,age.is.null') // additional filters imply "AND" + .not('team_id', 'eq', 'STL') +``` + +Select all columns from a single table with a complex where clause: AND OR AND + +```sql +select * from players +where ((team_id = 'CHN' and age > 35) or (team_id <> 'CHN' and age is not null)) +``` + +```js +const { data, error } = await supabase + .from('players') + .select() // or .select('*') + .or('and(team_id.eq.CHN,age.gt.35),and(team_id.neq.CHN,.not.age.is.null)') +``` + +Get a count of rows, but don't return any data. + +```sql +select count(*) from players +where team_id = 'NYM' +``` + +```js +const { data, error } = await supabase + .from('players') + .select('*', { count: 'exact', head: true }) // exact, planned, or executed + .eq('team_id', 'NYM') +``` + +## Resources + +- [Supabase Account - Free Tier OK](https://supabase.com) +- [Postgrest Operators](https://postgrest.org/en/stable/api.html#operators) +- [Supabase Javascript API: select](/docs/reference/javascript/select) +- [Supabase Javascript API: modifiers](/docs/reference/javascript/using-modifiers) +- [Supabase Javascript API: filters](/docs/reference/javascript/using-filters) diff --git a/apps/temp-docs/docs/guides/database/tables.mdx b/apps/temp-docs/docs/guides/database/tables.mdx new file mode 100644 index 00000000000..89626dab66d --- /dev/null +++ b/apps/temp-docs/docs/guides/database/tables.mdx @@ -0,0 +1,135 @@ +--- +id: tables +title: Tables +description: Creating and using Postgres tables. +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + + +In Postgres, data is stored in "tables". +Tables are similar to excel spreadsheets. They contain columns & rows of data. There are a few key differences from a spreadsheet however: + +- Every column is a strict type of data. When you set up a column, you must define the "data type". +- Tables can be "joined" together. For example you can have a `users` table, which is joined to a `teams` table (because users belong to teams). + +For example, this table has 3 "columns" (`id`, `name`, `description`) and 4 "rows" of data: + +| `id` | `name` | `description` | +| ---- | ---- | ----------- | +| 1 | Toy Story | When a new toy called "Forky" joins Woody and the gang, a road trip alongside old and new friends reveals how big the world can be for a toy. | +| 2 | Monsters, Inc. | In order to power the city, monsters have to scare children so that they scream. However, the children are toxic to monsters. | +| 3 | Finding Nemo | After his son is captured in the Great Barrier Reef and taken to Sydney, a timid clownfish sets out on a journey to bring him home. | +| 4 | WALL-E | In the distant future, a small waste-collecting robot inadvertently embarks on a space journey that will ultimately decide the fate of mankind. | + + +## Creating Tables + +Supabase provides several options for creating tables. You can use the Table Editor or create them directly using SQL. +We provide a SQL editor within the Dashboard, or you can [connect](/docs/guides/database/connecting/connecting-to-postgres) to your database +and run the SQL queries yourself. + + + + + +```sh +1. Go to the "Table editor" section. +2. Click "New Table". +3. Enter the table name "todos". +4. Click "Save". +5. Click "New Column". +6. Enter the column name "task" and make the type "text". +7. Click "Save". +``` + + + + + + +```sql +-- Create a table called "todos" with a column to store tasks. + +create table todos ( + id bigint generated by default as identity primary key, + task text check (char_length(task) > 3) +); +``` + + + + + +### Tips + +- It is best practice to use lowercase and underscores when naming tables. For example: `table_name`, not `Table Name`. +- Tables belong to `schemas`. If you don't explicitly pass the schema, Postgres will assume that you want to create the table in the `public` schema. + + +### Data types + +Every column is a predefined type. PostgreSQL provides many [default types](https://www.postgresql.org/docs/current/datatype.html), and you can even design your own (or use extensions) +if the default types don't fit your needs. + +
    +Show/Hide default data types + + +| `Name` | `Aliases` | `Description` | +| ------------------------------------------- | -------------------- | ----------------------------------------------------------------- | +| bigint | int8 | signed eight-byte integer | +| bigserial | serial8 | autoincrementing eight-byte integer | +| bit | | fixed-length bit string | +| bit varying | varbit | variable-length bit string | +| boolean | bool | logical Boolean (true/false) | +| box | | rectangular box on a plane | +| bytea | | binary data (“byte array”) | +| character | char | fixed-length character string | +| character varying | varchar | variable-length character string | +| cidr | | IPv4 or IPv6 network address | +| circle | | circle on a plane | +| date | | calendar date (year, month, day) | +| double precision | float8 | double precision floating-point number (8 bytes) | +| inet | | IPv4 or IPv6 host address | +| integer | int, int4 | signed four-byte integer | +| interval \[ fields \] | | time span | +| json | | textual JSON data | +| jsonb | | binary JSON data, decomposed | +| line | | infinite line on a plane | +| lseg | | line segment on a plane | +| macaddr | | MAC (Media Access Control) address | +| macaddr8 | | MAC (Media Access Control) address (EUI-64 format) | +| money | | currency amount | +| numeric | decimal | exact numeric of selectable precision | +| path | | geometric path on a plane | +| pg\_lsn | | PostgreSQL Log Sequence Number | +| pg\_snapshot | | user-level transaction ID snapshot | +| point | | geometric point on a plane | +| polygon | | closed geometric path on a plane | +| real | float4 | single precision floating-point number (4 bytes) | +| smallint | int2 | signed two-byte integer | +| smallserial | serial2 | autoincrementing two-byte integer | +| serial | serial4 | autoincrementing four-byte integer | +| text | | variable-length character string | +| time \[ without time zone \] | | time of day (no time zone) | +| time with time zone | timetz | time of day, including time zone | +| timestamp \[ without time zone \] | | date and time (no time zone) | +| timestamp with time zone | timestamptz | date and time, including time zone | +| tsquery | | text search query | +| tsvector | | text search document | +| txid\_snapshot | | user-level transaction ID snapshot (deprecated; see pg\_snapshot) | +| uuid | | universally unique identifier | +| xml | | XML data | + + +
    + diff --git a/apps/temp-docs/docs/guides/database/timeouts.mdx b/apps/temp-docs/docs/guides/database/timeouts.mdx new file mode 100644 index 00000000000..81979b95fba --- /dev/null +++ b/apps/temp-docs/docs/guides/database/timeouts.mdx @@ -0,0 +1,29 @@ +--- +id: timeouts +title: Timeouts +description: Timeouts and optimization +--- + +# Timeouts + +By default, Supabase limits the maximum statement execution time to _3 seconds_ for users accessing the API using the anon key, and _8 seconds_ for authenticated users. Additionally, all users are subject to a global limit of _2 minutes_. This serves as a backstop against resource exhaustion due to either poorly written queries, or abusive usage. + +### Changing the default timeout + +The timeout values were picked as a reasonable default for the majority of use-cases, but can be modified using the [`alter role`](https://www.postgresql.org/docs/13/sql-alterrole.html) statement: + +```sql +alter role authenticated set statement_timeout = '15s'; +``` + +You can also update the statement timeout for a session: + +```sql +set statement_timeout to 60000; -- 1 minute in milliseconds +``` + +### Statement Optimization + +All Supabase projects come with the [`pg_stat_statements`](https://www.postgresql.org/docs/13/pgstatstatements.html) extension installed, which tracks planning and execution statistics for all statements executed against it. These statistics can be used in order to diagnose the performance of your project. + +This data can further be used in conjunction with the [`explain`](https://www.postgresql.org/docs/13/using-explain.html) functionality of Postgres to optimize your usage. diff --git a/apps/temp-docs/docs/guides/examples.mdx b/apps/temp-docs/docs/guides/examples.mdx new file mode 100644 index 00000000000..930cd82dfdc --- /dev/null +++ b/apps/temp-docs/docs/guides/examples.mdx @@ -0,0 +1,90 @@ +--- +title: 'Examples and Resources' +description: 'Supabase examples and resources' +--- + +# Examples and Resources + +We have a [set of examples](https://github.com/supabase/supabase/tree/master/examples) in our [main repository](https://github.com/supabase/supabase) to help you get started. + +## Todo List + +Build a basic Todo List with Supabase and your favorite frontend framework: + +- [Expo Todo List.](https://github.com/supabase/supabase/tree/master/examples/expo-todo-list) +- [Next.js Todo List.](https://github.com/supabase/supabase/tree/master/examples/nextjs-todo-list) +- [React Todo List.](https://github.com/supabase/supabase/tree/master/examples/react-todo-list) +- [Svelte Todo List.](https://github.com/supabase/supabase/tree/master/examples/sveltejs-todo-list) +- [Vue 3 Todo List (Typescript).](https://github.com/supabase/supabase/tree/master/examples/vue3-ts-todo-list) +- [Angular Todo List.](https://github.com/supabase/supabase/tree/master/examples/angular-todo-list) + +## Auth examples# + +- [Supabase Auth with vanilla Javascript..](https://github.com/supabase/supabase/tree/master/examples/javascript-auth) Use Supabase without any frontend frameworks. +- [Supabase Auth with Next.js SSR.](https://github.com/supabase/supabase/tree/master/examples/nextjs-with-supabase-auth) Uses cookies to persist auth between the server and the client. +- [Supabase Auth with RedwoodJS.](https://redwood-playground-auth.netlify.app/supabase) Try out Supabase authentication in the [RedwoodJS](https://redwoodjs.com/) Authentication Playground complete with OAuth support and code samples. + +## Collaborative + +- [Next.js Slack Clone.](https://github.com/supabase/supabase/tree/master/examples/nextjs-slack-clone) + +## Community + +### Libraries +- Dart (in development): [GitHub](https://github.com/supabase/supabase-dart ) +- Python (in development): [GitHub](https://github.com/supabase/supabase-py) +- C# (in development): [GitHub](https://github.com/supabase/supabase-csharp) +- Kotlin (in development): [GitHub](https://github.com/supabase/supabase-kt) +- useSupabase: Supabase React Hooks. [GitHub](https://github.com/gbibeaul/use-supabase) +- vue-supabase: Supabase Vue wrapper. [GitHub](https://github.com/supabase/vue-supabase) +- vue-3-supabase: Supabase Vue 3 wrapper. [GitHub](https://github.com/DidoMarchet/vue-3-supabase) +- nuxt-supabase: Supabase Nuxt wrapper. [GitHub](https://github.com/supabase/nuxt-supabase) +- react-supabase: Supabase React Hooks. [Docs](https://react-supabase.vercel.app/) [GitHub](https://github.com/tmm/react-supabase) +- @triniwiz/nativescript-supabase: Supabase NativeScript. [GitHub](https://github.com/triniwiz/nativescript-plugins/tree/master/packages/nativescript-supabase) + +### Guides + +- Supabase Auth with Redwood. [Docs](https://redwoodjs.com/tutorial/authentication) +- Supabase Auth with Sapper SSR. [Blog](https://dev.to/jakobbouchard/how-to-setup-supabase-auth-with-sapper-ssr-13od) +- Switch from Firebase Auth to Supabase Auth. [Blog](https://msyyn.medium.com/switch-from-firebase-auth-to-supabase-auth-the-open-source-firebase-alternative-509746952b1b) +- Setting up Umami Analytics with Supabase. [Blog](https://dev.to/jakobbouchard/setting-up-umami-with-vercel-and-supabase-3a73) +- Creating New Supabase Users In NextJS. [Blog](https://www.aboutmonica.com/blog/creating-new-supabase-users-in-next-js) +- Creating Protected Routes In NextJS With Supabase. [Blog](https://www.aboutmonica.com/blog/creating-protected-routes-in-next-js-with-supabase) +- Migrate from Google Cloud Storage (GCS) to Supabase Storage Gist +- Subscriptions with Supabase and Stripe Billing [Blog](https://www.sandromaglione.com/2021/04/29/supabase-auth-create-stripe-customer-subscription-supabase-stripe-billing-part-1/) +- Flutter Supabase Authentication [Blog](https://www.sandromaglione.com/2021/04/24/flutter-supabase-authentication/) +- Supabase in 6 minutes []Video(https://www.youtube.com/watch?v=c8DNV9yl0mg) +- Let's build SupaAuth - Build an Authentication System using Supabase, Next.js and Typescript 6-part [Blog Series](https://aalam.in/blog/supabase-auth-intro-setup-next) +- In-depth self-hosting guide using Nginx [Blog](https://dev.to/chronsyn/self-hosting-with-supabase-1aii) + +### Example apps + + +Supabase + Stripe + Next.js. [GitHub](https://github.com/vercel/nextjs-subscription-payments) +Supabase + Svelte Trello clone. [GitHub](https://github.com/joshnuss/supabase-kanban) +Supabase + Expo Starter. [GitHub](https://github.com/codingki/react-native-expo-template/tree/master/template-typescript-bottom-tabs-supabase-auth-flow) +Supabase + Nest.js. [GitHub](https://github.com/hiro1107/nestjs-supabase-auth) +Supabase + Cloudflare Workers. [GitHub](https://github.com/supabase/supabase/tree/master/examples/with-cloudflare-workers) +Supabase + Cloudflare Workers + Webpack. [GitHub](https://github.com/signalnerve/supabase-workers-proxy) +Realtime chat app with Supabase + React. [GitHub](https://github.com/shwosner/realtime-chat-supabase-react) +Repository.surf: GitHub insights dashboard. [GitHub](https://github.com/supabase/repository.surf) +Supabase + React + Mobx-State-Tree Instagram Clone. [GitHub](https://github.com/NiketanG/instaclone) +KeepLink: Simple bookmark service with tags and archive. [GitHub](https://github.com/fengkx/keeplink) +Supabase + Next.js (Next.js Starter Kit) [Github](https://github.com/one-aalam/next-starter-kit/tree/auth-supabase) +Supabase + Svelte (Svelte Starter Kit) [Github](https://github.com/one-aalam/svelte-starter-kit) +Supabase + SolidJS (SolidJS Starter Kit) [Github](https://github.com/one-aalam/solid-starter-kit) +Supabase + Nuxt3 (Nuxt Starter Kit) [Github](https://github.com/one-aalam/nuxt-starter-kit) +Supabase + Remix (Remix Starter Kit) [Github](https://github.com/one-aalam/remix-starter-kit) +Supabase + Angular (Angular Starter Kit) [Github](https://github.com/one-aalam/ng-starter-kit) + +### Blog Posts + + +Realtime Subscriptions using Vue + Supabase. [Blog](https://dev.to/ftonato/realtime-subscriptions-using-vue-supabase-1e11) +Creating a microblog using Vue + Supabase. [Blog](https://dev.to/ftonato/creating-a-microblog-using-vue-supabase-31p) +Track Real-time Page Views. [Blog](https://codebycorey.com/blog/page-views-nextjs-supabase) +Supabase as a Sentry alternative. [Blog](http://kopi.cloud/blog/2021/sentry-supabase/) +Using Supabase with Chartbrew. [Blog](https://chartbrew.com/blog/how-to-visualize-your-supabase-data-with-chartbrew/) +Authentication with Supabase and React. [Blog](https://hyperfoo.io/posts/supabase-authentication-react) +Supabase Schema Visualizer. [Blog](https://dev.to/zernonia/supabase-schema-visualizer-no-installation-login-49kg) +Create a real-time UI using Next.js + Supabase. [Blog](https://pablopunk.com/posts/how-to-create-a-real-time-ui-with-nextjs-and-supabase) diff --git a/apps/temp-docs/docs/guides/hosting/docker.mdx b/apps/temp-docs/docs/guides/hosting/docker.mdx new file mode 100644 index 00000000000..957cf8b9873 --- /dev/null +++ b/apps/temp-docs/docs/guides/hosting/docker.mdx @@ -0,0 +1,91 @@ +--- +id: docker +title: With Docker +description: How to use configure and deploy Supabase. +--- + +Docker is the easiest way to get started with self-hosted Supabase. + +## Before you begin + +You need the following installed in your system: + +- [Docker](https://docs.docker.com/engine/install/) and docker-compose +- [Git](https://git-scm.com/downloads) + +## Getting started + +### Get the code + +Checkout the docker directory in the Supabase repo: + +```sh +git clone --depth 1 https://github.com/supabase/supabase +cd supabase/docker +``` + +### Manage Secrets + +Copy `.env.example` to `.env` and populate the values. + +```sh +cp .env.example .env +``` + +In particular, these are required: + +- `POSTGRES_PASSWORD`: the password for the `postgres` role +- `JWT_SECRET`: used by PostgREST and GoTrue, among others +- `SITE_URL`: the base URL of your site +- `SMTP_*`: mail server credentials + +### Generate API Keys + +Use your `JWT_SECRET` to generate a `anon` and `service` API keys using the [JWT generator](/docs/guides/hosting/overview#api-keys). + +Replace the values in these files: + +- `docker-compose.yml`: + - `ANON_KEY` - replace with an `anon` key + - `SERVICE_KEY` - replace with a `service` key +- `volumes/kong.yml` + - `anon` - replace with an `anon` key + - `service_role` - replace with a `service` key + +### Start + +You can now start Supabase: + +```sh +docker-compose up +``` + +Your database will be persisted in `volumes/db/data`, and your storage objects in `volumes/storage`. + +Try out the examples in `supabase/examples` to verify if it works correctly! + + +## Configuration + +To keep the setup simple, we made some choices that may not be optimal for production: + +- the database is in the same machine as the servers +- the storage uses the filesystem backend instead of S3 + +We strongly [recommend](/docs/guides/hosting/overview#managing-your-database) that you decouple your database +before deploying. +Each system can be [configured](/docs/guides/hosting/overview#configuration) to suit your particular use-case. + +## Deploying + +See the following guides to deploy Docker Compose setup using your preferred tool and platform: + +- [Docker Swarm](https://docs.docker.com/engine/swarm/stack-deploy/) +- [AWS Fargate](https://aws.amazon.com/blogs/containers/deploy-applications-on-amazon-ecs-using-docker-compose/) +- [Using Kompose for Kubernetes](https://kubernetes.io/docs/tasks/configure-pod-container/translate-compose-kubernetes/) + + +## Next steps + +- Got a question? [Ask here](https://github.com/supabase/supabase/discussions). +- Sign in: [app.supabase.io](https://app.supabase.io) diff --git a/apps/temp-docs/docs/guides/hosting/overview.mdx b/apps/temp-docs/docs/guides/hosting/overview.mdx new file mode 100644 index 00000000000..e65cab3597b --- /dev/null +++ b/apps/temp-docs/docs/guides/hosting/overview.mdx @@ -0,0 +1,162 @@ +--- +id: overview +title: Self Hosting +sidebar_label: Overview +description: Getting started with Self Hosting. +--- + +import JwtGenerator from '@site/src/components/JwtGenerator' + +There are several ways to use Supabase: + +- [Supabase Cloud](https://app.supabase.io): you don't need to deploy anything. We will manage and scale your infrastructure. +- [Docker](/docs/guides/hosting/docker): deploy to your own infrastructure. +- Kubernetes: coming soon. + +#### Before you begin + +The self-hosted version of Supabase does not include a UI yet. +We are working on this in stages, starting with our [UI library](https://github.com/supabase/ui) and with a [WIP PR here](https://github.com/supabase/supabase/pull/2281). +[[more context](https://github.com/supabase/supabase/discussions/1001#discussioncomment-558696)] + +In the meantime, here are some suggestions for working with your Postgres Database: + +- `pgadmin`: https://www.pgadmin.org +- `dbeaver`: https://dbeaver.com +- `BeeKeeper`: https://beekeeperstudio.io +- `HeidiSQL`: https://heidisql.com +- `Table Plus`: https://www.tableplus.io + + +## Architecture + +Supabase is a combination of open source tools, each specifically chosen for Enterprise-readiness. + +If the tools and communities already exist, with an MIT, Apache 2, or equivalent open license, we will use and support that tool. +If the tool doesn't exist, we build and open source it ourselves. + +![Supabase Architecture](/docs/img/supabase-architecture.png) + + +- [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. Supabase listens to Postgres' built-in replication functionality, converts the replication byte stream into JSON, then broadcasts the JSON over websockets. +- [PostgREST](http://postgrest.org/) is a web server that turns your PostgreSQL database directly into a RESTful 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. +- [Kong](https://github.com/Kong/kong) is a cloud-native API gateway. + + +## Configuration + +Each system has a number of configuration options which can be found in the relevant product documentation. + +- [Postgres](https://hub.docker.com/_/postgres/) +- [PostgREST](https://postgrest.org/en/stable/configuration.html) +- [Realtime](https://github.com/supabase/realtime#server-set-up) +- [GoTrue](https://github.com/supabase/gotrue) +- [Storage](https://github.com/supabase/storage-api) +- [Kong](https://docs.konghq.com/install/docker/) + +## Managing your database + +It is recommended that you decouple your database from the middleware so that you can upgrade the middleware without any downtime. +The "middleware" is everything except Postgres, and it should work with any Postgres provider (such as AWS RDS), or your own Postgres cluster. + +### Database Extensions + +Supabase requires some Postgres extensions to be enabled by default for the API and Auth system to work. You can find the extensions inside the +[schema initialization script](https://github.com/supabase/supabase/blob/master/docker/volumes/db/init/00-initial-schema.sql). + + +We recommend installing all extensions into an `extensions` schema. This will keep your API clean, +since all tables in the `public` schema are exposed via the API. + +```sql +create schema if not exists extensions; +create extension if not exists "uuid-ossp" with schema extensions; +create extension if not exists pgcrypto with schema extensions; +create extension if not exists pgjwt with schema extensions; +``` + +##### `uuid-ossp` + +For UUID functions, required for PostgreSQL <13. + + +##### `pgcrypto` and `pgjwt` + + +For working with JWT and Auth functions. + +### Database Roles + +Supabase creates several default roles in your Postgres database. To restore defaults at any time you can run the commands inside the +[schema initialization script](https://github.com/supabase/supabase/blob/master/docker/volumes/db/init/00-initial-schema.sql). + +##### `postgres` + +The default PostgreSQL role. This has admin privileges. + +##### `anon` + +For "anonymous access". This is the role which the API (PostgREST) will use when a user _is not_ logged in. + +##### `authenticator` + +A special role for the API (PostgREST). It has very limited access, and is used to validate a JWT and then +"change into" another role determined by the JWT verification. + +##### `authenticated` + +For "authenticated access". This is the role which the API (PostgREST) will use when a user _is_ logged in. + +##### `service_role` + +For elevated access. This role is used by the API (PostgREST) to bypass Row Level Security. + +##### `supabase_auth_admin` + +Used by the Auth middleware to connect to the database and run migration. Access is scoped to the `auth` schema. + +##### `supabase_storage_admin` + +Used by the Auth middleware to connect to the database and run migration. Access is scoped to the `storage` schema. + +##### `dashboard_user` + +For running commands via the Supabase UI. + +##### `supabase_admin` + +Supabase Administrative role for maintaining your database. + +## API Keys + +The API Gateway (Kong) uses JWT to authenticate access through to the database. The JWT should correspond to a relevant Postgres Role, +and Supabase is designed to work with 2 roles: an `ANON_KEY` for unauthenticated access and a `SERVICE_KEY` for elevated access. + +Use this tool to generate keys: + + + +## Managing your secrets + +Many components inside Supabase use secure secrets and passwords. These are listed in the self-hosting +[env file](https://github.com/supabase/supabase/blob/master/docker/.env.example), but we strongly recommend using a +secrets manager when deploying to production. Plain text files like dotenv lead to accidental costly leaks. + +Some suggested systems include: + +- [Doppler](https://www.doppler.com/) +- [Key Vault](https://docs.microsoft.com/en-us/azure/key-vault/general/overview) by Azure +- [Secrets Manager](https://aws.amazon.com/secrets-manager/) by AWS +- [Secrets Manager](https://cloud.google.com/secret-manager) by GCP +- [Vault](https://www.hashicorp.com/products/vault) by Hashicorp + +## Migrating and Upgrading + +If you have decoupled your database from the middleware, then you should be able to redeploy the latest middleware at any time as long as it has no breaking changes. +Supabase is evolving fast, and we'll continue to improve the migration strategy as part of our core offering. + +We realize that database migrations are difficult, and this is one of the problems we plan to make easy for developers. diff --git a/apps/temp-docs/docs/guides/hosting/platform.mdx b/apps/temp-docs/docs/guides/hosting/platform.mdx new file mode 100644 index 00000000000..c74e5abe601 --- /dev/null +++ b/apps/temp-docs/docs/guides/hosting/platform.mdx @@ -0,0 +1,35 @@ +--- +id: platform +title: Supabase Platform +description: Getting started with the Supabase platform. +--- + + +Supabase is a hosted platform which makes it very simple to get started without needing to manage any infrastructure. + +Visit [app.supabase.io](https://app.supabase.io) and sign in to start creating projects. + +## Organizations + +Organizations are a way to group your projects. Every Organization can be configured with different Team members and billing settings. + +### Managing Team Members + +You can invite your Team members into your Organizations so that you can collaborate on projects. + + + +## Projects + +Each project on Supabase comes with these features: + +- A dedicated Postgres database. [Learn more](/docs/guides/database) +- Auto-generated APIs. +- User management. [Learn more](/docs/guides/auth) +- Storage. [Learn more](/docs/guides/storage) + +## Next Steps + +- Sign in to [app.supabase.io](https://app.supabase.io) diff --git a/apps/temp-docs/docs/guides/local-development.mdx b/apps/temp-docs/docs/guides/local-development.mdx new file mode 100644 index 00000000000..c4bb44734dd --- /dev/null +++ b/apps/temp-docs/docs/guides/local-development.mdx @@ -0,0 +1,172 @@ +--- +id: local-development +title: Local Development +description: How to use Supabase on your local development machine. +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Supabase provides a CLI so that you can develop your application locally, rather than connecting to a live project. + +## Before you begin + +If you're using the CLI, please record your steps! You can help us improve by adding missing details and fixing errors. + +Our CLI is still under heavy development, and is missing some features: + +- The self-hosted version of Supabase does not include a UI yet. +We are working on this in stages, starting with our [UI library](https://github.com/supabase/ui) +([more context](https://github.com/supabase/supabase/discussions/1001#discussioncomment-558696)). + +In the meantime, here are some suggested tools for interacting with your Postgres Database: + +- `pgadmin`: https://www.pgadmin.org +- `dbeaver`: https://dbeaver.com +- `BeeKeeper`: https://beekeeperstudio.io +- `HeidiSQL`: https://heidisql.com +- `Table Plus`: https://www.tableplus.io + +## Prerequisites + +You will need to have these in your environment: +- Git +- Docker (make sure the daemon is up and running) +- Supabase CLI (instructions [here](https://github.com/supabase/cli)) + +## Initialize your project + +```bash +supabase init +``` + +This command will create a `supabase` folder which holds all the configuration for developing your project locally. + +## Start + +```bash +supabase start +``` + +This command uses Docker Compose to start all the open source [services](/docs/#how-it-works) of Supabase. This command will take a while to run, there are a lot of services to build. + +Once this is running, you will see an output that contains your local Supabase credentials: + +```txt +Started local development setup. +API URL: http://localhost:54321 +DB URL: postgresql://postgres:postgres@localhost:5432/postgres +anon key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiJ9.ZopqoUt20nEV9cklpv9e3yw3PVyZLmKs5qLD6nGL1SI +service_role key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoic2VydmljZV9yb2xlIn0.M2d2z4SFn5C7HlJlaSLfrzuYim9nbY_XI40uWFN3hEE +``` + +#### Accessing Services Directly + + + + + +```sh +# Default URL: +postgresql://postgres:postgres@localhost:5432/postgres +``` + +The local Postgres instance can be accessed through [`psql`](https://www.postgresql.org/docs/current/app-psql.html) +or any other Postgres client, such as [pgadmin](https://www.pgadmin.org/). + +For example: + +```bash +psql 'postgresql://postgres:postgres@localhost:5432/postgres' +``` + + + + +```sh +# Default URL: +http://localhost:54321 +``` + +All of the services are accessible through the API Gateway [Kong](https://github.com/Kong/kong)). +If you are accessing these services without the client libraries, you may need to pass the client keys as an `Authorization` header. +You can learn more about these JWT headers in our [Resources](/docs/learn/auth-deep-dive/auth-deep-dive-jwts). + +```sh +curl 'http://localhost:54321/rest/v1/' \ + -H "apikey: SUPABASE_KEY" \ + -H "Authorization: Bearer SUPABASE_KEY" + +http://localhost:54321/v1/rest/v1/ # REST (PostgREST) +http://localhost:54321/v1/realtime/v1/ # Realtime +http://localhost:54321/v1/storage/v1/ # Storage +http://localhost:54321/v1/auth/v1/ # Auth (GoTrue) +``` + + + + + + +## Example application + +Now that we've learned how to install and start Supabase locally, let's see how you can use it with a frontend application. +This quick-start guide will show you, how you can configure a React app which uses the Supabase stack. + +```bash +# create a fresh React app +npx create-react-app react-demo --use-npm + +# move into the new folder +cd react-demo + +# set up Supabase +supabase init + +# Save the install supabase-js library +npm install --save @supabase/supabase-js +``` + +Now that your application is prepared, start the backend: + +```bash +supabase start # Start Supabase +``` + +You can use Supabase anywhere in your application. Copy this snippet into `App.js`: + +```js +import { createClient } from '@supabase/supabase-js' + +const SUPABASE_URL = '' +const SUPABASE_ANON_KEY = '' + +const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY) +``` + +Then start the frontend in a separate terminal: + +```bash +npm start # Start the React app +``` + +If everything is working, you should have a React app running on `http://localhost:3000` and Supabase services running on `http://localhost:54321` + +## Stop + +When you're finished with Supabase, send Ctrl-C to stop the Docker services. + +## Migrations + +You can also use the CLI to manage your migrations. Follow the the tour [here](https://github.com/supabase/cli/tree/main/examples/tour) to get started. + +## Next steps + +- Got a question? [Ask here](https://github.com/supabase/supabase/discussions). +- CLI repository: [GitHub](https://github.com/supabase/cli). +- Sign in: [app.supabase.io](https://app.supabase.io) diff --git a/apps/temp-docs/docs/guides/storage.mdx b/apps/temp-docs/docs/guides/storage.mdx new file mode 100644 index 00000000000..11fa5fc50c0 --- /dev/null +++ b/apps/temp-docs/docs/guides/storage.mdx @@ -0,0 +1,159 @@ +--- +title: 'Storage' +description: 'Supabase Storage' +--- + +# Storage + +## Overview + +Supabase Storage makes it simple to store and serve large files. + +### Files + +Files can be any sort of media file. This includes images, GIFs, and videos. It is best practice to store files outside of your database because of their sizes. + +### Folders + +Folders are a way to organize your files (just like on your computer). There is no right or wrong way to organize your files. You can store them in whichever folder structure suits your project. + +### Buckets + +Buckets are distinct containers for files and folders. You can think of them like "super folders". Generally you would create distinct buckets for different Security and Access Rules. For example, you might keep all public files in a "public" bucket, and other files that require logged-in access in a "restricted" bucket. + +## Getting started + +This is a quick guide that shows the basic functionality of Supabase Storage. Find a full [example application in GitHub](https://github.com/supabase/supabase/edit/master/examples/nextjs-ts-user-management), which you can deploy yourself. + + + + Deploy with Vercel + + +### Create a bucket + +You can create a bucket using the Supabase Dashboard. Since the storage is interoperable with your Postgres database, you can also use SQL or our client libraries. Here we create a bucket called "avatars": + + + +[Reference](https://pub.dev/documentation/storage_client/latest/storage_client/SupabaseStorageClient/createBucket.html) + +### Upload a file +You can upload a file from the Dashboard, or within a browser using our JS libraries. + + + +### Download a file +You can download a file from the Dashboard, or within a browser using our JS libraries. + + + +### Add security rules + +To restrict access to your files you can use either the Dashboard or SQL. + + + +### Helpers + +Supabase Storage is configured with database SQL helper functions which you can use in your database queries and policies. + +
    + +`storage.filename()` + +Returns the name of a file. + +```sql +select storage.filename(name) +from storage.objects; +``` + +For example, if your file is stored in `public/subfolder/avatar.png` it would return: + +`'avatar.png'` + +
    + +`storage.foldername()` + +Returns an array path, with all of the subfolders that a file belongs to. + +```sql +select storage.foldername(name) +from storage.objects; +``` + +For example, if your file is stored in `public/subfolder/avatar.png` it would return: + +`[ 'public', 'subfolder' ]` + +
    + +`storage.extension()` + +Returns the extension of a file. + +```sql +select storage.extension(name) +from storage.objects; +``` + +For example, if your file is stored in `public/subfolder/avatar.png` it would return: + +`'png'` + +
    + +### Security + +Supabase Storage is integrated with your Postgres Database. This means that you can use the same Policy engine for managing access to your files. + +### Policy Examples + +Here are some examples to show you the power of PostgreSQL's Row Level Security. Each policy is attached to a table, and the policy is executed every time a table is accessed. + +#### Allow public access to a bucket + +```sql +-- 1. Allow public access to any files in the "public" bucket +create policy "Public Access" +on storage.objects for select +using ( bucket_id = 'public' ); +``` +#### Allow logged-in access to a bucket +```sql +-- 1. Allow logged-in access to any files in the "restricted" bucket +create policy "Restricted Access" +on storage.objects for select +using ( + bucket_id = 'restricted' + and auth.role() = 'authenticated' +); +``` + +#### Allow individual access to a file + +```sql +-- 1. Allow a user to access their own files +create policy "Individual user Access" +on storage.objects for select +using ( auth.uid() = owner ); +``` +### Tips +#### Go Easy +Supabase Storage is in Beta. If you're experiencing any issues, let us know on our [GitHub](https://github.com/supabase/supabase/discussions) and we will fix it as fast as we can. + +## Next steps +- Got a question? Ask here. +- Read more about storage in our blog post. +- Sign in: app.supabase.io + diff --git a/apps/temp-docs/docs/guides/storage/storage-sample.mdx b/apps/temp-docs/docs/guides/storage/storage-sample.mdx new file mode 100644 index 00000000000..da9b915620a --- /dev/null +++ b/apps/temp-docs/docs/guides/storage/storage-sample.mdx @@ -0,0 +1,12 @@ +--- +id: storage-sample +title: "Storage Sample Doc" +description: Storage Sample Doc +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +## Description + +Sample... \ No newline at end of file diff --git a/apps/temp-docs/docs/guides/with-angular.mdx b/apps/temp-docs/docs/guides/with-angular.mdx new file mode 100644 index 00000000000..8b2d755bc7c --- /dev/null +++ b/apps/temp-docs/docs/guides/with-angular.mdx @@ -0,0 +1,542 @@ +--- +id: with-angular +title: 'Quickstart: Angular' +description: Learn how to use Supabase in your Angular App. +--- + +# Quickstart: Angular + +## Intro + +This example provides the steps to build a simple user management app (from scratch!) using Supabase and Angular. It includes: + +- Supabase [Database](/guides/database): a Postgres database for storing your user data. +- Supabase [Auth](/guides/auth): users can sign in with magic links (no passwords, only email). +- Supabase [Storage](/guides/storage): users can upload a photo. +- [Row Level Security](/guides/auth#row-level-security): data is protected so that individuals can only access their own data. +- Instant [APIs](/guides/api): APIs will be automatically generated when you create your database tables. + +By the end of this guide you'll have an app which allows users to login and update some basic profile details: + +![Supabase User Management example](/docs/img/user-management-demo.png) + +Clicking this button the application will: + +- Launch and prepare the Postgres database in Supabase. +- Launch the app in Vercel. +- Fork the example into your own GitHub account. +- Prepare the deployed application with all the necessary environment variables. + +If you want to do it yourself, let's get started! + +### Github + +Whenever you get stuck at any point, take a look at [this repo](https://github.com/angular-supa/supabase-angular-user-management). + +## Project set up + +Before we start building we're going to set up our Database and API. This is as simple as starting a new Project in Supabase +and then creating a "schema" inside the database. + +### Create a project + +1. Go to [app.supabase.io](https://app.supabase.io). +1. Click on "New Project". +1. Enter your project details. +1. Wait for the new database to launch. + +### Set up the database schema + +Now we are going to set up the database schema. We can use the "User Management Starter" quickstart in the SQL Editor, +or you can just copy/paste the SQL from below and run it yourself. + + + + +```sh +1. Go to the "SQL" section. +2. Click "User Management Starter". +3. Click "Run". +``` + + + + + + +```sql +-- Create a table for public "profiles" +create table profiles ( + id uuid references auth.users not null, + updated_at timestamp with time zone, + username text unique, + avatar_url text, + website text, + + primary key (id), + unique(username), + constraint username_length check (char_length(username) >= 3) +); + +alter table profiles enable row level security; + +create policy "Public profiles are viewable by everyone." + on profiles for select + using ( true ); + +create policy "Users can insert their own profile." + on profiles for insert + with check ( auth.uid() = id ); + +create policy "Users can update own profile." + on profiles for update + using ( auth.uid() = id ); + +-- Set up Realtime! +begin; + drop publication if exists supabase_realtime; + create publication supabase_realtime; +commit; +alter publication supabase_realtime add table profiles; + +-- Set up Storage! +insert into storage.buckets (id, name) +values ('avatars', 'avatars'); + +create policy "Avatar images are publicly accessible." + on storage.objects for select + using ( bucket_id = 'avatars' ); + +create policy "Anyone can upload an avatar." + on storage.objects for insert + with check ( bucket_id = 'avatars' ); +``` + + + + +### Get the API Keys + +Now that you've created some database tables, you are ready to insert data using the auto-generated API. +We just need to get the URL and `anon` key from the API settings. + + + + +```sh +1. Go to the "Settings" section. +2. Click "API" in the sidebar. +3. Find your API URL in this page. +4. Find your "anon" and "service_role" keys on this page. +``` + + + + + + +## Building the App + +Let's start building the Angular app from scratch. + +### Initialize an Angular app + +We can use the [Angular CLI](https://angular.io/cli) to initialize +an app called `supabase-angular`: + +```bash +npx ng new supabase-angular --routing false --style css +cd supabase-angular +``` + +Then let's install the only additional dependency: [supabase-js](https://github.com/supabase/supabase-js) + +```bash +npm install @supabase/supabase-js +``` + +And finally we want to save the environment variables in the `environment.ts` file. +All we need are the API URL and the `anon` key that you copied [earlier](#get-the-api-keys). +These variables will be exposed on the browser, and that's completely fine since we have [Row Level Security](/guides/auth#row-level-security) enabled on our Database. + +```ts title="environment.ts" +export const environment = { + production: false, + supabaseUrl: 'YOUR_SUPABASE_URL', + supabaseKey: 'YOUR_SUPABASE_KEY', +} +``` + +Now that we have the API credentials in place, let's create a **SupabaseService** with `ng g s supabase` to initialize the Supabase client and implement functions to communicate with the Supabase API. + +```ts title="src/app/supabase.service.ts" +import { Injectable } from '@angular/core' +import { AuthChangeEvent, createClient, Session, SupabaseClient } from '@supabase/supabase-js' +import { environment } from '../environments/environment' + +export interface Profile { + username: string + website: string + avatar_url: string +} + +@Injectable({ + providedIn: 'root', +}) +export class SupabaseService { + private supabase: SupabaseClient + + constructor() { + this.supabase = createClient(environment.supabaseUrl, environment.supabaseKey) + } + + get user() { + return this.supabase.auth.user() + } + + get session() { + return this.supabase.auth.session() + } + + get profile() { + return this.supabase + .from('profiles') + .select(`username, website, avatar_url`) + .eq('id', this.user?.id) + .single() + } + + authChanges(callback: (event: AuthChangeEvent, session: Session | null) => void) { + return this.supabase.auth.onAuthStateChange(callback) + } + + signIn(email: string) { + return this.supabase.auth.signIn({ email }) + } + + signOut() { + return this.supabase.auth.signOut() + } + + updateProfile(profile: Profile) { + const update = { + ...profile, + id: this.user?.id, + updated_at: new Date(), + } + + return this.supabase.from('profiles').upsert(update, { + returning: 'minimal', // Don't return the value after inserting + }) + } + + downLoadImage(path: string) { + return this.supabase.storage.from('avatars').download(path) + } + + uploadAvatar(filePath: string, file: File) { + return this.supabase.storage.from('avatars').upload(filePath, file) + } +} +``` + +And one optional step is to update the CSS file `src/index.css` to make the app look nice. +You can find the full contents of this file [here](https://raw.githubusercontent.com/angular-supa/supabase-angular-user-management/main/src/styles.css). + +### Set up a Login component + +Let's set up an Angular component to manage logins and sign ups. We'll use Magic Links, so users can sign in with their email without using passwords. +Create an **AuthComponent** with `ng g c auth` Angular CLI command. + +```ts title="src/app/auth.component.ts" +import { Component } from '@angular/core' +import { SupabaseService } from './supabase.service' + +@Component({ + selector: 'app-auth', + template: ` +
    +
    +

    Supabase + Angular

    +

    Sign in via magic link with your email below

    +
    + +
    +
    + +
    +
    +
    + `, +}) +export class AuthComponent { + loading = false + + constructor(private readonly supabase: SupabaseService) {} + + async handleLogin(input: string) { + try { + this.loading = true + await this.supabase.signIn(input) + alert('Check your email for the login link!') + } catch (error) { + alert(error.error_description || error.message) + } finally { + this.loading = false + } + } +} +``` + +### Account page + +After a user is signed in we can allow them to edit their profile details and manage their account. +Create an **AccountComponent** with `ng g c account` Angular CLI command. + +```ts title="src/app/account.component.ts" +import { Component, Input, OnInit } from '@angular/core' +import { Profile, SupabaseService } from './supabase.service' +import { Session } from '@supabase/supabase-js' + +@Component({ + selector: 'app-account', + template: ` +
    +
    + + +
    +
    + + +
    +
    + + +
    + +
    + +
    + +
    + +
    +
    + `, +}) +export class AccountComponent implements OnInit { + loading = false + profile: Profile | undefined + + @Input() session: Session | undefined + + constructor(private readonly supabase: SupabaseService) {} + + ngOnInit() { + this.getProfile() + } + + async getProfile() { + try { + this.loading = true + let { data: profile, error, status } = await this.supabase.profile + + if (error && status !== 406) { + throw error + } + + if (profile) { + this.profile = profile + } + } catch (error) { + alert(error.message) + } finally { + this.loading = false + } + } + + async updateProfile(username: string, website: string, avatar_url: string = '') { + try { + this.loading = true + await this.supabase.updateProfile({ username, website, avatar_url }) + } catch (error) { + alert(error.message) + } finally { + this.loading = false + } + } + + async signOut() { + await this.supabase.signOut() + } +} +``` + +### Launch! + +Now that we have all the components in place, let's update **AppComponent**: + +```ts title="src/app/app.component.ts" +import { Component, OnInit } from '@angular/core' +import { SupabaseService } from './supabase.service' + +@Component({ + selector: 'app-root', + template: ` +
    + + + + +
    + `, +}) +export class AppComponent implements OnInit { + session = this.supabase.session + + constructor(private readonly supabase: SupabaseService) {} + + ngOnInit() { + this.supabase.authChanges((_, session) => (this.session = session)) + } +} +``` + +Once that's done, run this in a terminal window: + +```bash +npm run start +``` + +And then open the browser to [localhost:4200](http://localhost:4200) and you should see the completed app. + +![Supabase Angular](/docs/img/supabase-angular-demo.png) + +## Bonus: Profile photos + +Every Supabase project is configured with [Storage](/guides/storage) for managing large files like photos and videos. + +### Create an upload widget + +Let's create an avatar for the user so that they can upload a profile photo. +Create an **AvatarComponent** with `ng g c avatar` Angular CLI command. + +```ts title="src/app/avatar.component.ts" +import { Component, EventEmitter, Input, Output } from '@angular/core' +import { SupabaseService } from './supabase.service' +import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser' + +@Component({ + selector: 'app-avatar', + template: ` +
    + Avatar +
    +
    +
    + + +
    + `, +}) +export class AvatarComponent { + _avatarUrl: SafeResourceUrl | undefined + uploading = false + + @Input() + set avatarUrl(url: string | undefined) { + if (url) { + this.downloadImage(url) + } + } + + @Output() upload = new EventEmitter() + + constructor(private readonly supabase: SupabaseService, private readonly dom: DomSanitizer) {} + + async downloadImage(path: string) { + try { + const { data } = await this.supabase.downLoadImage(path) + this._avatarUrl = this.dom.bypassSecurityTrustResourceUrl(URL.createObjectURL(data)) + } catch (error) { + console.error('Error downloading image: ', error.message) + } + } + + async uploadAvatar(event: any) { + try { + this.uploading = true + if (!event.target.files || event.target.files.length === 0) { + throw new Error('You must select an image to upload.') + } + + const file = event.target.files[0] + const fileExt = file.name.split('.').pop() + const fileName = `${Math.random()}.${fileExt}` + const filePath = `${fileName}` + + await this.supabase.uploadAvatar(filePath, file) + this.upload.emit(filePath) + } catch (error) { + alert(error.message) + } finally { + this.uploading = false + } + } +} +``` + +### Add the new widget + +And then we can add the widget on top of the **AccountComponent** html template: + +```ts title="src/app/account.component.ts" +template: ` + + + + +` +``` + +## Next steps + +At this stage you have a fully functional application! + +- Got a question? [Ask here](https://github.com/supabase/supabase/discussions). +- Sign in: [app.supabase.io](https://app.supabase.io) diff --git a/apps/temp-docs/docs/guides/with-flutter.mdx b/apps/temp-docs/docs/guides/with-flutter.mdx new file mode 100644 index 00000000000..338b1279b46 --- /dev/null +++ b/apps/temp-docs/docs/guides/with-flutter.mdx @@ -0,0 +1,909 @@ +--- +id: with-flutter +title: 'Quickstart: Flutter' +description: Learn how to use Supabase in your Flutter App. +--- + +# Quickstart: Flutter + + +## Intro + +This example provides the steps to build a simple user management app (from scratch!) using Supabase and Flutter. It includes: + +- Supabase [Database](/guides/database): a Postgres database for storing your user data. +- Supabase [Auth](/guides/auth): users can sign in with magic links (no passwords, only email). + +- [Row Level Security](/guides/auth#row-level-security): data is protected so that individuals can only access their own data. +- Instant [APIs](/guides/api): APIs will be automatically generated when you create your database tables. + +By the end of this guide you'll have an app which allows users to login and update some basic profile details: + +![Supabase User Management example](/docs/img/supabase-flutter-demo.png) + +### Github + +Whenever you get stuck at any point, take a look at [this repo](https://github.com/supasquad/supabase-flutter-quickstart). + +## Project set up + +Before we start building we're going to set up our Database and API. This is as simple as starting a new Project in Supabase +and then creating a "schema" inside the database. + +### Create a project + +1. Go to [app.supabase.io](https://app.supabase.io). +1. Click on "New Project". +1. Enter your project details. +1. Wait for the new database to launch. + +### Set up the database schema + +Now we are going to set up the database schema. We can use the "User Management Starter" quickstart in the SQL Editor, +or you can just copy/paste the SQL from below and run it yourself. + + + + +```sh +1. Go to the "SQL" section. +2. Click "User Management Starter". +3. Click "Run". +``` + + + + + + +```sql +-- Create a table for public "profiles" +create table profiles ( + id uuid references auth.users not null, + updated_at timestamp with time zone, + username text unique, + avatar_url text, + website text, + + primary key (id), + unique(username), + constraint username_length check (char_length(username) >= 3) +); + +alter table profiles enable row level security; + +create policy "Public profiles are viewable by everyone." + on profiles for select + using ( true ); + +create policy "Users can insert their own profile." + on profiles for insert + with check ( auth.uid() = id ); + +create policy "Users can update own profile." + on profiles for update + using ( auth.uid() = id ); + +-- Set up Realtime! +begin; + drop publication if exists supabase_realtime; + create publication supabase_realtime; +commit; +alter publication supabase_realtime add table profiles; + +-- Set up Storage! +insert into storage.buckets (id, name, public) +values ('avatars', 'avatars', true); + +create policy "Anyone can upload an avatar." + on storage.objects for insert + with check ( bucket_id = 'avatars' ); + +``` + + + + +### Get the API Keys + +Now that you've created some database tables, you are ready to insert data using the auto-generated API. +We just need to get the URL and `anon` key from the API settings. + + + + +```sh +1. Go to the "Settings" section. +2. Click "API" in the sidebar. +3. Find your API URL in this page. +4. Find your "anon" key on this page. +``` + + + + + + +## Building the App + +Let's start building the Flutter app from scratch. + +### Initialize a Flutter app + +We can use [`flutter create`](https://flutter.dev/get-started/test-drive) to initialize +an app called `supabase_quickstart`: + +```bash +flutter create supabase_quickstart +``` + +Then let's install the only additional dependency: [`supabase_flutter`](https://github.com/supabase/supabase-flutter) + +Run the following command to get the newest version of `supabase_flutter` to your project. + +```bash +flutter pub add supabase_flutter +``` + +Run `flutter pub get` to install the dependencies. + +### Setup deep links + +Now that we have the dependencies installed let's setup deep links so users who have logged in via magic link or OAuth can come back to the app. + +```sh +1. Go to the "Authentication" section. +2. Click "Settings" in the sidebar. +3. Type `io.supabase.flutterquickstart://login-callback/` in the Additional Redirect URLs input field. +4. Hit save. +``` + +![Supabase console deep link setting](/docs/img/deeplink-setting.png) + +That is it on Supabase's end and the rest are platform specific settings: + +For Android, add an intent-filter to enable deep linking: + +```xml title="android/app/src/main/AndroidManifest.xml" + + + + + + + + + + + + + + + + + + +``` + +For iOS add CFBundleURLTypes to enable deep linking: + +```xml title="ios/Runner/Info.plist" + + + + + + + CFBundleURLTypes + + + CFBundleTypeRole + Editor + CFBundleURLSchemes + + io.supabase.flutterquickstart + + + + + + +``` + +For web: + +There are no additional configurations. + +### Main function + +Now that we have deep links ready let's initialize the Supabase client inside our `main` function with the API credentials that you copied [earlier](#get-the-api-keys). +These variables will be exposed on the app, and that's completely fine since we have +[Row Level Security](/guides/auth#row-level-security) enabled on our Database. + +```dart title="lib/main.dart" +Future main() async { + WidgetsFlutterBinding.ensureInitialized(); + + await Supabase.initialize( + url: '[YOUR_SUPABASE_URL]', + anonKey: '[YOUR_SUPABASE_ANON_KEY]', + ); + runApp(MyApp()); +} +``` + +### Set up AuthState + +In order to handle deep links for Android and iOS, let's create a class that will do just that. +`supabase_flutter` plugin comes with `SupabaseAuthState` class where we can inherit from to react to various deep link events. + +```dart title="lib/components/auth_state.dart" +import 'package:flutter/material.dart'; +import 'package:supabase/supabase.dart'; +import 'package:supabase_flutter/supabase_flutter.dart'; +import 'package:supabase_quickstart/utils/constants.dart'; + +class AuthState extends SupabaseAuthState { + @override + void onUnauthenticated() { + if (mounted) { + Navigator.of(context).pushNamedAndRemoveUntil('/login', (route) => false); + } + } + + @override + void onAuthenticated(Session session) { + if (mounted) { + Navigator.of(context) + .pushNamedAndRemoveUntil('/account', (route) => false); + } + } + + @override + void onPasswordRecovery(Session session) {} + + @override + void onErrorAuthenticating(String message) { + context.showErrorSnackBar(message: message); + } +} +``` + +### Set up AuthRequiredState + +We might want to show certain pages to the users only if they are signed in. +For that we can create a handy `AuthRequiredState` class that we can inherit from for pages where the users need to be authenticated. +`AuthRequiredState` will inherit `SupabaseAuthRequiredState` which is provided by `supabase_flutter` package. + +```dart title="lib/components/auth_required_state.dart" +import 'package:flutter/material.dart'; +import 'package:supabase_flutter/supabase_flutter.dart'; + +class AuthRequiredState + extends SupabaseAuthRequiredState { + @override + void onUnauthenticated() { + /// Users will be sent back to the LoginPage if they sign out. + if (mounted) { + /// Users will be sent back to the LoginPage if they sign out. + Navigator.of(context).pushNamedAndRemoveUntil('/login', (route) => false); + } + } +} +``` + +Let's also create a constant file to make it easier to use Supabase client. +We will also include an extension method declaration to call `showSnackBar` with one line of code. + +```dart title="lib/utils/constants.dart" +import 'package:flutter/material.dart'; +import 'package:supabase_flutter/supabase_flutter.dart'; + +final supabase = Supabase.instance.client; + +extension ShowSnackBar on BuildContext { + void showSnackBar({ + required String message, + Color backgroundColor = Colors.white, + }) { + ScaffoldMessenger.of(this).showSnackBar(SnackBar( + content: Text(message), + backgroundColor: backgroundColor, + )); + } + + void showErrorSnackBar({required String message}) { + showSnackBar(message: message, backgroundColor: Colors.red); + } +} +``` + +### Set up Splash Screen + +Let's create a splash screen that will be shown to users right after they open the app. +This splash screen inherits `AuthState` to redirect users to the appropriate pages depending on their authentication state. + +```dart title="lib/pages/splash_page.dart" +import 'package:flutter/material.dart'; +import 'package:supabase_quickstart/components/auth_state.dart'; + +class SplashPage extends StatefulWidget { + const SplashPage({Key? key}) : super(key: key); + + @override + _SplashPageState createState() => _SplashPageState(); +} + +class _SplashPageState extends AuthState { + @override + void initState() { + recoverSupabaseSession(); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return const Scaffold( + body: Center(child: CircularProgressIndicator()), + ); + } +} +``` + +### Set up a Login page + +Let's create a Flutter widget to manage logins and sign ups. +We'll use Magic Links, so users can sign in with their email without using passwords. +This page will also inherit `AuthState` as it will handle user login. + +```dart title="lib/pages/login_page.dart" +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:supabase/supabase.dart'; +import 'package:supabase_quickstart/components/auth_state.dart'; +import 'package:supabase_quickstart/utils/constants.dart'; + +class LoginPage extends StatefulWidget { + const LoginPage({Key? key}) : super(key: key); + + @override + _LoginPageState createState() => _LoginPageState(); +} + +class _LoginPageState extends AuthState { + bool _isLoading = false; + late final TextEditingController _emailController; + + Future _signIn() async { + setState(() { + _isLoading = true; + }); + final response = await supabase.auth.signIn( + email: _emailController.text, + options: AuthOptions( + redirectTo: kIsWeb + ? null + : 'io.supabase.flutterquickstart://login-callback/')); + final error = response.error; + if (error != null) { + context.showErrorSnackBar(message: error.message); + } else { + context.showSnackBar(message: 'Check your email for login link!'); + _emailController.clear(); + } + + setState(() { + _isLoading = false; + }); + } + + @override + void initState() { + super.initState(); + _emailController = TextEditingController(); + } + + @override + void dispose() { + _emailController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: const Text('Sign In')), + body: ListView( + padding: const EdgeInsets.symmetric(vertical: 18, horizontal: 12), + children: [ + const Text('Sign in via the magic link with your email below'), + const SizedBox(height: 18), + TextFormField( + controller: _emailController, + decoration: const InputDecoration(labelText: 'Email'), + ), + const SizedBox(height: 18), + ElevatedButton( + onPressed: _isLoading ? null : _signIn, + child: Text(_isLoading ? 'Loading' : 'Send Magic Link'), + ), + ], + ), + ); + } +} +``` + +### Set up Account page + +After a user is signed in we can allow them to edit their profile details and manage their account. +Let's create a new widget called `account_page.dart` for that. +Note that this page will inherit `AuthRequiredState` as user needs to be authenticated to view this page. + +```dart title="lib/pages/account_page.dart" +import 'package:flutter/material.dart'; +import 'package:supabase/supabase.dart'; +import 'package:supabase_quickstart/components/auth_required_state.dart'; +import 'package:supabase_quickstart/utils/constants.dart'; + +class AccountPage extends StatefulWidget { + const AccountPage({Key? key}) : super(key: key); + + @override + _AccountPageState createState() => _AccountPageState(); +} + +class _AccountPageState extends AuthRequiredState { + final _usernameController = TextEditingController(); + final _websiteController = TextEditingController(); + var _loading = false; + + /// Called once a user id is received within `onAuthenticated()` + Future _getProfile(String userId) async { + setState(() { + _loading = true; + }); + final response = await supabase + .from('profiles') + .select() + .eq('id', userId) + .single() + .execute(); + final error = response.error; + if (error != null && response.status != 406) { + context.showErrorSnackBar(message: error.message); + } + final data = response.data; + if (data != null) { + _usernameController.text = (data['username'] ?? '') as String; + _websiteController.text = (data['website'] ?? '') as String; + } + setState(() { + _loading = false; + }); + } + + /// Called when user taps `Update` button + Future _updateProfile() async { + setState(() { + _loading = true; + }); + final userName = _usernameController.text; + final website = _websiteController.text; + final user = supabase.auth.currentUser; + final updates = { + 'id': user!.id, + 'username': userName, + 'website': website, + 'updated_at': DateTime.now().toIso8601String(), + }; + final response = await supabase.from('profiles').upsert(updates).execute(); + final error = response.error; + if (error != null) { + context.showErrorSnackBar(message: error.message); + } else { + context.showSnackBar(message: 'Successfully updated profile!'); + } + setState(() { + _loading = false; + }); + } + + Future _signOut() async { + final response = await supabase.auth.signOut(); + final error = response.error; + if (error != null) { + context.showErrorSnackBar(message: error.message); + } + } + + @override + void onAuthenticated(Session session) { + final user = session.user; + if (user != null) { + _getProfile(user.id); + } + } + + @override + void dispose() { + _usernameController.dispose(); + _websiteController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: const Text('Profile')), + body: ListView( + padding: const EdgeInsets.symmetric(vertical: 18, horizontal: 12), + children: [ + TextFormField( + controller: _usernameController, + decoration: const InputDecoration(labelText: 'User Name'), + ), + const SizedBox(height: 18), + TextFormField( + controller: _websiteController, + decoration: const InputDecoration(labelText: 'Website'), + ), + const SizedBox(height: 18), + ElevatedButton( + onPressed: _updateProfile, + child: Text(_loading ? 'Saving...' : 'Update')), + const SizedBox(height: 18), + ElevatedButton(onPressed: _signOut, child: const Text('Sign Out')), + ], + ), + ); + } +} +``` + +### Launch! + +Now that we have all the components in place, let's update `lib/main.dart`: + +```dart title="lib/main.dart" +import 'package:flutter/material.dart'; +import 'package:supabase_flutter/supabase_flutter.dart'; +import 'package:supabase_quickstart/pages/account_page.dart'; +import 'package:supabase_quickstart/pages/login_page.dart'; +import 'package:supabase_quickstart/pages/splash_page.dart'; + +Future main() async { + WidgetsFlutterBinding.ensureInitialized(); + + await Supabase.initialize( + // TODO: Replace credentials with your own + url: '[YOUR_SUPABASE_URL]', + anonKey: '[YOUR_SUPABASE_ANNON_KEY]', + ); + runApp(MyApp()); +} + +class MyApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Supabase Flutter', + theme: ThemeData.dark().copyWith( + primaryColor: Colors.green, + elevatedButtonTheme: ElevatedButtonThemeData( + style: ElevatedButton.styleFrom( + onPrimary: Colors.white, + primary: Colors.green, + ), + ), + ), + initialRoute: '/', + routes: { + '/': (_) => const SplashPage(), + '/login': (_) => const LoginPage(), + '/account': (_) => const AccountPage(), + }, + ); + } +} +``` + +Once that's done, run this in a terminal window to launch on Android or iOS: + +```bash +flutter run +``` + +Or for web, run the following command to launch it on `localhost:3000` + +```bash +flutter run -d web-server --web-hostname localhost --web-port 3000 +``` + +And then open the browser to [localhost:3000](http://localhost:3000) and you should see the completed app. + +![Supabase User Management example](/docs/img/supabase-flutter-account-page.png) + +## Bonus: Profile photos + +Every Supabase project is configured with [Storage](/guides/storage) for managing large files like +photos and videos. + +### Adding image uploading feature to Account page + +We will use [`image_picker`](https://pub.dev/packages/image_picker) plugin to select an image from the device. + +Run the following command to install it. + +```bash +flutter pub add image_picker +``` + +Using [`image_picker`](https://pub.dev/packages/image_picker) requires some additional preparation depending on the platform. +Follow the instruction on README.md of [`image_picker`](https://pub.dev/packages/image_picker) on how to set it up for the platform you are using. + +Once you are done with all of the above, it is time to dive into coding. + +### Create an upload widget + +Let's create an avatar for the user so that they can upload a profile photo. +We can start by creating a new component: + +```dart title="lib/components/avatar.dart" +import 'package:flutter/material.dart'; +import 'package:image_picker/image_picker.dart'; +import 'package:supabase_quickstart/utils/constants.dart'; + +class Avatar extends StatefulWidget { + const Avatar({ + Key? key, + required this.imageUrl, + required this.onUpload, + }) : super(key: key); + + final String? imageUrl; + final void Function(String) onUpload; + + @override + _AvatarState createState() => _AvatarState(); +} + +class _AvatarState extends State { + bool _isLoading = false; + + @override + Widget build(BuildContext context) { + return Column( + children: [ + if (widget.imageUrl == null) + Container( + width: 150, + height: 150, + color: Colors.grey, + child: const Center( + child: Text('No Image'), + ), + ) + else + Image.network( + widget.imageUrl!, + width: 150, + height: 150, + fit: BoxFit.cover, + ), + ElevatedButton( + onPressed: _isLoading ? null : _upload, + child: const Text('Upload'), + ), + ], + ); + } + + Future _upload() async { + final _picker = ImagePicker(); + final imageFile = await _picker.pickImage( + source: ImageSource.gallery, + maxWidth: 300, + maxHeight: 300, + ); + if (imageFile == null) { + return; + } + setState(() => _isLoading = true); + + final bytes = await imageFile.readAsBytes(); + final fileExt = imageFile.path.split('.').last; + final fileName = '${DateTime.now().toIso8601String()}.$fileExt'; + final filePath = fileName; + final response = + await supabase.storage.from('avatars').uploadBinary(filePath, bytes); + + setState(() => _isLoading = false); + + final error = response.error; + if (error != null) { + context.showErrorSnackBar(message: error.message); + return; + } + final imageUrlResponse = + supabase.storage.from('avatars').getPublicUrl(filePath); + widget.onUpload(imageUrlResponse.data!); + } +} +``` + +### Add the new widget + +And then we can add the widget to the Account page as well as some logic to update the `avatar_url` whenever the user uploads a new avatar. + +```dart title="lib/pages/account_page.dart" +import 'package:flutter/material.dart'; +import 'package:supabase/supabase.dart'; +import 'package:supabase_quickstart/components/auth_required_state.dart'; +import 'package:supabase_quickstart/components/avatar.dart'; +import 'package:supabase_quickstart/utils/constants.dart'; + +class AccountPage extends StatefulWidget { + const AccountPage({Key? key}) : super(key: key); + + @override + _AccountPageState createState() => _AccountPageState(); +} + +class _AccountPageState extends AuthRequiredState { + final _usernameController = TextEditingController(); + final _websiteController = TextEditingController(); + String? _userId; + String? _avatarUrl; + var _loading = false; + + /// Called once a user id is received within `onAuthenticated()` + Future _getProfile(String userId) async { + setState(() { + _loading = true; + }); + final response = await supabase + .from('profiles') + .select() + .eq('id', userId) + .single() + .execute(); + final error = response.error; + if (error != null && response.status != 406) { + context.showErrorSnackBar(message: error.message); + } + final data = response.data; + if (data != null) { + _usernameController.text = (data['username'] ?? '') as String; + _websiteController.text = (data['website'] ?? '') as String; + _avatarUrl = (data['avatar_url'] ?? '') as String; + } + setState(() { + _loading = false; + }); + } + + /// Called when user taps `Update` button + Future _updateProfile() async { + setState(() { + _loading = true; + }); + final userName = _usernameController.text; + final website = _websiteController.text; + final user = supabase.auth.currentUser; + final updates = { + 'id': user!.id, + 'username': userName, + 'website': website, + 'updated_at': DateTime.now().toIso8601String(), + }; + final response = await supabase.from('profiles').upsert(updates).execute(); + final error = response.error; + if (error != null) { + context.showErrorSnackBar(message: error.message); + } else { + context.showSnackBar(message: 'Successfully updated profile!'); + } + setState(() { + _loading = false; + }); + } + + Future _signOut() async { + final response = await supabase.auth.signOut(); + final error = response.error; + if (error != null) { + context.showErrorSnackBar(message: error.message); + } + Navigator.of(context).pushReplacementNamed('/login'); + } + + /// Called when image has been uploaded to Supabase storage from within Avatar widget + Future _onUpload(String imageUrl) async { + final response = await supabase.from('profiles').upsert({ + 'id': _userId, + 'avatar_url': imageUrl, + }).execute(); + final error = response.error; + if (error != null) { + context.showErrorSnackBar(message: error.message); + } + setState(() { + _avatarUrl = imageUrl; + }); + context.showSnackBar(message: 'Updated your profile image!'); + } + + @override + void onAuthenticated(Session session) { + final user = session.user; + if (user != null) { + _userId = user.id; + _getProfile(user.id); + } + } + + @override + void onUnauthenticated() { + Navigator.of(context).pushReplacementNamed('/login'); + } + + @override + void dispose() { + _usernameController.dispose(); + _websiteController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: const Text('Profile')), + body: ListView( + padding: const EdgeInsets.symmetric(vertical: 18, horizontal: 12), + children: [ + Avatar( + imageUrl: _avatarUrl, + onUpload: _onUpload, + ), + const SizedBox(height: 18), + TextFormField( + controller: _usernameController, + decoration: const InputDecoration(labelText: 'User Name'), + ), + const SizedBox(height: 18), + TextFormField( + controller: _websiteController, + decoration: const InputDecoration(labelText: 'Website'), + ), + const SizedBox(height: 18), + ElevatedButton( + onPressed: _updateProfile, + child: Text(_loading ? 'Saving...' : 'Update')), + const SizedBox(height: 18), + ElevatedButton(onPressed: _signOut, child: const Text('Sign Out')), + ], + ), + ); + } +} +``` + +Congratulations, that is it! You have now built a fully functional user management app using Flutter and Supabase! + +## Next steps + +At this stage you have a fully functional application! + +- Got a question? [Ask here](https://github.com/supabase/supabase/discussions). +- Sign in: [app.supabase.io](https://app.supabase.io) diff --git a/apps/temp-docs/docs/guides/with-nextjs.mdx b/apps/temp-docs/docs/guides/with-nextjs.mdx new file mode 100644 index 00000000000..c674fa00271 --- /dev/null +++ b/apps/temp-docs/docs/guides/with-nextjs.mdx @@ -0,0 +1,540 @@ +--- +id: with-nextjs +title: 'Quickstart: Next.js' +description: Learn how to use Supabase in your Next App. +--- + +# Quickstart: Next.js + +import Tabs from '@theme/Tabs' +import TabsPanel from '@theme/TabsPanel' + +## Intro + +This example provides the steps to build a simple user management app (from scratch!) using Supabase and Next.js. It includes: + +- Supabase [Database](/docs/guides/database): a Postgres database for storing your user data. +- Supabase [Auth](/docs/guides/auth): users can sign in with magic links (no passwords, only email). +- Supabase [Storage](/docs/guides/storage): users can upload a photo. +- [Row Level Security](/docs/guides/auth#row-level-security): data is protected so that individuals can only access their own data. +- Instant [APIs](/docs/guides/api): APIs will be automatically generated when you create your database tables. + +By the end of this guide you'll have an app which allows users to login and update some basic profile details: + +![Supabase User Management example](/docs/img/user-management-demo.png) + + + +## Project set up + +Before we start building we're going to set up our Database and API. This is as simple as starting a new Project in Supabase +and then creating a "schema" inside the database. + +### Create a project + +1. Go to [app.supabase.io](https://app.supabase.io). +1. Click on "New Project". +1. Enter your project details. +1. Wait for the new database to launch. + +### Set up the database schema + +Now we are going to set up the database schema. We can use the "User Management Starter" quickstart in the SQL Editor, +or you can just copy/paste the SQL from below and run it yourself. + + + + +```sh +1. Go to the "SQL" section. +2. Click "User Management Starter". +3. Click "Run". +``` + + + + + + +```sql +-- Create a table for public "profiles" +create table profiles ( + id uuid references auth.users not null, + updated_at timestamp with time zone, + username text unique, + avatar_url text, + website text, + + primary key (id), + unique(username), + constraint username_length check (char_length(username) >= 3) +); + +alter table profiles enable row level security; + +create policy "Public profiles are viewable by everyone." + on profiles for select + using ( true ); + +create policy "Users can insert their own profile." + on profiles for insert + with check ( auth.uid() = id ); + +create policy "Users can update own profile." + on profiles for update + using ( auth.uid() = id ); + +-- Set up Realtime! +begin; + drop publication if exists supabase_realtime; + create publication supabase_realtime; +commit; +alter publication supabase_realtime add table profiles; + +-- Set up Storage! +insert into storage.buckets (id, name) +values ('avatars', 'avatars'); + +create policy "Avatar images are publicly accessible." + on storage.objects for select + using ( bucket_id = 'avatars' ); + +create policy "Anyone can upload an avatar." + on storage.objects for insert + with check ( bucket_id = 'avatars' ); + +``` + + + + +### Get the API Keys + +Now that you've created some database tables, you are ready to insert data using the auto-generated API. +We just need to get the URL and `anon` key from the API settings. + + + + +```sh +1. Go to the "Settings" section. +2. Click "API" in the sidebar. +3. Find your API URL in this page. +4. Find your "anon" and "service_role" keys on this page. +``` + + + + + + +## Building the App + +Let's start building the Next.js app from scratch. + +### Initialize a Next.js app + +We can use [`create-next-app`](https://nextjs.org/docs/getting-started) to initialize +an app called `supabase-nextjs`: + +```bash +npx create-next-app supabase-nextjs +cd supabase-nextjs +``` + +Then let's install the only additional dependency: [supabase-js](https://github.com/supabase/supabase-js) + +```bash +npm install @supabase/supabase-js +``` + +And finally we want to save the environment variables in a `.env.local`. +All we need are the API URL and the `anon` key that you copied [earlier](#get-the-api-keys). + +```bash title=".env.local" +NEXT_PUBLIC_SUPABASE_URL=YOUR_SUPABASE_URL +NEXT_PUBLIC_SUPABASE_ANON_KEY=YOUR_SUPABASE_ANON_KEY +``` + +Now that we have the API credentials in place, let's create a helper file to initialize the Supabase client. +These variables will be exposed on the browser, and that's completely fine since we have +[Row Level Security](/docs/guides/auth#row-level-security) enabled on our Database. + +```js title="utils/supabaseClient.js" +import { createClient } from '@supabase/supabase-js' + +const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL +const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY + +export const supabase = createClient(supabaseUrl, supabaseAnonKey) +``` + +And one optional step is to update the CSS file `styles/globals.css` to make the app look nice. +You can find the full contents of this file [here](https://raw.githubusercontent.com/supabase/supabase/master/examples/react-user-management/src/index.css). + +### Set up a Login component + +Let's set up a React component to manage logins and sign ups. +We'll use Magic Links, so users can sign in with their email without using passwords. + +```jsx title="components/Auth.js" +import { useState } from 'react' +import { supabase } from '../utils/supabaseClient' + +export default function Auth() { + const [loading, setLoading] = useState(false) + const [email, setEmail] = useState('') + + const handleLogin = async (email) => { + try { + setLoading(true) + const { error } = await supabase.auth.signIn({ email }) + if (error) throw error + alert('Check your email for the login link!') + } catch (error) { + alert(error.error_description || error.message) + } finally { + setLoading(false) + } + } + + return ( +
    +
    +

    Supabase + Next.js

    +

    Sign in via magic link with your email below

    +
    + setEmail(e.target.value)} + /> +
    +
    + +
    +
    +
    + ) +} +``` + +### Account page + +After a user is signed in we can allow them to edit their profile details and manage their account. + +Let's create a new component for that called `Account.js`. + +```jsx title="components/Account.js" +import { useState, useEffect } from 'react' +import { supabase } from '../utils/supabaseClient' + +export default function Account({ session }) { + const [loading, setLoading] = useState(true) + const [username, setUsername] = useState(null) + const [website, setWebsite] = useState(null) + const [avatar_url, setAvatarUrl] = useState(null) + + useEffect(() => { + getProfile() + }, [session]) + + async function getProfile() { + try { + setLoading(true) + const user = supabase.auth.user() + + let { data, error, status } = await supabase + .from('profiles') + .select(`username, website, avatar_url`) + .eq('id', user.id) + .single() + + if (error && status !== 406) { + throw error + } + + if (data) { + setUsername(data.username) + setWebsite(data.website) + setAvatarUrl(data.avatar_url) + } + } catch (error) { + alert(error.message) + } finally { + setLoading(false) + } + } + + async function updateProfile({ username, website, avatar_url }) { + try { + setLoading(true) + const user = supabase.auth.user() + + const updates = { + id: user.id, + username, + website, + avatar_url, + updated_at: new Date(), + } + + let { error } = await supabase.from('profiles').upsert(updates, { + returning: 'minimal', // Don't return the value after inserting + }) + + if (error) { + throw error + } + } catch (error) { + alert(error.message) + } finally { + setLoading(false) + } + } + + return ( +
    +
    + + +
    +
    + + setUsername(e.target.value)} + /> +
    +
    + + setWebsite(e.target.value)} + /> +
    + +
    + +
    + +
    + +
    +
    + ) +} +``` + +### Launch! + +Now that we have all the components in place, let's update `pages/index.js`: + +```jsx title="pages/index.js" +import { useState, useEffect } from 'react' +import { supabase } from '../utils/supabaseClient' +import Auth from '../components/Auth' +import Account from '../components/Account' + +export default function Home() { + const [session, setSession] = useState(null) + + useEffect(() => { + setSession(supabase.auth.session()) + + supabase.auth.onAuthStateChange((_event, session) => { + setSession(session) + }) + }, []) + + return ( +
    + {!session ? : } +
    + ) +} +``` + +Once that's done, run this in a terminal window: + +```bash +npm run dev +``` + +And then open the browser to [localhost:3000](http://localhost:3000) and you should see the completed app. + +![Supabase User demo](/docs/img/supabase-react-demo.png) + +## Bonus: Profile photos + +Every Supabase project is configured with [Storage](/docs/guides/storage) for managing large files like +photos and videos. + +### Create an upload widget + +Let's create an avatar for the user so that they can upload a profile photo. +We can start by creating a new component: + +```jsx title="components/Avatar.js" +import { useEffect, useState } from 'react' +import { supabase } from '../utils/supabaseClient' + +export default function Avatar({ url, size, onUpload }) { + const [avatarUrl, setAvatarUrl] = useState(null) + const [uploading, setUploading] = useState(false) + + useEffect(() => { + if (url) downloadImage(url) + }, [url]) + + async function downloadImage(path) { + try { + const { data, error } = await supabase.storage.from('avatars').download(path) + if (error) { + throw error + } + const url = URL.createObjectURL(data) + setAvatarUrl(url) + } catch (error) { + console.log('Error downloading image: ', error.message) + } + } + + async function uploadAvatar(event) { + try { + setUploading(true) + + if (!event.target.files || event.target.files.length === 0) { + throw new Error('You must select an image to upload.') + } + + const file = event.target.files[0] + const fileExt = file.name.split('.').pop() + const fileName = `${Math.random()}.${fileExt}` + const filePath = `${fileName}` + + let { error: uploadError } = await supabase.storage.from('avatars').upload(filePath, file) + + if (uploadError) { + throw uploadError + } + + onUpload(filePath) + } catch (error) { + alert(error.message) + } finally { + setUploading(false) + } + } + + return ( +
    + {avatarUrl ? ( + Avatar + ) : ( +
    + )} +
    + + +
    +
    + ) +} +``` + +### Add the new widget + +And then we can add the widget to the Account page: + +```jsx title="components/Account.js" +// Import the new component +import Avatar from './Avatar' + +// ... + +return ( +
    + {/* Add to the body */} + { + setAvatarUrl(url) + updateProfile({ username, website, avatar_url: url }) + }} + /> + {/* ... */} +
    +) +``` + +## Next steps + +At this stage you have a fully functional application! + +- Got a question? [Ask here](https://github.com/supabase/supabase/discussions). +- Sign in: [app.supabase.io](https://app.supabase.io) diff --git a/apps/temp-docs/docs/guides/with-react.mdx b/apps/temp-docs/docs/guides/with-react.mdx new file mode 100644 index 00000000000..4ae6698de3e --- /dev/null +++ b/apps/temp-docs/docs/guides/with-react.mdx @@ -0,0 +1,547 @@ +--- +id: with-react +title: 'Quickstart: React' +description: Learn how to use Supabase in your React App. +--- + +# Quickstart: React + +## Intro + +This example provides the steps to build a simple user management app (from scratch!) using Supabase and React. It includes: + +- Supabase [Database](/docs/guides/database): a Postgres database for storing your user data. +- Supabase [Auth](/docs/guides/auth): users can sign in with magic links (no passwords, only email). +- Supabase [Storage](/docs/guides/storage): users can upload a photo. +- [Row Level Security](/docs/guides/auth#row-level-security): data is protected so that individuals can only access their own data. +- Instant [APIs](/docs/guides/api): APIs will be automatically generated when you create your database tables. + +By the end of this guide you'll have an app which allows users to login and update some basic profile details: + +![Supabase User Management example](/docs/img/user-management-demo.png) + + + +## Project set up + +Before we start building we're going to set up our Database and API. This is as simple as starting a new Project in Supabase +and then creating a "schema" inside the database. + +### Create a project + +1. Go to [app.supabase.io](https://app.supabase.io). +1. Click on "New Project". +1. Enter your project details. +1. Wait for the new database to launch. + +### Set up the database schema + +Now we are going to set up the database schema. We can use the "User Management Starter" quickstart in the SQL Editor, +or you can just copy/paste the SQL from below and run it yourself. + + + + +```sh +1. Go to the "SQL" section. +2. Click "User Management Starter". +3. Click "Run". +``` + + + + + +```sql +-- Create a table for public "profiles" +create table profiles ( + id uuid references auth.users not null, + updated_at timestamp with time zone, + username text unique, + avatar_url text, + website text, + + primary key (id), + unique(username), + constraint username_length check (char_length(username) >= 3) +); + +alter table profiles enable row level security; + +create policy "Public profiles are viewable by everyone." + on profiles for select + using ( true ); + +create policy "Users can insert their own profile." + on profiles for insert + with check ( auth.uid() = id ); + +create policy "Users can update own profile." + on profiles for update + using ( auth.uid() = id ); + +-- Set up Realtime! +begin; + drop publication if exists supabase_realtime; + create publication supabase_realtime; +commit; +alter publication supabase_realtime add table profiles; + +-- Set up Storage! +insert into storage.buckets (id, name) +values ('avatars', 'avatars'); + +create policy "Avatar images are publicly accessible." + on storage.objects for select + using ( bucket_id = 'avatars' ); + +create policy "Anyone can upload an avatar." + on storage.objects for insert + with check ( bucket_id = 'avatars' ); + +``` + + + + +### Get the API Keys + +Now that you've created some database tables, you are ready to insert data using the auto-generated API. +We just need to get the URL and `anon` key from the API settings. + + + + +```sh +1. Go to the "Settings" section. +2. Click "API" in the sidebar. +3. Find your API URL in this page. +4. Find your "anon" and "service_role" keys on this page. +``` + + + + + + +```sh +1. Go to the "Settings" section. +2. Click "API" in the sidebar. +3. Find your API URL in this page. +4. Find your "anon" and "service_role" keys on this page. +``` + + + + + + +## Building the App + +Let's start building the React app from scratch. + +### Initialize a React app + +We can use [Create React App](https://create-react-app.dev/docs/getting-started/) to initialize +an app called `supabase-react`: + +```bash +npx create-react-app supabase-react --use-npm +cd supabase-react +``` + +Then let's install the only additional dependency: [supabase-js](https://github.com/supabase/supabase-js) + +```bash +npm install @supabase/supabase-js +``` + +And finally we want to save the environment variables in a `.env`. +All we need are the API URL and the `anon` key that you copied [earlier](#get-the-api-keys). + +```bash title=".env" +REACT_APP_SUPABASE_URL=YOUR_SUPABASE_URL +REACT_APP_SUPABASE_ANON_KEY=YOUR_SUPABASE_ANON_KEY +``` + +Now that we have the API credentials in place, let's create a helper file to initialize the Supabase client. These variables will be exposed +on the browser, and that's completely fine since we have [Row Level Security](/docs/guides/auth#row-level-security) enabled on our Database. + +```js title="src/supabaseClient.js" +import { createClient } from '@supabase/supabase-js' + +const supabaseUrl = process.env.REACT_APP_SUPABASE_URL +const supabaseAnonKey = process.env.REACT_APP_SUPABASE_ANON_KEY + +export const supabase = createClient(supabaseUrl, supabaseAnonKey) +``` + +And one optional step is to update the CSS file `src/index.css` to make the app look nice. +You can find the full contents of this file [here](https://raw.githubusercontent.com/supabase/supabase/master/examples/react-user-management/src/index.css). + +### Set up a Login component + +Let's set up a React component to manage logins and sign ups. We'll use Magic Links, so users can sign in with their email without using passwords. + +```jsx title="/src/Auth.js" +import { useState } from 'react' +import { supabase } from './supabaseClient' + +export default function Auth() { + const [loading, setLoading] = useState(false) + const [email, setEmail] = useState('') + + const handleLogin = async (email) => { + try { + setLoading(true) + const { error } = await supabase.auth.signIn({ email }) + if (error) throw error + alert('Check your email for the login link!') + } catch (error) { + alert(error.error_description || error.message) + } finally { + setLoading(false) + } + } + + return ( +
    +
    +

    Supabase + React

    +

    Sign in via magic link with your email below

    +
    + setEmail(e.target.value)} + /> +
    +
    + +
    +
    +
    + ) +} +``` + +### Account page + +After a user is signed in we can allow them to edit their profile details and manage their account. + +Let's create a new component for that called `Account.js`. + +```jsx title="src/Account.js" +import { useState, useEffect } from 'react' +import { supabase } from './supabaseClient' + +export default function Account({ session }) { + const [loading, setLoading] = useState(true) + const [username, setUsername] = useState(null) + const [website, setWebsite] = useState(null) + const [avatar_url, setAvatarUrl] = useState(null) + + useEffect(() => { + getProfile() + }, [session]) + + async function getProfile() { + try { + setLoading(true) + const user = supabase.auth.user() + + let { data, error, status } = await supabase + .from('profiles') + .select(`username, website, avatar_url`) + .eq('id', user.id) + .single() + + if (error && status !== 406) { + throw error + } + + if (data) { + setUsername(data.username) + setWebsite(data.website) + setAvatarUrl(data.avatar_url) + } + } catch (error) { + alert(error.message) + } finally { + setLoading(false) + } + } + + async function updateProfile({ username, website, avatar_url }) { + try { + setLoading(true) + const user = supabase.auth.user() + + const updates = { + id: user.id, + username, + website, + avatar_url, + updated_at: new Date(), + } + + let { error } = await supabase.from('profiles').upsert(updates, { + returning: 'minimal', // Don't return the value after inserting + }) + + if (error) { + throw error + } + } catch (error) { + alert(error.message) + } finally { + setLoading(false) + } + } + + return ( +
    +
    + + +
    +
    + + setUsername(e.target.value)} + /> +
    +
    + + setWebsite(e.target.value)} + /> +
    + +
    + +
    + +
    + +
    +
    + ) +} +``` + +### Launch! + +Now that we have all the components in place, let's update `App.js`: + +```jsx title="src/App.js" +import './index.css' +import { useState, useEffect } from 'react' +import { supabase } from './supabaseClient' +import Auth from './Auth' +import Account from './Account' + +export default function Home() { + const [session, setSession] = useState(null) + + useEffect(() => { + setSession(supabase.auth.session()) + + supabase.auth.onAuthStateChange((_event, session) => { + setSession(session) + }) + }, []) + + return ( +
    + {!session ? : } +
    + ) +} +``` + +Once that's done, run this in a terminal window: + +```bash +npm start +``` + +And then open the browser to [localhost:3000](http://localhost:3000) and you should see the completed app. + +![Supabase React](/docs/img/supabase-react-demo.png) + +## Bonus: Profile photos + +Every Supabase project is configured with [Storage](/docs/guides/storage) for managing large files like photos and videos. + +### Create an upload widget + +Let's create an avatar for the user so that they can upload a profile photo. We can start by creating a new component: + +```jsx title="src/Avatar.js" +import { useEffect, useState } from 'react' +import { supabase } from './supabaseClient' + +export default function Avatar({ url, size, onUpload }) { + const [avatarUrl, setAvatarUrl] = useState(null) + const [uploading, setUploading] = useState(false) + + useEffect(() => { + if (url) downloadImage(url) + }, [url]) + + async function downloadImage(path) { + try { + const { data, error } = await supabase.storage.from('avatars').download(path) + if (error) { + throw error + } + const url = URL.createObjectURL(data) + setAvatarUrl(url) + } catch (error) { + console.log('Error downloading image: ', error.message) + } + } + + async function uploadAvatar(event) { + try { + setUploading(true) + + if (!event.target.files || event.target.files.length === 0) { + throw new Error('You must select an image to upload.') + } + + const file = event.target.files[0] + const fileExt = file.name.split('.').pop() + const fileName = `${Math.random()}.${fileExt}` + const filePath = `${fileName}` + + let { error: uploadError } = await supabase.storage.from('avatars').upload(filePath, file) + + if (uploadError) { + throw uploadError + } + + onUpload(filePath) + } catch (error) { + alert(error.message) + } finally { + setUploading(false) + } + } + + return ( +
    + {avatarUrl ? ( + Avatar + ) : ( +
    + )} +
    + + +
    +
    + ) +} +``` + +### Add the new widget + +And then we can add the widget to the Account page: + +```jsx title="src/Account.js" +// Import the new component +import Avatar from './Avatar' + +// ... + +return ( +
    + {/* Add to the body */} + { + setAvatarUrl(url) + updateProfile({ username, website, avatar_url: url }) + }} + /> + {/* ... */} +
    +) +``` + +## Next steps + +At this stage you have a fully functional application! + +- Got a question? [Ask here](https://github.com/supabase/supabase/discussions). +- Sign in: [app.supabase.io](https://app.supabase.io) diff --git a/apps/temp-docs/docs/guides/with-redwoodjs.mdx b/apps/temp-docs/docs/guides/with-redwoodjs.mdx new file mode 100644 index 00000000000..8e9f36fdd03 --- /dev/null +++ b/apps/temp-docs/docs/guides/with-redwoodjs.mdx @@ -0,0 +1,773 @@ +--- +id: with-redwoodjs +title: 'Quickstart: RedwoodJS' +description: Learn how to use Supabase in your RedwoodJS App. +--- + +# Quickstart: RedwoodJS + +import Tabs from '@theme/Tabs' +import TabsPanel from '@theme/TabsPanel' + +## Intro + +For the sake of consistency with the other framework Quickstart examples, we'll build a RedwoodJS a little differently than normal. + +We **_won't use_** Prisma to connect to the Supabase Postgres database or [Prisma migrations](https://redwoodjs.com/docs/cli-commands#prisma-migrate) as one typically might in a Redwood app. +Instead, we'll rely on the Supabase client to do some of the work on the **web** side and use the client again on the **API** side to do data fetching as well. + +That means you will want to refrain from running any `yarn rw prisma migrate` commands and also double check your build commands on deployment to ensure Prisma won't reset your database. + +:::note +TLDR; Prisma currently doesn't support cross-schema foreign keys, so introspecting the schema fails due to how your Supabase `public` schema references the `auth.users`. +::: + +This example provides the steps to build a simple user management app (from scratch!) using Supabase and [RedwoodJS](https://redwoodjs.com/docs/introduction). It includes: + +- Supabase [Database](/docs/guides/database): a Postgres database for storing your user data. +- Supabase [Auth](/docs/guides/auth): users can sign in with magic links (no passwords, only email). +- Supabase [Storage](/docs/guides/storage): users can upload a photo. +- Instant [APIs](/docs/guides/api): APIs will be automatically generated when you create your database tables. +- [Row Level Security](/docs/guides/auth#row-level-security): data is protected so that individuals can only access their own data. + +By the end of this guide you'll have an app which allows users to login and update some basic profile details: + +![Supabase User Management example](/docs/img/user-management-demo.png) + +:::note +Note: For RedwoodJS apps, port will be 8910 +::: + +### Github + +If you get stuck at any point, take a look at [this repo](https://github.com/dthyresson/redwoodjs-supabase-quickstart). + + + +## About RedwoodJS + +A Redwood application is split into two parts: a frontend and a backend. This is represented as two node projects within a single monorepo. + +The frontend project is called **`web`** and the backend project is called **`api`**. For clarity, we will refer to these in prose as **"sides"**, i.e. the "web side" and the "api side". +They are separate projects because code on the `web side` will end up running in the user's browser while code on the `api side` will run on a server somewhere. + +:::note +Important: When this guide refers to "API", that means the Supabase API and when it refers to "api side", that means the RedwoodJS `api side`. +::: + +The **`api side`** is an implementation of a GraphQL API. The business logic is organized into "services" that represent their own internal API and can be called both from external GraphQL requests and other internal services. + +The **`web side`** is built with React. Redwood's router makes it simple to map URL paths to React "Page" components (and automatically code-split your app on each route). +Pages may contain a "Layout" component to wrap content. They also contain "Cells" and regular React components. +Cells allow you to declaratively manage the lifecycle of a component that fetches and displays data. + +:::note +For the sake of consistency with the other framework Quickstart examples, we'll build a RedwoodJS a little differently than normal. +We **_won't use_** Prisma to connect to the Supabase Postgres database or [Prisma migrations](https://redwoodjs.com/docs/cli-commands#prisma-migrate) as one typically might in a Redwood app. +Instead, we'll rely on the Supabase client to do some of the work on the **`web`** side and use the client again on the **`api`** side to do data fetching as well. +::: + +## Project set up + +Before we start building we're going to set up our Database and API. This is as simple as starting a new Project in Supabase +and then creating a "schema" inside the database. + +:::note +When setting up Supabase, you'll interact with your project dashboard. However, most of the RedwoodJS setup steps will interact with the [Redwood CLI](https://redwoodjs.com/docs/cli-commands) to generate routes, pages, components, and more. +So be sure to have a terminal at the ready and in your project directory. +::: + +### Create a project + +1. Go to [app.supabase.io](https://app.supabase.io). +1. Click on "New Project". +1. Enter your project details. +1. Wait for the new database to launch. + +### Set up the database schema + +Now we are going to set up the database schema. We can use the "User Management Starter" quickstart in the SQL Editor, +or you can just copy/paste the SQL from below and run it yourself. + + + + +```sh +1. Go to the "SQL" section. +2. Click "User Management Starter". +4. Click "Run". +``` + + + + + + +```sql +-- Create a table for public "profiles" +create table profiles ( + id uuid references auth.users not null, + updated_at timestamp with time zone, + username text unique, + avatar_url text, + website text, + + primary key (id), + unique(username), + constraint username_length check (char_length(username) >= 3) +); + +alter table profiles enable row level security; + +create policy "Public profiles are viewable by everyone." + on profiles for select + using ( true ); + +create policy "Users can insert their own profile." + on profiles for insert + with check ( auth.uid() = id ); + +create policy "Users can update own profile." + on profiles for update + using ( auth.uid() = id ); + +-- Set up Realtime! +begin; + drop publication if exists supabase_realtime; + create publication supabase_realtime; +commit; +alter publication supabase_realtime add table profiles; + +-- Set up Storage! +insert into storage.buckets (id, name) +values ('avatars', 'avatars'); + +create policy "Avatar images are publicly accessible." + on storage.objects for select + using ( bucket_id = 'avatars' ); + +create policy "Anyone can upload an avatar." + on storage.objects for insert + with check ( bucket_id = 'avatars' ); + +``` + + + + +#### Important Note about Prisma and Migrations + +:::note +Because this Quick Start does not use Prisma to manage the database schema, seed it, or run migrations, you **need** to take extra care when running some of the typical Redwood CLI commands. +::: + +### Get the API Keys + +Now that you've created some database tables, you are ready to insert data using the auto-generated API. +We just need to get the URL as well as the `anon`, `service_role` and `JWT_SECRET` keys from the API settings. + + + + +```sh +1. Go to the "Settings" section. +2. Click "API" in the sidebar. +3. Find your API URL in this page. +4. Find your "anon" and "JWT Secret" keys on this page. +``` + + + + + + +## Building the App + +Let's start building the RedwoodJS app from scratch. + +:::note +RedwoodJS requires Node.js (>=14.x <=16.x) and Yarn (>=1.15). +::: + +Make sure you have installed yarn since RedwoodJS relies on it to [manage its packages in workspaces](https://classic.yarnpkg.com/lang/en/docs/workspaces/) for its `web` and `api` "sides". + +### Initialize a RedwoodJS app + +We can use [Create Redwood App](https://redwoodjs.com/docs/quick-start) command to initialize +an app called `supabase-redwoodjs`: + +```bash +yarn create redwood-app supabase-redwoodjs +cd supabase-redwoodjs +``` + +While the app is installing, you should see: + +```bash +✔ Creating Redwood app + ✔ Checking node and yarn compatibility + ✔ Creating directory 'supabase-redwoodjs' +✔ Installing packages + ✔ Running 'yarn install'... (This could take a while) +✔ Convert TypeScript files to JavaScript +✔ Generating types + +Thanks for trying out Redwood! +``` + +Then let's install the only additional dependency [supabase-js](https://github.com/supabase/supabase-js) by running the `setup auth` command: + +```bash +yarn redwood setup auth supabase +``` + +When prompted: + +Overwrite existing /api/src/lib/auth.[jt]s? +::: + +Say, **yes** and it will setup the Supabase client in your app and also provide hooks used with Supabase authentication. + +```bash +✔ Generating auth lib... + ✔ Successfully wrote file `./api/src/lib/auth.js` + ✔ Adding auth config to web... + ✔ Adding auth config to GraphQL API... + ✔ Adding required web packages... + ✔ Installing packages... + ✔ One more thing... + + You will need to add your Supabase URL (SUPABASE_URL), public API KEY, + and JWT SECRET (SUPABASE_KEY, and SUPABASE_JWT_SECRET) to your .env file. +``` + +Next, we want to save the environment variables in a `.env`. +We need the `API URL` as well as the `anon` and `jwt_secret` keys that you copied [earlier](#get-the-api-keys). + +```bash title=".env" +SUPABASE_URL=YOUR_SUPABASE_URL +SUPABASE_KEY=YOUR_SUPABASE_ANON_KEY +SUPABASE_JWT_SECRET=YOUR_SUPABASE_JWT_SECRET +``` + +And finally, you will also need to save **just** the `web side` environment variables to the `redwood.toml`. + +```bash title="redwood.toml" +[web] + title = "Supabase Redwood Quickstart" + port = 8910 + apiProxyPath = "/.redwood/functions" + includeEnvironmentVariables = ["SUPABASE_URL", "SUPABASE_KEY"] +[api] + port = 8911 +[browser] + open = true +``` + +These variables will be exposed on the browser, and that's completely fine. +They allow your web app to initialize the Supabase client with your public anon key +since we have [Row Level Security](/docs/guides/auth#row-level-security) enabled on our Database. + +You'll see these being used to configure your Supabase client in `web/src/App.js`: + +```js title="web/src/App.js" +// ... Redwood imports +import { AuthProvider } from '@redwoodjs/auth' +import { createClient } from '@supabase/supabase-js' + +// ... + +const supabaseClient = createClient(process.env.SUPABASE_URL, process.env.SUPABASE_KEY) + +const App = () => ( + + + + + + + + + +) + +export default App +``` + +And one optional step is to update the CSS file `web/src/index.css` to make the app look nice. +You can find the full contents of this file [here](https://raw.githubusercontent.com/supabase/supabase/master/examples/react-user-management/src/index.css). + +### Start RedwoodJS and your first Page + +Let's test our setup at the moment by starting up the app: + +```bash +yarn rw dev +``` + +:::note +Note: You can also use the alias `rw` for `redwood`, as in `yarn rw` to run Redwood CLI commands +::: + +You should see a "Welcome to RedwoodJS" page and a message about not having any pages yet. + +So, let's create a "home" page: + +```bash +yarn rw generate page home / + +✔ Generating page files... + ✔ Successfully wrote file `./web/src/pages/HomePage/HomePage.stories.js` + ✔ Successfully wrote file `./web/src/pages/HomePage/HomePage.test.js` + ✔ Successfully wrote file `./web/src/pages/HomePage/HomePage.js` +✔ Updating routes file... +✔ Generating types ... +``` + +:::note +Note: the slash `/` is important here as it creates a root level route. +::: + +You can stop the `dev` server if you want; to see your changes, just be sure to run `yarn rw dev` again. + +You should see the `Home` page route in `web/src/Routes.js`: + +```bash title="web/src/Routes.js" +import { Router, Route } from '@redwoodjs/router' + +const Routes = () => { + return ( + + + + + ) +} + +export default Routes +``` + +### Set up a Login component + +Let's set up a Redwood component to manage logins and sign ups. We'll use Magic Links, so users can sign in with their email without using passwords. + +```bash +yarn rw g component auth + + ✔ Generating component files... + ✔ Successfully wrote file `./web/src/components/Auth/Auth.test.js` + ✔ Successfully wrote file `./web/src/components/Auth/Auth.stories.js` + ✔ Successfully wrote file `./web/src/components/Auth/Auth.js` + +``` + +Now, update the `Auth.js` component to contain: + +```jsx title="/web/src/components/Auth/Auth.js" +import { useState } from 'react' +import { useAuth } from '@redwoodjs/auth' + +const Auth = () => { + const { logIn } = useAuth() + const [loading, setLoading] = useState(false) + const [email, setEmail] = useState('') + + const handleLogin = async (email) => { + try { + setLoading(true) + const { error } = await logIn({ email }) + if (error) throw error + alert('Check your email for the login link!') + } catch (error) { + alert(error.error_description || error.message) + } finally { + setLoading(false) + } + } + + return ( +
    +
    +

    Supabase + RedwoodJS

    +

    Sign in via magic link with your email below

    +
    + setEmail(e.target.value)} + /> +
    +
    + +
    +
    +
    + ) +} + +export default Auth +``` + +### Set up an Account component + +After a user is signed in we can allow them to edit their profile details and manage their account. + +Let's create a new component for that called `Account.js`. + +```bash +yarn rw g component account + + ✔ Generating component files... + ✔ Successfully wrote file `./web/src/components/Account/Account.test.js` + ✔ Successfully wrote file `./web/src/components/Account/Account.stories.js` + ✔ Successfully wrote file `./web/src/components/Account/Account.js` +``` + +And then update the file to contain: + +```jsx title="web/src/components/Account/Account.js" +import { useState, useEffect } from 'react' +import { useAuth } from '@redwoodjs/auth' + +const Account = () => { + const { client: supabase, currentUser, logOut } = useAuth() + const [loading, setLoading] = useState(true) + const [username, setUsername] = useState(null) + const [website, setWebsite] = useState(null) + const [avatar_url, setAvatarUrl] = useState(null) + + useEffect(() => { + getProfile() + }, [supabase.auth.session]) + + async function getProfile() { + try { + setLoading(true) + const user = supabase.auth.user() + + let { data, error, status } = await supabase + .from('profiles') + .select(`username, website, avatar_url`) + .eq('id', user.id) + .single() + + if (error && status !== 406) { + throw error + } + + if (data) { + setUsername(data.username) + setWebsite(data.website) + setAvatarUrl(data.avatar_url) + } + } catch (error) { + alert(error.message) + } finally { + setLoading(false) + } + } + + async function updateProfile({ username, website, avatar_url }) { + try { + setLoading(true) + const user = supabase.auth.user() + + const updates = { + id: user.id, + username, + website, + avatar_url, + updated_at: new Date(), + } + + let { error } = await supabase.from('profiles').upsert(updates, { + returning: 'minimal', // Don't return the value after inserting + }) + + if (error) { + throw error + } + + alert('Updated profile!') + } catch (error) { + alert(error.message) + } finally { + setLoading(false) + } + } + + return ( +
    +
    +

    Supabase + RedwoodJS

    +

    Your profile

    +
    +
    + + +
    +
    + + setUsername(e.target.value)} + /> +
    +
    + + setWebsite(e.target.value)} + /> +
    + +
    + +
    + +
    + +
    +
    +
    +
    + ) +} + +export default Account +``` + +:::note +Note: You'll see the use of `useAuth()` several times in the quickstart. Redwood's `useAuth` hook provides convenient ways to access +logIn, logOut, currentUser, and access the `supabase` authenticate client. We'll use it to get an instance +of the supabase client to interact with your API. +::: + +### Update Home Page + +Now that we have all the components in place, let's update your `HomePage` page to use them: + +```jsx title="web/src/pages/HomePage/HomePage.js" +import { useAuth } from '@redwoodjs/auth' +import { MetaTags } from '@redwoodjs/web' + +import Account from 'src/components/Account' +import Auth from 'src/components/Auth' + +const HomePage = () => { + const { isAuthenticated } = useAuth() + + return ( + <> + + {!isAuthenticated ? : } + + ) +} + +export default HomePage +``` + +> What we're doing here is showing the sign in form if you aren't logged in and your account profile if you are. + +### Launch! + +Once that's done, run this in a terminal window to launch the `dev` server: + +```bash +yarn rw dev +``` + +And then open the browser to [localhost:8910](http://localhost:8910) and you should see the completed app. + +![Supabase RedwoodJS](/docs/img/supabase-redwoodjs-demo.png) + +## Bonus: Profile photos + +Every Supabase project is configured with [Storage](/docs/guides/storage) for managing large files like photos and videos. + +### Create an upload widget + +Let's create an avatar for the user so that they can upload a profile photo. We can start by creating a new component: + +```bash +yarn rw g component avatar + ✔ Generating component files... + ✔ Successfully wrote file `./web/src/components/Avatar/Avatar.test.js` + ✔ Successfully wrote file `./web/src/components/Avatar/Avatar.stories.js` + ✔ Successfully wrote file `./web/src/components/Avatar/Avatar.js` +``` + +Now, update your Avatar component to contain the following widget: + +```jsx title="web/src/components/Avatar/Avatar.js" +import { useEffect, useState } from 'react' +import { useAuth } from '@redwoodjs/auth' + +const Avatar = ({ url, size, onUpload }) => { + const { client: supabase } = useAuth() + + const [avatarUrl, setAvatarUrl] = useState(null) + const [uploading, setUploading] = useState(false) + + useEffect(() => { + if (url) downloadImage(url) + }, [url]) + + async function downloadImage(path) { + try { + const { data, error } = await supabase.storage.from('avatars').download(path) + if (error) { + throw error + } + const url = URL.createObjectURL(data) + setAvatarUrl(url) + } catch (error) { + console.log('Error downloading image: ', error.message) + } + } + + async function uploadAvatar(event) { + try { + setUploading(true) + + if (!event.target.files || event.target.files.length === 0) { + throw new Error('You must select an image to upload.') + } + + const file = event.target.files[0] + const fileExt = file.name.split('.').pop() + const fileName = `${Math.random()}.${fileExt}` + const filePath = `${fileName}` + + let { error: uploadError } = await supabase.storage.from('avatars').upload(filePath, file) + + if (uploadError) { + throw uploadError + } + + onUpload(filePath) + } catch (error) { + alert(error.message) + } finally { + setUploading(false) + } + } + + return ( +
    + {avatarUrl ? ( + Avatar + ) : ( +
    + )} +
    + + +
    +
    + ) +} + +export default Avatar +``` + +### Add the new widget + +And then we can add the widget to the Account component: + +```jsx title="web/src/components/Account/Account.js" +// Import the new component +import Avatar from 'src/components/Avatar' + +// ... + +return ( +
    + {/* Add to the body */} + { + setAvatarUrl(url) + updateProfile({ username, website, avatar_url: url }) + }} + /> + {/* ... */} +
    +) +``` + +## Next steps + +At this stage you have a fully functional application! + +- Got a question? [Ask here](https://github.com/supabase/supabase/discussions). +- Sign in: [app.supabase.io](https://app.supabase.io) +- Learn more about [RedwoodJS](https://redwoodjs.com) +- Visit the [RedwoodJS Discourse Community](https://community.redwoodjs.com) diff --git a/apps/temp-docs/docs/guides/with-svelte.mdx b/apps/temp-docs/docs/guides/with-svelte.mdx new file mode 100644 index 00000000000..19de7fdcc23 --- /dev/null +++ b/apps/temp-docs/docs/guides/with-svelte.mdx @@ -0,0 +1,525 @@ +--- +id: with-svelte +title: 'Quickstart: Svelte' +description: Learn how to use Supabase in your Svelte App. +--- + +# Quickstart: Svelte + +import Tabs from '@theme/Tabs' +import TabsPanel from '@theme/TabsPanel' + +## Intro + +This example provides the steps to build a simple user management app (from scratch!) using Supabase and Svelte. It includes: + +- Supabase [Database](/docs/guides/database): a Postgres database for storing your user data. +- Supabase [Auth](/docs/guides/auth): users can sign in with magic links (no passwords, only email). +- Supabase [Storage](/docs/guides/storage): users can upload a photo. +- [Row Level Security](/docs/guides/auth#row-level-security): data is protected so that individuals can only access their own data. +- Instant [APIs](/docs/guides/api): APIs will be automatically generated when you create your database tables. + +By the end of this guide you'll have an app which allows users to login and update some basic profile details: + +![Supabase User Management example](/docs/img/user-management-demo.png) + +### Github + +Whenever you get stuck at any point, take a look at [this repo](https://github.com/yustarandomname/svelte-supabase-quickstart). + +## Project set up + +Before we start building we're going to set up our Database and API. This is as simple as starting a new Project in Supabase +and then creating a "schema" inside the database. + +### Create a project + +1. Go to [app.supabase.io](https://app.supabase.io). +1. Click on "New Project". +1. Enter your project details. +1. Wait for the new database to launch. + +### Set up the database schema + +Now we are going to set up the database schema. We can use the "User Management Starter" quickstart in the SQL Editor, +or you can just copy/paste the SQL from below and run it yourself. + + + + +```sh +1. Go to the "SQL" section. +2. Click "User Management Starter". +3. Click "Run". +``` + + + + + + +```sql +-- Create a table for public "profiles" +create table profiles ( + id uuid references auth.users not null, + updated_at timestamp with time zone, + username text unique, + avatar_url text, + website text, + + primary key (id), + unique(username), + constraint username_length check (char_length(username) >= 3) +); + +alter table profiles enable row level security; + +create policy "Public profiles are viewable by everyone." + on profiles for select + using ( true ); + +create policy "Users can insert their own profile." + on profiles for insert + with check ( auth.uid() = id ); + +create policy "Users can update own profile." + on profiles for update + using ( auth.uid() = id ); + +-- Set up Realtime! +begin; + drop publication if exists supabase_realtime; + create publication supabase_realtime; +commit; +alter publication supabase_realtime add table profiles; + +-- Set up Storage! +insert into storage.buckets (id, name) +values ('avatars', 'avatars'); + +create policy "Avatar images are publicly accessible." + on storage.objects for select + using ( bucket_id = 'avatars' ); + +create policy "Anyone can upload an avatar." + on storage.objects for insert + with check ( bucket_id = 'avatars' ); + +``` + + + + +### Get the API Keys + +Now that you've created some database tables, you are ready to insert data using the auto-generated API. +We just need to get the URL and `anon` key from the API settings. + + + + +```sh +1. Go to the "Settings" section. +2. Click "API" in the sidebar. +3. Find your API URL in this page. +4. Find your "anon" and "service_role" keys on this page. +``` + + + + + + +## Building the App + +Let's start building the Svelte app from scratch. + +### Initialize a Svelte app + +We can use the [Quickstart Svelte Template](https://svelte.dev/blog/the-easiest-way-to-get-started) to initialize +an app called `supabase-svelte`: + +```bash +npx degit sveltejs/template supabase-svelte +cd supabase-svelte +``` + +Then let's install the only additional dependency: [supabase-js](https://github.com/supabase/supabase-js) + +```bash +npm install @supabase/supabase-js +``` + +And finally we want to save the environment variables in a `.env`. +All we need are the API URL and the `anon` key that you copied [earlier](#get-the-api-keys). + +```bash title=".env" +SVELTE_APP_SUPABASE_URL=YOUR_SUPABASE_URL +SVELTE_APP_SUPABASE_ANON_KEY=YOUR_SUPABASE_ANON_KEY +``` + +Our app is almost functional, to make svelte work with supabase and .env files we first need to change the `rollup.config.js` file a bit. +Supabase imports `json` files, to convert .json files to ES6 modules we need the `@rollup/plugin-json` install it by running: + +```bash + npm install --save-dev @rollup/plugin-json +``` + +Furthermore, to use the .env with svelte we need another rollup plugin. Install: + +```bash + npm install --save-dev dotenv @rollup/plugin-replace +``` + +and add these plugins to the `rollup.config.js` file. + +```js title="rollup.config.js" +import { config } from 'dotenv' +import replace from '@rollup/plugin-replace' +import json from '@rollup/plugin-json' + +export default { + plugins: [ + replace({ + __api: JSON.stringify({ + env: { + isProd: production, + ...config().parsed, // attached the .env config + }, + }), + delimiters: ['', ''], + }), + json(), + // ... + ], + // ... +} +``` + +Now that we have the API credentials in place, let's create a helper file to initialize the Supabase client. These variables will be exposed +on the browser, and that's completely fine since we have [Row Level Security](/docs/guides/auth#row-level-security) enabled on our Database. + +```js title="src/supabaseClient.js" +import { createClient } from '@supabase/supabase-js' + +const supabaseUrl = __api.env.SVELTE_APP_SUPABASE_URL +const supabaseAnonKey = __api.env.SVELTE_APP_SUPABASE_ANON_KEY + +export const supabase = createClient(supabaseUrl, supabaseAnonKey) +``` + +And one optional step is to update the CSS file `public/global.css` to make the app look nice. +You can find the full contents of this file [here](https://raw.githubusercontent.com/supabase/supabase/master/examples/react-user-management/src/index.css). + +### Set up a Login component + +Let's set up a Svelte component to manage logins and sign ups. We'll use Magic Links, so users can sign in with their email without using passwords. + +```html title="/src/Auth.svelte" + + +
    +
    +

    Supabase + Svelte

    +

    Sign in via magic link with your email below

    +
    + +
    +
    + +
    +
    +
    +``` + +### User store + +To access the user information in other places, we use a writable store. Create a new file called `sessionStore.js` + +```javascript title="src/sessionStore.js" +import { writable } from 'svelte/store' + +export const user = writable(false) +``` + +### Account page + +After a user is signed in we can allow them to edit their profile details and manage their account. +Let's create a new component for that called `Profile.svelte`. + +```html title="src/Profile.svelte" + + +
    +
    + + +
    +
    + + +
    +
    + + +
    + +
    + +
    + +
    + +
    +
    +``` + +### Launch! + +Now that we have all the components in place, let's update `App.svelte`: + +```html title="src/App.svelte" + + +
    + {#if $user} + + {:else} + + {/if} +
    +``` + +Once that's done, run this in a terminal window: + +```bash +npm run dev +``` + +And then open the browser to [localhost:5000](http://localhost:5000) and you should see the completed app. + +> ⚠️ WARNING: Svelte uses by default `port 5000`, Supabase uses `port 3000`. To change the redirection port for supabase go to: `Authentication > Settings` and change the `Site Url` to `localhost:5000` + +![Supabase Svelte](/docs/img/supabase-svelte-demo.png) + +## Bonus: Profile photos + +Every Supabase project is configured with [Storage](/docs/guides/storage) for managing large files like photos and videos. + +### Create an upload widget + +Let's create an avatar for the user so that they can upload a profile photo. We can start by creating a new component: + +```html title="src/Avatar.svelte" + + +
    + {#if path} + Avatar + {:else} +
    + {/if} + +
    + + +
    +
    +``` + +### Add the new widget + +And then we can add the widget to the Account page: + +```html title="src/Profile.svelte" + + +
    + + + + + +``` + +## Next steps + +At this stage you have a fully functional application! + +- Got a question? [Ask here](https://github.com/supabase/supabase/discussions). +- Sign in: [app.supabase.io](https://app.supabase.io) diff --git a/apps/temp-docs/docs/guides/with-vue-3.mdx b/apps/temp-docs/docs/guides/with-vue-3.mdx new file mode 100644 index 00000000000..c624568a11d --- /dev/null +++ b/apps/temp-docs/docs/guides/with-vue-3.mdx @@ -0,0 +1,570 @@ +--- +id: with-vue-3 +title: 'Quickstart: Vue 3' +description: Learn how to use Supabase in your Vue 3 App. +--- + +# Quickstart: Svelte + +## Intro + +This example provides the steps to build a simple user management app (from scratch!) using Supabase and Vue 3. It includes: + +- Supabase [Database](/docs/guides/database): a Postgres database for storing your user data. +- Supabase [Auth](/docs/guides/auth): users can sign in with magic links (no passwords, only email). +- Supabase [Storage](/docs/guides/storage): users can upload a photo. +- [Row Level Security](/docs/guides/auth#row-level-security): data is protected so that individuals can only access their own data. +- Instant [APIs](/docs/guides/api): APIs will be automatically generated when you create your database tables. + +By the end of this guide you'll have an app which allows users to login and update some basic profile details: + +![Supabase User Management example](/docs/img/user-management-demo.png) + +### Github + +Whenever you get stuck at any point, take a look at [this repo](https://github.com/zernonia/supabase-vue-3). + +## Project set up + +Before we start building we're going to set up our Database and API. This is as simple as starting a new Project in Supabase +and then creating a "schema" inside the database. + +### Create a project + +1. Go to [app.supabase.io](https://app.supabase.io). +1. Click on "New Project". +1. Enter your project details. +1. Wait for the new database to launch. + +### Set up the database schema + +Now we are going to set up the database schema. We can use the "User Management Starter" quickstart in the SQL Editor, +or you can just copy/paste the SQL from below and run it yourself. + + + + +```sh +1. Go to the "SQL" section. +2. Click "User Management Starter". +3. Click "Run". +``` + + + + + + +```sql +-- Create a table for public "profiles" +create table profiles ( + id uuid references auth.users not null, + updated_at timestamp with time zone, + username text unique, + avatar_url text, + website text, + + primary key (id), + unique(username), + constraint username_length check (char_length(username) >= 3) +); + +alter table profiles enable row level security; + +create policy "Public profiles are viewable by everyone." + on profiles for select + using ( true ); + +create policy "Users can insert their own profile." + on profiles for insert + with check ( auth.uid() = id ); + +create policy "Users can update own profile." + on profiles for update + using ( auth.uid() = id ); + +-- Set up Realtime! +begin; + drop publication if exists supabase_realtime; + create publication supabase_realtime; +commit; +alter publication supabase_realtime add table profiles; + +-- Set up Storage! +insert into storage.buckets (id, name) +values ('avatars', 'avatars'); + +create policy "Avatar images are publicly accessible." + on storage.objects for select + using ( bucket_id = 'avatars' ); + +create policy "Anyone can upload an avatar." + on storage.objects for insert + with check ( bucket_id = 'avatars' ); + +``` + + + + +### Get the API Keys + +Now that you've created some database tables, you are ready to insert data using the auto-generated API. +We just need to get the URL and `anon` key from the API settings. + + + + +```sh +1. Go to the "Settings" section. +2. Click "API" in the sidebar. +3. Find your API URL in this page. +4. Find your "anon" and "service_role" keys on this page. +``` + + + + + + +## Building the App + +Let's start building the Vue 3 app from scratch. + +### Initialize a Vue 3 app + +We can quickly use [Vite with Vue 3 Template](https://vitejs.dev/guide/#scaffolding-your-first-vite-project) to initialize +an app called `supabase-vue-3`: + +```bash +# npm 6.x +npm init @vitejs/app supabase-vue-3 --template vue + +# npm 7+, extra double-dash is needed: +npm init @vitejs/app supabase-vue-3 -- --template vue + +cd supabase-vue-3 +``` + +Then let's install the only additional dependency: [supabase-js](https://github.com/supabase/supabase-js) + +```bash +npm install @supabase/supabase-js +``` + +And finally we want to save the environment variables in a `.env`. +All we need are the API URL and the `anon` key that you copied [earlier](#get-the-api-keys). + +```bash title=".env" +VITE_SUPABASE_URL=YOUR_SUPABASE_URL +VITE_SUPABASE_ANON_KEY=YOUR_SUPABASE_ANON_KEY +``` + +Now that we have the API credentials in place, let's create a helper file to initialize the Supabase client. These variables will be exposed +on the browser, and that's completely fine since we have [Row Level Security](/docs/guides/auth#row-level-security) enabled on our Database. + +```js title="src/supabase.js" +import { createClient } from '@supabase/supabase-js' + +const supabaseUrl = import.meta.env.VITE_SUPABASE_URL +const supabaseAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEY + +export const supabase = createClient(supabaseUrl, supabaseAnonKey) +``` + +And one optional step is to update the CSS file `src/assets/main.css` to make the app look nice. +You can find the full contents of this file [here](https://raw.githubusercontent.com/supabase/supabase/master/examples/react-user-management/src/index.css). + +```javascript title="src/main.js" +import { createApp } from 'vue' +import App from './App.vue' +import './assets/main.css' + +createApp(App).mount('#app') +``` + +### Set up a Login component + +Let's set up a Vue component to manage logins and sign ups. We'll use Magic Links, so users can sign in with their email without using passwords. + +```html title="/src/components/Auth.vue" + + + +``` + +### User store + +To access the user information in other places, we use a reactive store. Create a new file called `store.js` and utilize Vue 3 `reactive` functionalities. + +```javascript title="src/store.js" +import { reactive } from 'vue' + +export const store = reactive({ + user: {}, +}) +``` + +### Account page + +After a user is signed in we can allow them to edit their profile details and manage their account. +Let's create a new component for that called `Profile.vue`. + +```html title="src/components/Profile.vue" + + + +``` + +### Launch! + +Now that we have all the components in place, let's update `App.vue`: + +```html title="src/App.vue" + + + +``` + +Once that's done, run this in a terminal window: + +```bash +npm run dev +``` + +And then open the browser to [localhost:3000](http://localhost:3000) and you should see the completed app. + +![Supabase Vue 3](/docs/img/supabase-vue-3-demo.png) + +## Bonus: Profile photos + +Every Supabase project is configured with [Storage](/docs/guides/storage) for managing large files like photos and videos. + +### Create an upload widget + +Let's create an avatar for the user so that they can upload a profile photo. We can start by creating a new component: + +```html title="src/components/Avatar.vue" + + + +``` + +### Add the new widget + +And then we can add the widget to the Account page: + +```html title="src/Profile.vue" + + + +``` + +## Next steps + +At this stage you have a fully functional application! + +- Got a question? [Ask here](https://github.com/supabase/supabase/discussions). +- Sign in: [app.supabase.io](https://app.supabase.io) diff --git a/apps/temp-docs/docs/handbook/contributing.mdx b/apps/temp-docs/docs/handbook/contributing.mdx new file mode 100644 index 00000000000..89b050586bc --- /dev/null +++ b/apps/temp-docs/docs/handbook/contributing.mdx @@ -0,0 +1,86 @@ +--- +title: 'Contributing' +description: 'Contributing to Supabase' +--- + +# Contributing + +## How to contribute + +Want to contribute? Why not jump into our GitHub repo and: + +- [Sponsor Supabase](https://github.com/sponsors/supabase). +- [Answer Discussions](https://github.com/supabase/supabase/discussions). +- Submit an issue. +- Report a performance issue or a part of the documentation that you find confusing. +- Create a pull request. +- [Translate our Readme](https://github.com/supabase/supabase/issues/1341). +- Try our products and give feedback. +- Spread the word if you like what we are doing. + +## Sponsors + +**Evangelist: $49 per month** + + + + + + + +**Supporter: $19 per month** + + + + + + + + + + + + + + +**Contributor: $5 per month** + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/temp-docs/docs/handbook/supasquad.mdx b/apps/temp-docs/docs/handbook/supasquad.mdx new file mode 100644 index 00000000000..d61563bdc4d --- /dev/null +++ b/apps/temp-docs/docs/handbook/supasquad.mdx @@ -0,0 +1,66 @@ +--- +title: 'SupaSquad' +description: 'Supabase SupaSquad' +--- + +# SupaSquad + +The SupaSquad is an official Supabase advocate program where community members help build and manage the Supabase community. + +- Official recognition in the Supabase community. +- Direct connection to the Supabase team. +- Help steer the Supabase community. + +Supabase SupaSquad + +## Requirements + +As a member of the Squad, you choose the approach where you'll provide the most value. You can help in one of five ways: + +### Maintainer + +Help maintain Supabase repositories. This includes building client libraries, managing issues, and fixing bugs. + +### Expert +Answer user questions on Github [Discussions](https://github.com/supabase/supabase/discussions), Discord, and various other social platforms. + +### Advocate +Spread the word on social channels and help to answer Supabase-related questions in the broader community and social channels. + +### Builder +Build Supabase examples, blog about them, and them add to the [SupaSquad GitHub Org](https://github.com/supasquad). + +### Author +Write guest blog posts, create documentation, and help Supabase global expansion through translation. + +### Moderator +Help us maintain the community guidelines in our GitHub and Community-led communities such as Discord, [Reddit](https://reddit.com/r/Supabase/), (StackOverflow)[https://stackoverflow.com/questions/tagged/supabase], etc. + + +### Benefits for SupaSquad members +- Access to a Supabase Discord channel providing direct communication with the team, Discord badges, and elevated privileges. +- Special AMA sessions with members of the Supabase team. +- Monthly DevRel committee call with industry-leading Developer Advocates (many of whom are [angel investors](https://supabase.com/docs/blog/2021/03/25/angels-of-supabase)), where you can learn from the best. +- We'll help you build your audience by promoting content via the Supabase social channels. +- Featured profile on Supabase website. +- Early access to new features (and the opportunity to provide feedback to the team!). +- Free credits that you can use for Squad efforts. +- Direct access to members of the Supabase team for questions, suggestions, etc. +- Help shape the future of the program. +- Invited to the [SupaSquad GitHub Org](https://github.com/supasquad) to collaborate with the other squad members. +- Exclusive Supabase Team swag drops are usually exclusively reserved for the Supabase core team. + +### How to join +1. Apply to join the program using this form. +2. We will start taking interviewing members from 1 September 2021. +3. Entry is capped to 20 founding members so we can grow the community at a healthy pace and provide a great experience to all new users. +4. Membership is valid for one year, and can be renewed every year. + +### FAQs +- Why are you only admitting 20 new members? +The entire Supabase team is only 20 people, so as you can imagine adding another 20 people sounds like a lot to us! We wish we could admit everyone who wanted to join. But we also want to make sure everyone who joins the Squad has an awesome experience. In the future we will probably expand the intake to include a monthly quota. +- What is expected? +Mostly just enthusiasm. If you are interested in Open Source and want to get involved, the SupaSquad program is a great channel. You'll be given opportunities to contribute to the community in whatever ways match your skillset. +- What if I become too busy to contribute? +No worries! The program isn't a job. It's just an opportunity to build your skillset and audience within the Supabase ecosystem. + diff --git a/apps/temp-docs/docs/introduction.mdx b/apps/temp-docs/docs/introduction.mdx new file mode 100644 index 00000000000..410065073d2 --- /dev/null +++ b/apps/temp-docs/docs/introduction.mdx @@ -0,0 +1,48 @@ +--- +title: Introduction +description: Introduction to Supabase +--- + + +# Introduction + +Supabase is an open source Firebase alternative. + +It provides all the backend services you need to build a product. You can use it completely, or just the services you require: + + + + + + + + +## Getting Started + +Visit [app.supabase.io](https://app.supabase.io) to get started with the hosted platform or visit the self-hosting docs to learn how to host Supabase yourself. + +Supabase is just Postgres, which makes it compatible with a large number of tools and frameworks. + + + + + + + + + + + + +## How to use these docs +The documentation is divided into 3 sections. + + + + + + + + + + diff --git a/apps/temp-docs/docs/javascript/.gitkeep b/apps/temp-docs/docs/javascript/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/apps/temp-docs/docs/javascript/auth-api-createuser.mdx b/apps/temp-docs/docs/javascript/auth-api-createuser.mdx new file mode 100644 index 00000000000..95eb40e21dd --- /dev/null +++ b/apps/temp-docs/docs/javascript/auth-api-createuser.mdx @@ -0,0 +1,97 @@ +--- +id: auth-api-createuser +title: "createUser()" +slug: auth-api-createuser +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Creates a new user. + +This function should only be called on a server. Never expose your `service_role` key in the browser. + + + + + +```js +const { data: user, error } = await supabase.auth.api.createUser({ + name: 'Yoda' +}) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + attributes + + + required + + + UserAttributes + +

      +
      + +The data you want to create the user with. + +
      + +
    • + +
    + + +## Notes + +- Requires a `service_role` key. +- This function should be called on a server. Never expose your `service_role` key in the browser. + + + + + + + + + + +## Examples + +### Create a new user. + + + + + + + +```js +const { data: user, error } = await supabase.auth.api.createUser({ + name: 'Yoda' +}) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/auth-api-deleteuser.mdx b/apps/temp-docs/docs/javascript/auth-api-deleteuser.mdx new file mode 100644 index 00000000000..4cd5536d508 --- /dev/null +++ b/apps/temp-docs/docs/javascript/auth-api-deleteuser.mdx @@ -0,0 +1,120 @@ +--- +id: auth-api-deleteuser +title: "deleteUser()" +slug: auth-api-deleteuser +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Delete a user. Requires a `service_role` key. + +This function should only be called on a server. Never expose your `service_role` key in the browser. + + + + + +```js +const { data: user, error } = await supabase.auth.api.deleteUser( + '715ed5db-f090-4b8c-a067-640ecee36aa0', + 'YOUR_SERVICE_ROLE_KEY' +) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + uid + + + required + + + string + +

      +
      + +The user uid you want to remove. + +
      + +
    • + + +
    • +

      + + jwt + + + required + + + string + +

      +
      + +A valid JWT. Must be a full-access API key (e.g. service_role key). + +
      + +
    • + +
    + + +## Notes + +- Requires a `service_role` key. +- This function should be called on a server. Never expose your `service_role` key in the browser. + + + + + + + + + + +## Examples + +### Remove a user completely. + + + + + + + +```js +const { data: user, error } = await supabase.auth.api.deleteUser( + '715ed5db-f090-4b8c-a067-640ecee36aa0', + 'YOUR_SERVICE_ROLE_KEY' +) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/auth-api-generatelink.mdx b/apps/temp-docs/docs/javascript/auth-api-generatelink.mdx new file mode 100644 index 00000000000..bfb612aef93 --- /dev/null +++ b/apps/temp-docs/docs/javascript/auth-api-generatelink.mdx @@ -0,0 +1,189 @@ +--- +id: auth-api-generatelink +title: "generateLink()" +slug: auth-api-generatelink +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Generates links to be sent via email or other. + + + +## Parameters + + +
      + +
    • +

      + + type + + + required + + + signup | magiclink | recovery | invite + +

      +
      + +The link type ("signup" or "magiclink" or "recovery" or "invite"). + +
      + +
    • + + +
    • +

      + + email + + + required + + + string + +

      +
      + +The user's email. + +
      + +
    • + + +
    • +

      + + options + + + required + + + object + +

      +
      + +No description provided. + +
      + +
        +
        Properties
        + +
      • +

        + + data + + + optional + + + object + +

        +
        + +No description provided. + +
        + +
      • + + +
      • +

        + + password + + + optional + + + string + +

        +
        + +No description provided. + +
        + +
      • + + +
      • +

        + + redirectTo + + + optional + + + string + +

        +
        + +No description provided. + +
        + +
      • + +
      + +
    • + +
    + + +## Notes + +- Requires a `service_role` key. +- This function should only be called on a server. Never expose your `service_role` key in the browser. + + + + + + + + + + +## Examples + +### Generate invite link. + + + + + + + +```js +const { data: user, error } = await supabase.auth.api.generateLink({ + type: 'invite', + email: 'email@example.com' +}) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/auth-api-getuser.mdx b/apps/temp-docs/docs/javascript/auth-api-getuser.mdx new file mode 100644 index 00000000000..0d10b1bbca8 --- /dev/null +++ b/apps/temp-docs/docs/javascript/auth-api-getuser.mdx @@ -0,0 +1,96 @@ +--- +id: auth-api-getuser +title: "getUser()" +slug: auth-api-getuser +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Gets the user details. + + + + + +```js +const { user, error } = await supabase.auth.api.getUser( + 'ACCESS_TOKEN_JWT', +) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + jwt + + + required + + + string + +

      +
      + +A valid, logged-in JWT. + +
      + +
    • + +
    + + +## Notes + +- Fetches the user object from the database instead of local storage. +- Note that user() fetches the user object from local storage which might not be the most updated. +- Requires the user's access_token. + + + + + + + + + + +## Examples + +### Fetch the user object using the access_token jwt. + + + + + + + +```js +const { user, error } = await supabase.auth.api.getUser( + 'ACCESS_TOKEN_JWT', +) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/auth-api-inviteuserbyemail.mdx b/apps/temp-docs/docs/javascript/auth-api-inviteuserbyemail.mdx new file mode 100644 index 00000000000..1ed7271198f --- /dev/null +++ b/apps/temp-docs/docs/javascript/auth-api-inviteuserbyemail.mdx @@ -0,0 +1,146 @@ +--- +id: auth-api-inviteuserbyemail +title: "inviteUserByEmail()" +slug: auth-api-inviteuserbyemail +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Sends an invite link to an email address. + + + +## Parameters + + +
      + +
    • +

      + + email + + + required + + + string + +

      +
      + +The email address of the user. + +
      + +
    • + + +
    • +

      + + options + + + required + + + object + +

      +
      + +No description provided. + +
      + +
        +
        Properties
        + +
      • +

        + + data + + + optional + + + object + +

        +
        + +No description provided. + +
        + +
      • + + +
      • +

        + + redirectTo + + + optional + + + string + +

        +
        + +No description provided. + +
        + +
      • + +
      + +
    • + +
    + + +## Notes + +- Requires a `service_role` key. +- This function should only be called on a server. Never expose your `service_role` key in the browser. + + + + + + + + + + +## Examples + +### Basic example. + + + + + + + +```js +const { data: user, error } = await supabase.auth + .api + .inviteUserByEmail('email@example.com') +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/auth-api-resetpasswordforemail.mdx b/apps/temp-docs/docs/javascript/auth-api-resetpasswordforemail.mdx new file mode 100644 index 00000000000..68ad2d890fc --- /dev/null +++ b/apps/temp-docs/docs/javascript/auth-api-resetpasswordforemail.mdx @@ -0,0 +1,125 @@ +--- +id: auth-api-resetpasswordforemail +title: "resetPasswordForEmail()" +slug: auth-api-resetpasswordforemail +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Sends a reset request to an email address. + + + +## Parameters + + +
      + +
    • +

      + + email + + + required + + + string + +

      +
      + +The email address of the user. + +
      + +
    • + + +
    • +

      + + options + + + required + + + object + +

      +
      + +No description provided. + +
      + +
        +
        Properties
        + +
      • +

        + + redirectTo + + + optional + + + string + +

        +
        + +No description provided. + +
        + +
      • + +
      + +
    • + +
    + + +## Notes + +- Requires a `service_role` key. +- This function should only be called on a server. Never expose your `service_role` key in the browser. + + + + + + + + + + +## Examples + +### Basic example. + + + + + + + +```js +const { data: user, error } = await supabase.auth + .api + .resetPasswordForEmail('email@example.com') +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/auth-api-sendmobileotp.mdx b/apps/temp-docs/docs/javascript/auth-api-sendmobileotp.mdx new file mode 100644 index 00000000000..671a54b7545 --- /dev/null +++ b/apps/temp-docs/docs/javascript/auth-api-sendmobileotp.mdx @@ -0,0 +1,79 @@ +--- +id: auth-api-sendmobileotp +title: "sendMobileOTP()" +slug: auth-api-sendmobileotp +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Sends a mobile OTP via SMS. Will register the account if it doesn't already exist + + + +## Parameters + + +
      + +
    • +

      + + phone + + + required + + + string + +

      +
      + +The user's phone number WITH international prefix + +
      + +
    • + +
    + + +## Notes + +- Requires a `service_role` key. +- This function should only be called on a server. Never expose your `service_role` key in the browser. + + + + + + + + + + +## Examples + +### Basic example. + + + + + + + +```js +const { data: user, error } = await supabase.auth + .api + .sendMobileOTP('12345879') +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/auth-onauthstatechange.mdx b/apps/temp-docs/docs/javascript/auth-onauthstatechange.mdx new file mode 100644 index 00000000000..baa6bd540d5 --- /dev/null +++ b/apps/temp-docs/docs/javascript/auth-onauthstatechange.mdx @@ -0,0 +1,93 @@ +--- +id: auth-onauthstatechange +title: "onAuthStateChange()" +slug: auth-onauthstatechange +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Receive a notification every time an auth event happens. + + + + + +```js +supabase.auth.onAuthStateChange((event, session) => { + console.log(event, session) +}) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + callback + + + required + + + object + +

      +
      + +No description provided. + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### Listen to auth changes + + + + + + + +```js +supabase.auth.onAuthStateChange((event, session) => { + console.log(event, session) +}) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/auth-session.mdx b/apps/temp-docs/docs/javascript/auth-session.mdx new file mode 100644 index 00000000000..fb1f1287b30 --- /dev/null +++ b/apps/temp-docs/docs/javascript/auth-session.mdx @@ -0,0 +1,65 @@ +--- +id: auth-session +title: "session()" +slug: auth-session +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Returns the session data, if there is an active session. + + + + + +```js +const session = supabase.auth.session() +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### Get the session data + + + + + + + +```js +const session = supabase.auth.session() +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/auth-setauth.mdx b/apps/temp-docs/docs/javascript/auth-setauth.mdx new file mode 100644 index 00000000000..4a86aaffe4f --- /dev/null +++ b/apps/temp-docs/docs/javascript/auth-setauth.mdx @@ -0,0 +1,160 @@ +--- +id: auth-setauth +title: "setAuth()" +slug: auth-setauth +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Overrides the JWT on the current client. The JWT will then be sent in all subsequent network requests. + + + + + +```js +function apiFunction(req, res) { + // Assuming the access token was sent as a header "X-Supabase-Auth" + const { access_token } = req.get('X-Supabase-Auth') + + // You can now use it within a Supabase Client + const supabase = createClient("https://xyzcompany.supabase.co", "public-anon-key") + const { user, error } = supabase.auth.setAuth(access_token) + + // This client will now send requests as this user + const { data } = await supabase.from('your_table').select() +} +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + access_token + + + required + + + string + +

      +
      + +a jwt access token + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### Basic example. + +This is most useful on server-side functions where you cannot log the user in, but have access to the user's access token. + + + + + +```js +function apiFunction(req, res) { + // Assuming the access token was sent as a header "X-Supabase-Auth" + const { access_token } = req.get('X-Supabase-Auth') + + // You can now use it within a Supabase Client + const supabase = createClient("https://xyzcompany.supabase.co", "public-anon-key") + const { user, error } = supabase.auth.setAuth(access_token) + + // This client will now send requests as this user + const { data } = await supabase.from('your_table').select() +} +``` + + + + + + +### With Express. + + + + + + + +```js + +/** +* Make a request from the client to your server function +*/ +async function makeApiRequest() { + const token = newClient.session()?.access_token + + await fetch('https://example.com/withAuth', { + method: 'GET', + withCredentials: true, + credentials: 'include', + headers: { + 'Content-Type': 'application/json' + 'Authorization': bearer, // Your own auth + 'X-Supabase-Auth': token, // Set the Supabase user + } + }) +} + +/** +* Use the Auth token in your server-side function. +*/ +async function apiFunction(req, res) { + const { access_token } = req.get('X-Supabase-Auth') + + // You can now use it within a Supabase Client + const supabase = createClient("https://xyzcompany.supabase.co", "public-anon-key") + const { user, error } = supabase.auth.setAuth(access_token) + + // This client will now send requests as this user + const { data } = await supabase.from('your_table').select() +} +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/auth-signin.mdx b/apps/temp-docs/docs/javascript/auth-signin.mdx new file mode 100644 index 00000000000..d19f85cc52b --- /dev/null +++ b/apps/temp-docs/docs/javascript/auth-signin.mdx @@ -0,0 +1,297 @@ +--- +id: auth-signin +title: "signIn()" +slug: auth-signin +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Log in an existing user, or login via a third-party provider. + + + + + +```js +const { user, session, error } = await supabase.auth.signIn({ + email: 'example@email.com', + password: 'example-password', +}) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + __namedParameters + + + required + + + UserCredentials + +

      +
      + +No description provided. + +
      + +
    • + + +
    • +

      + + options + + + required + + + object + +

      +
      + +No description provided. + +
      + +
        +
        Properties
        + +
      • +

        + + redirectTo + + + optional + + + string + +

        +
        + +No description provided. + +
        + +
      • + + +
      • +

        + + scopes + + + optional + + + string + +

        +
        + +No description provided. + +
        + +
      • + +
      + +
    • + +
    + + +## Notes + +- A user can sign up either via email or OAuth. +- If you provide `email` without a `password`, the user will be sent a magic link. +- The magic link's destination URL is determined by the SITE_URL config variable. To change this, you can go to Authentication -> Settings on [app.supabase.io](https://app.supabase.io) +- Specifying a `provider` will open the browser to the relevant login page. + + + + + + + + + + +## Examples + +### Sign in with email. + + + + + + + +```js +const { user, session, error } = await supabase.auth.signIn({ + email: 'example@email.com', + password: 'example-password', +}) +``` + + + + + + +### Sign in with magic link. + +If no password is provided, the user will be sent a "magic link" to their email address, which they can click to open your application with a valid session. By default, a given user can only request a Magic Link once every 60 seconds. + + + + + +```js +const { user, session, error } = await supabase.auth.signIn({ + email: 'example@email.com' +}) +``` + + + + + + +### Sign in using third-party providers. + +Supabase supports OAuth logins. + + + + + +```js +const { user, session, error } = await supabase.auth.signIn({ + // provider can be 'github', 'google', 'gitlab', or 'bitbucket' + provider: 'github' +}) +``` + + + + + + +### Sign in with redirect. + +Sometimes you want to control where the user is redirected to after they are logged in. Supabase supports this for +any URL path on your website (the base domain must be the same as the domain in your Auth settings). + + + + + + +```js +const { user, session, error } = await supabase.auth.signIn({ + provider: 'github' +}, { + redirectTo: 'https://example.com/welcome' +}) +``` + + + + + + +### Sign in with scopes. + +If you need additional data from an OAuth provider, you can include a space-separated list of scopes in your request to get back an OAuth provider token. +You may also need to specify the scopes in the provider's OAuth app settings, depending on the provider. + + + + + + +```js +const { user, session, error } = await supabase.auth.signIn({ + provider: 'github' +}, { + scopes: 'repo gist notifications' +}) +const oAuthToken = session.provider_token // use to access provider API +``` + + + + + + +### Sign in using a refresh token (e.g. in React Native). + +If you are completing a sign up or login in a React Native app you can pass the refresh token obtained from the provider to obtain a session. + + + + + + +```js +// An example using Expo's `AuthSession` +const redirectUri = AuthSession.makeRedirectUri({ useProxy: false }); +const provider = 'google'; + +AuthSession.startAsync({ + authUrl: `https://MYSUPABASEAPP.supabase.co/auth/v1/authorize?provider=${provider}&redirect_to=${redirectUri}`, + returnUrl: redirectUri, +}).then(async (response: any) => { + if (!response) return; + const { user, session, error } = await supabase.auth.signIn({ + refreshToken: response.params?.refresh_token, + }); +}); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/auth-signout.mdx b/apps/temp-docs/docs/javascript/auth-signout.mdx new file mode 100644 index 00000000000..caa66f506bf --- /dev/null +++ b/apps/temp-docs/docs/javascript/auth-signout.mdx @@ -0,0 +1,68 @@ +--- +id: auth-signout +title: "signOut()" +slug: auth-signout +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Inside a browser context, `signOut()` will remove the logged in user from the browser session +and log them out - removing all items from localstorage and then trigger a "SIGNED_OUT" event. + +For server-side management, you can disable sessions by passing a JWT through to `auth.api.signOut(JWT: string)` + + + + + +```js +const { error } = await supabase.auth.signOut() +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### Sign out + + + + + + + +```js +const { error } = await supabase.auth.signOut() +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/auth-signup.mdx b/apps/temp-docs/docs/javascript/auth-signup.mdx new file mode 100644 index 00000000000..89e17586e34 --- /dev/null +++ b/apps/temp-docs/docs/javascript/auth-signup.mdx @@ -0,0 +1,205 @@ +--- +id: auth-signup +title: "signUp()" +slug: auth-signup +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Creates a new user. + + + + + +```js +const { user, session, error } = await supabase.auth.signUp({ + email: 'example@email.com', + password: 'example-password', +}) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + __namedParameters + + + required + + + UserCredentials + +

      +
      + +No description provided. + +
      + +
    • + + +
    • +

      + + options + + + required + + + object + +

      +
      + +No description provided. + +
      + +
        +
        Properties
        + +
      • +

        + + data + + + optional + + + object + +

        +
        + +No description provided. + +
        + +
      • + + +
      • +

        + + redirectTo + + + optional + + + string + +

        +
        + +No description provided. + +
        + +
      • + +
      + +
    • + +
    + + +## Notes + +- By default, the user will need to verify their email address before logging in. If you would like to change this, you can disable "Email Confirmations" by going to Authentication -> Settings on [app.supabase.io](https://app.supabase.io) +- If "Email Confirmations" is turned on, a `user` is returned but `session` will be null +- If "Email Confirmations" is turned off, both a `user` and a `session` will be returned +- When the user confirms their email address, they will be redirected to localhost:3000 by default. To change this, you can go to Authentication -> Settings on [app.supabase.io](https://app.supabase.io) +- If signUp() is called for an existing confirmed user: + - If "Enable email confirmations" is enabled on the "Authentication" -> "Settings" page, an obfuscated / fake user object will be returned. + - If "Enable email confirmations" is disabled, an error with a message "User already registered" will be returned. +- To check if a user already exists, refer to getUser(). + + + + + + + + + + +## Examples + +### Sign up. + + + + + + + +```js +const { user, session, error } = await supabase.auth.signUp({ + email: 'example@email.com', + password: 'example-password', +}) +``` + + + + + + +### Sign up with additional user meta data. + + + + + + + +```js +const { user, session, error } = await supabase.auth.signUp( + { + email: 'example@email.com', + password: 'example-password', + }, + { + data: { + first_name: 'John', + age: 27, + } + } +) +``` + + + + + + +### Sign up with third-party providers. + +You can sign up with OAuth providers using the [`signIn()`](/docs/reference/javascript/auth-signin#sign-in-using-third-party-providers) method. \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/auth-update.mdx b/apps/temp-docs/docs/javascript/auth-update.mdx new file mode 100644 index 00000000000..bc7f9f6124a --- /dev/null +++ b/apps/temp-docs/docs/javascript/auth-update.mdx @@ -0,0 +1,137 @@ +--- +id: auth-update +title: "update()" +slug: auth-update +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Updates user data, if there is a logged in user. + + + + + +```js +const { user, error } = await supabase.auth.update({email: 'new@email.com'}) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + attributes + + + required + + + UserAttributes + +

      +
      + +No description provided. + +
      + +
    • + +
    + + +## Notes + +User email: Email updates will send an email to both the user's current and new email with a confirmation link by default. +To toggle this behavior off and only send a single confirmation link to the new email, toggle "Double confirm email changes" under "Authentication" -> "Settings" off. + + +User metadata: It's generally better to store user data in a table inside your public schema (i.e. `public.users`). +Use the `update()` method if you have data which rarely changes or is specific only to the logged in user. + + + + + + + + + + +## Examples + +### Update email for authenticated user. + +Sends a "Confirm Email Change" email to the new email address. + + + + + +```js +const { user, error } = await supabase.auth.update({email: 'new@email.com'}) +``` + + + + + + +### Update password for authenticated user. + + + + + + + +```js +const { user, error } = await supabase.auth.update({password: 'new password'}) +``` + + + + + + +### Update a user's metadata. + + + + + + + +```js +const { user, error } = await supabase.auth.update({ + data: { hello: 'world' } +}) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/auth-user.mdx b/apps/temp-docs/docs/javascript/auth-user.mdx new file mode 100644 index 00000000000..f0875580371 --- /dev/null +++ b/apps/temp-docs/docs/javascript/auth-user.mdx @@ -0,0 +1,68 @@ +--- +id: auth-user +title: "user()" +slug: auth-user +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Inside a browser context, `user()` will return the user data, if there is a logged in user. + +For server-side management, you can get a user through `auth.api.getUserByCookie()` + + + + + +```js +const user = supabase.auth.user() +``` + + + + + + + + + + +## Notes + +This method gets the user object from memory. + + + + + + + + + + +## Examples + +### Get the logged in user + + + + + + + +```js +const user = supabase.auth.user() +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/containedby.mdx b/apps/temp-docs/docs/javascript/containedby.mdx new file mode 100644 index 00000000000..6e783d53d71 --- /dev/null +++ b/apps/temp-docs/docs/javascript/containedby.mdx @@ -0,0 +1,140 @@ +--- +id: containedby +title: ".containedBy()" +slug: containedby +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .select('name, id, main_exports') + .containedBy('main_exports', ['cars', 'food', 'machine']) +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .select('name, id, main_exports') + .containedBy('main_exports', ['cars', 'food', 'machine']) +``` + + + + + + +### With `update()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .update({ name: 'Mordor' }) + .containedBy('main_exports', ['orks', 'surveillance', 'evil']) +``` + + + + + + +### With `delete()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .delete() + .containedBy('main_exports', ['cars', 'food', 'machine']) +``` + + + + + + +### With `rpc()` + + + + + + + +```js +// Only valid if the Postgres function returns a table type. +const { data, error } = await supabase + .rpc('echo_all_countries') + .containedBy('main_exports', ['cars', 'food', 'machine']) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/contains.mdx b/apps/temp-docs/docs/javascript/contains.mdx new file mode 100644 index 00000000000..9d46db6f9db --- /dev/null +++ b/apps/temp-docs/docs/javascript/contains.mdx @@ -0,0 +1,140 @@ +--- +id: contains +title: ".contains()" +slug: contains +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .select('name, id, main_exports') + .contains('main_exports', ['oil']) +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .select('name, id, main_exports') + .contains('main_exports', ['oil']) +``` + + + + + + +### With `update()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .update({ name: 'Mordor' }) + .contains('main_exports', ['oil']) +``` + + + + + + +### With `delete()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .delete() + .contains('main_exports', ['oil']) +``` + + + + + + +### With `rpc()` + + + + + + + +```js +// Only valid if the Postgres function returns a table type. +const { data, error } = await supabase + .rpc('echo_all_countries') + .contains('main_exports', ['oil']) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/delete-user.mdx b/apps/temp-docs/docs/javascript/delete-user.mdx new file mode 100644 index 00000000000..cb370409907 --- /dev/null +++ b/apps/temp-docs/docs/javascript/delete-user.mdx @@ -0,0 +1,118 @@ +--- +id: delete-user +title: "Delete User" +slug: delete-user +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Delete a user. Requires a `service_role` key. + +This function should only be called on a server. Never expose your `service_role` key in the browser. + + + + + +```js +const { user, error } = await supabase.auth.api.deleteUser( + '715ed5db-f090-4b8c-a067-640ecee36aa0', + 'YOUR_SERVICE_ROLE_KEY' +) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + uid + + + required + + + string + +

      +
      + +The user uid you want to remove. + +
      + +
    • + + +
    • +

      + + jwt + + + required + + + string + +

      +
      + +A valid JWT. Must be a full-access API key (e.g. service_role key). + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### Remove a user completely. + + + + + + + +```js +const { user, error } = await supabase.auth.api.deleteUser( + '715ed5db-f090-4b8c-a067-640ecee36aa0', + 'YOUR_SERVICE_ROLE_KEY' +) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/delete.mdx b/apps/temp-docs/docs/javascript/delete.mdx new file mode 100644 index 00000000000..75b26387576 --- /dev/null +++ b/apps/temp-docs/docs/javascript/delete.mdx @@ -0,0 +1,147 @@ +--- +id: delete +title: "Delete data: delete()" +slug: delete +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Performs a DELETE on the table. + + + + + +```js +const { data, error } = await supabase + .from('cities') + .delete() + .match({ id: 666 }) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + __namedParameters + + + required + + + object + +

      +
      + +No description provided. + +
      + +
        +
        Properties
        + +
      • +

        + + returning + + + required + + + minimal | representation + +

        +
        + +If `true`, return the deleted row(s) in the response. + +
        + +
      • + + +
      • +

        + + count + + + required + + + null | exact | planned | estimated + +

        +
        + +Count algorithm to use to count rows in a table. + +
        + +
      • + +
      + +
    • + +
    + + +## Notes + +- `delete()` should always be combined with [filters](/docs/reference/javascript/using-filters) to target the item(s) you wish to delete. +- If you use `delete()` with filters and you have + [RLS](/docs/learn/auth-deep-dive/auth-row-level-security) enabled, only + rows visible through `SELECT` policies are deleted. Note that by default + no rows are visible, so you need at least one `SELECT`/`ALL` policy that + makes the rows visible. + + + + + + + + + + +## Examples + +### Delete records + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .delete() + .match({ id: 666 }) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/eq.mdx b/apps/temp-docs/docs/javascript/eq.mdx new file mode 100644 index 00000000000..57a536977bf --- /dev/null +++ b/apps/temp-docs/docs/javascript/eq.mdx @@ -0,0 +1,186 @@ +--- +id: eq +title: ".eq()" +slug: eq +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose value on the stated `column` exactly matches the +specified `value`. + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .eq('name', 'The shire') +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + column + + + required + + + object + +

      +
      + +The column to filter on. + +
      + +
    • + + +
    • +

      + + value + + + required + + + object + +

      +
      + +The value to filter with. + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .eq('name', 'The shire') +``` + + + + + + +### With `update()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .update({ name: 'Mordor' }) + .eq('name', 'San Francisco') +``` + + + + + + +### With `delete()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .delete() + .eq('name', 'Mordor') +``` + + + + + + +### With `rpc()` + + + + + + + +```js +// Only valid if the Postgres function returns a table type. +const { data, error } = await supabase + .rpc('echo_all_cities') + .eq('name', 'San Francisco') +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/filter.mdx b/apps/temp-docs/docs/javascript/filter.mdx new file mode 100644 index 00000000000..4dcd39afe94 --- /dev/null +++ b/apps/temp-docs/docs/javascript/filter.mdx @@ -0,0 +1,230 @@ +--- +id: filter +title: ".filter()" +slug: filter +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose `column` satisfies the filter. + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .filter('name', 'in', '("Paris","Tokyo")') +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + column + + + required + + + object + +

      +
      + +The column to filter on. + +
      + +
    • + + +
    • +

      + + operator + + + required + + + FilterOperator + +

      +
      + +The operator to filter with. + +
      + +
    • + + +
    • +

      + + value + + + required + + + any + +

      +
      + +The value to filter with. + +
      + +
    • + +
    + + +## Notes + +- `.filter()` expects you to use the raw [PostgREST syntax](https://postgrest.org/en/stable/api.html#horizontal-filtering-rows) for the filter values, so it should only be used as an escape hatch in case other filters don't work. + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .filter('name', 'in', '("Paris","Tokyo")') +``` + + + + + + +### With `update()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .update({ name: 'Mordor' }) + .filter('name', 'in', '("Paris","Tokyo")') +``` + + + + + + +### With `delete()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .delete() + .filter('name', 'in', '("Paris","Tokyo")') +``` + + + + + + +### With `rpc()` + + + + + + + +```js +// Only valid if the Postgres function returns a table type. +const { data, error } = await supabase + .rpc('echo_all_cities') + .filter('name', 'in', '("Paris","Tokyo")') +``` + + + + + + +### Filter embedded resources + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, countries ( name )') + .filter('countries.name', 'in', '("France","Japan")') +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/generating-types.mdx b/apps/temp-docs/docs/javascript/generating-types.mdx new file mode 100644 index 00000000000..70f24120dd4 --- /dev/null +++ b/apps/temp-docs/docs/javascript/generating-types.mdx @@ -0,0 +1,136 @@ +--- +id: generating-types +title: "Generating Types" +slug: generating-types +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Supabase will soon release native type generators that dump your database types for various languages. For now, we support TypeScript through a third-party tool. + +## Usage with TypeScript + +`supabase-js` ships with type definitions for usage with TypeScript and for convenient IntelliSense auto-complete and documentation in your editor. + +When using TypeScript, you can pass the type of database row as a type parameter to the `from` method to get better auto-completion support down the chain. +If you don't provide a type for the row you need to explicitly pass `from('tableName')`. + +```ts +type Message = { + id: number; + inserted_at: string; + message: string; + user_id: string; + channel_id: number; + author: { username: string }; +} + +const response = await supabase + .from('messages') // Message maps to the type of the row in your database. + .select('*, author:user_id(username)') + .match({ channel_id: 2 }) // Your IDE will be able to help with auto-completion. +response.data // Response data will be of type Array. + +// If you don't provide a type for the row you need to explicitly pass `from('tableName')`. +const response = await supabase + .from('messages') + .select('*, author:user_id(username)') + .match({ channel_id: 2 }) +response.data // Response data will be of type Array. +``` + +### Generate database types from OpenAPI specification + +Supabase generates an OpenAPI specification file for your database which can be used to generate your data types for usage with TypeScript. + +The OpenAPI specification for your Supabase project can be accessed as follows: + +```txt +https://your-project.supabase.co/rest/v1/?apikey=your-anon-key +``` + +Using the open source [openapi-typescript](https://github.com/drwpow/openapi-typescript#%EF%B8%8F-reading-specs-from-remote-resource) tool you can generate your types and store them locally: + +```bash +npx openapi-typescript https://your-project.supabase.co/rest/v1/?apikey=your-anon-key --output types/supabase.ts +``` + +Important notes: + +- Since the generator uses JSON API, there is no way to determine if a column is an Array. It will generate array types as `string`, even though Supabase handles this automatically and returns arrays. + You can fix this manually in the files by changing the type, e.g. `names: string` -> `names: string[]` +- The types won't automatically stay in sync with your database, so make sure to regenerate your types after your make changes to your database. + +After you have generated your types, you can use them in your TypeScript projects: + +```ts +import { NextApiRequest, NextApiResponse } from "next"; +import { createClient } from "@supabase/supabase-js"; +import { definitions } from "../../types/supabase"; + +const supabase = createClient( + process.env.NEXT_PUBLIC_SUPABASE_URL, + process.env.SUPABASE_SECRET_KEY +); + +export default async (req: NextApiRequest, res: NextApiResponse) => { + const allOnlineUsers = await supabase + .from("users") + .select("*") + .eq("status", "ONLINE"); + res.status(200).json(allOnlineUsers); +}; +``` + +### Update types automatically with GitHub Actions + +One way to keep your type definitions in sync with your database is to set up a GitHub action that runs on a schedule. + +Add a script to your package.json to generate the types: + +``` +"update-types": "npx openapi-typescript https://your-project.supabase.co/rest/v1/?apikey=your-anon-key --output types/database/index.ts" +``` + +In your repo, create the file `.github/workflows/update-types.yml`. Add the following snippet into this file to define the action. If there is a change to your definitions, this script will commit the change to your repo. + +```yml +name: Update database types + +on: + schedule: + # sets the action to run daily. You can modify this to run the action more or less frequently + - cron: '0 0 * * *' + +jobs: + update: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + persist-credentials: false + fetch-depth: 0 + - uses: actions/setup-node@v2.1.5 + with: + node-version: 14 + - run: npm run update-types + - name: check for file changes + id: git_status + run: | + echo "::set-output name=status::$(git status -s)" + - name: Commit files + if: ${{contains(steps.git_status.outputs.status, ' ')}} + run: | + git add types/database/index.ts + git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" + git config --local user.name "github-actions[bot]" + git commit -m "Update database types" -a + - name: Push changes + if: ${{contains(steps.git_status.outputs.status, ' ')}} + uses: ad-m/github-push-action@master + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + branch: ${{ github.ref }} +``` \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/getsubscriptions.mdx b/apps/temp-docs/docs/javascript/getsubscriptions.mdx new file mode 100644 index 00000000000..7e98d88a575 --- /dev/null +++ b/apps/temp-docs/docs/javascript/getsubscriptions.mdx @@ -0,0 +1,65 @@ +--- +id: getsubscriptions +title: "getSubscriptions()" +slug: getsubscriptions +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Returns an array of all your subscriptions. + + + + + +```js +const subscriptions = supabase.getSubscriptions() +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### Get all subscriptions + + + + + + + +```js +const subscriptions = supabase.getSubscriptions() +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/gt.mdx b/apps/temp-docs/docs/javascript/gt.mdx new file mode 100644 index 00000000000..159221aabd6 --- /dev/null +++ b/apps/temp-docs/docs/javascript/gt.mdx @@ -0,0 +1,186 @@ +--- +id: gt +title: ".gt()" +slug: gt +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose value on the stated `column` is greater than the +specified `value`. + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .gt('country_id', 250) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + column + + + required + + + object + +

      +
      + +The column to filter on. + +
      + +
    • + + +
    • +

      + + value + + + required + + + object + +

      +
      + +The value to filter with. + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .gt('country_id', 250) +``` + + + + + + +### With `update()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .update({ name: 'Mordor' }) + .gt('country_id', 250) +``` + + + + + + +### With `delete()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .delete() + .gt('country_id', 250) +``` + + + + + + +### With `rpc()` + + + + + + + +```js +// Only valid if the Postgres function returns a table type. +const { data, error } = await supabase + .rpc('echo_all_cities') + .gt('country_id', 250) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/gte.mdx b/apps/temp-docs/docs/javascript/gte.mdx new file mode 100644 index 00000000000..eb67a61bcd8 --- /dev/null +++ b/apps/temp-docs/docs/javascript/gte.mdx @@ -0,0 +1,186 @@ +--- +id: gte +title: ".gte()" +slug: gte +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose value on the stated `column` is greater than or +equal to the specified `value`. + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .gte('country_id', 250) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + column + + + required + + + object + +

      +
      + +The column to filter on. + +
      + +
    • + + +
    • +

      + + value + + + required + + + object + +

      +
      + +The value to filter with. + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .gte('country_id', 250) +``` + + + + + + +### With `update()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .update({ name: 'Mordor' }) + .gte('country_id', 250) +``` + + + + + + +### With `delete()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .delete() + .gte('country_id', 250) +``` + + + + + + +### With `rpc()` + + + + + + + +```js +// Only valid if the Postgres function returns a table type. +const { data, error } = await supabase + .rpc('echo_all_cities') + .gte('country_id', 250) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/ilike.mdx b/apps/temp-docs/docs/javascript/ilike.mdx new file mode 100644 index 00000000000..94090260f1e --- /dev/null +++ b/apps/temp-docs/docs/javascript/ilike.mdx @@ -0,0 +1,186 @@ +--- +id: ilike +title: ".ilike()" +slug: ilike +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose value in the stated `column` matches the supplied +`pattern` (case insensitive). + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .ilike('name', '%la%') +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + column + + + required + + + object + +

      +
      + +The column to filter on. + +
      + +
    • + + +
    • +

      + + pattern + + + required + + + string + +

      +
      + +The pattern to filter with. + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .ilike('name', '%la%') +``` + + + + + + +### With `update()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .update({ name: 'Mordor' }) + .ilike('name', '%la%') +``` + + + + + + +### With `delete()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .delete() + .ilike('name', '%la%') +``` + + + + + + +### With `rpc()` + + + + + + + +```js +// Only valid if the Postgres function returns a table type. +const { data, error } = await supabase + .rpc('echo_all_cities') + .ilike('name', '%la%') +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/in.mdx b/apps/temp-docs/docs/javascript/in.mdx new file mode 100644 index 00000000000..09c29d98692 --- /dev/null +++ b/apps/temp-docs/docs/javascript/in.mdx @@ -0,0 +1,186 @@ +--- +id: in +title: ".in()" +slug: in +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose value on the stated `column` is found on the +specified `values`. + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .in('name', ['Rio de Janeiro', 'San Francisco']) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + column + + + required + + + object + +

      +
      + +The column to filter on. + +
      + +
    • + + +
    • +

      + + values + + + required + + + object + +

      +
      + +The values to filter with. + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .in('name', ['Rio de Janeiro', 'San Francisco']) +``` + + + + + + +### With `update()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .update({ name: 'Mordor' }) + .in('name', ['Rio de Janeiro', 'San Francisco']) +``` + + + + + + +### With `delete()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .delete() + .in('name', ['Rio de Janeiro', 'San Francisco']) +``` + + + + + + +### With `rpc()` + + + + + + + +```js +// Only valid if the Postgres function returns a table type. +const { data, error } = await supabase + .rpc('echo_all_cities') + .in('name', ['Rio de Janeiro', 'San Francisco']) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/index.mdx b/apps/temp-docs/docs/javascript/index.mdx new file mode 100644 index 00000000000..7701a27a439 --- /dev/null +++ b/apps/temp-docs/docs/javascript/index.mdx @@ -0,0 +1,109 @@ +--- +id: index +title: "Supabase Client" +slug: supabase-client +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Our approach for client libraries is modular. Each sub-library is a standalone implementation for a single external system. This is one of the ways we support existing tools. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    LanguageClientFeature-Clients (bundled in Supabase client)
    SupabasePostgRESTGoTrueRealtimeStorage
    ⚡️ Official ⚡️
    JavaScript (TypeScript)supabase-jspostgrest-jsgotrue-jsrealtime-jsstorage-js
    💚 Community 💚
    C#supabase-csharppostgrest-csharpgotrue-csharprealtime-csharp-
    Dart (Flutter)supabase-dartpostgrest-dartgotrue-langrealtime-dartstorage-dart
    Go-postgrest-go---
    Java--gotrue-java--
    Kotlin-postgrest-ktgotrue-kt--
    Pythonsupabase-pypostgrest-pygotrue-pyrealtime-py-
    Rubysupabase-rbpostgrest-rb---
    Rust-postgrest-rs---
    Swiftsupabase-swiftpostgrest-swiftgotrue-swiftrealtime-swiftstorage-swift
    \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/initializing.mdx b/apps/temp-docs/docs/javascript/initializing.mdx new file mode 100644 index 00000000000..39bd9890b98 --- /dev/null +++ b/apps/temp-docs/docs/javascript/initializing.mdx @@ -0,0 +1,211 @@ +--- +id: initializing +title: "Initializing" +slug: initializing +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +You can initialize a new Supabase client using the `createClient()` method. + +The Supabase client is your entrypoint to the rest of the Supabase functionality +and is the easiest way to interact with everything we offer within the Supabase ecosystem. + + + + +## Parameters + + +
      + +
    • +

      + + supabaseUrl + + + required + + + string + +

      +
      + +The unique Supabase URL which is supplied when you create a new project in your project dashboard. + +
      + +
    • + + +
    • +

      + + supabaseKey + + + required + + + string + +

      +
      + +The unique Supabase Key which is supplied when you create a new project in your project dashboard. + +
      + +
    • + + +
    • +

      + + options + + + optional + + + SupabaseClientOptions + +

      +
      + +No description provided. + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### createClient() + + + + + + + +```js +import { createClient } from '@supabase/supabase-js' + +// Create a single supabase client for interacting with your database +const supabase = createClient('https://xyzcompany.supabase.co', 'public-anon-key') +``` + + + + + + +### With additional parameters + + + + + + + +```js +import { createClient } from '@supabase/supabase-js' + +const options = { + schema: 'public', + headers: { 'x-my-custom-header': 'my-app-name' }, + autoRefreshToken: true, + persistSession: true, + detectSessionInUrl: true +} +const supabase = createClient("https://xyzcompany.supabase.co", "public-anon-key", options) +``` + + + + + + +### API schemas + + + + + + + +```js +import { createClient } from '@supabase/supabase-js' + +// Provide a custom schema. Defaults to "public". +const supabase = createClient('https://xyzcompany.supabase.co', 'public-anon-key', { + schema: 'other_schema' +}) +``` + +By default the API server points to the `public` schema. You can enable other database schemas within the Dashboard. +Go to `Settings > API > Schema` and add the schema which you want to expose to the API. + +Note: each client connection can only access a single schema, so the code above can access the `other_schema` schema but cannot access the `public` schema. + + + + + + +### Custom `fetch` implementation + + + + + + + +```js +import { createClient } from '@supabase/supabase-js' + +const supabase = createClient('https://xyzcompany.supabase.co', 'public-anon-key', { + fetch: fetch.bind(globalThis) +}) +``` + +`supabase-js` uses the [`cross-fetch`](https://www.npmjs.com/package/cross-fetch) library to make HTTP requests, +but an alternative `fetch` implementation can be provided as an option. +This is most useful in environments where `cross-fetch` is not compatible (for instance Cloudflare Workers). + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/insert.mdx b/apps/temp-docs/docs/javascript/insert.mdx new file mode 100644 index 00000000000..abaf8b0eda2 --- /dev/null +++ b/apps/temp-docs/docs/javascript/insert.mdx @@ -0,0 +1,179 @@ +--- +id: insert +title: "Create data: insert()" +slug: insert +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Performs an INSERT into the table. + + + + + +```js +const { data, error } = await supabase + .from('cities') + .insert([ + { name: 'The Shire', country_id: 554 } + ]) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + values + + + required + + + Partial | array + +

      +
      + +The values to insert. + +
      + +
    • + + +
    • +

      + + options + + + optional + + + undefined | reflection + +

      +
      + +No description provided. + +
      + +
    • + +
    + + +## Notes + +- By default, every time you run `insert()`, the client library will make a `select` to return the full record. +This is convenient, but it can also cause problems if your Policies are not configured to allow the `select` operation. +If you are using Row Level Security and you are encountering problems, try setting the `returning` param to `minimal`. + + + + + + + + + + +## Examples + +### Create a record + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .insert([ + { name: 'The Shire', country_id: 554 } + ]) +``` + + + + + + +### Bulk create + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .insert([ + { name: 'The Shire', country_id: 554 }, + { name: 'Rohan', country_id: 555 }, + ]) +``` + + + + + + +### Upsert + +For upsert, if set to true, primary key columns would need to be included +in the data parameter in order for an update to properly happen. Also, primary keys +used must be natural, not surrogate. There are however, +[workarounds](https://github.com/PostgREST/postgrest/issues/1118) +for surrogate primary keys. + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .insert( + [ + { name: 'The Shire', country_id: 554 }, + { name: 'Rohan', country_id: 555 }, + { name: 'City by the Bay', country_id:840} + ], + { upsert: true }) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/installing.mdx b/apps/temp-docs/docs/javascript/installing.mdx new file mode 100644 index 00000000000..aeb6b0fff5a --- /dev/null +++ b/apps/temp-docs/docs/javascript/installing.mdx @@ -0,0 +1,42 @@ +--- +id: installing +title: "Installing" +slug: installing +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +All JavaScript libraries are built directly by the Supabase team. + +Other languages are built by the community and supported by Supabase. + +## JavaScript + +Via NPM +```bash +npm install @supabase/supabase-js +``` + +Via Yarn +```bash +yarn add @supabase/supabase-js +``` + +Find the source code on [GitHub](https://github.com/supabase/supabase-js). + +Or via CDN +```js + +//or + +``` + +## Python + +```bash +pip install supabase-py +``` + +Find the source code on [GitHub](https://github.com/supabase/supabase-py). \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/is.mdx b/apps/temp-docs/docs/javascript/is.mdx new file mode 100644 index 00000000000..fb75d615a60 --- /dev/null +++ b/apps/temp-docs/docs/javascript/is.mdx @@ -0,0 +1,186 @@ +--- +id: is +title: ".is()" +slug: is +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +A check for exact equality (null, true, false), finds all rows whose +value on the stated `column` exactly match the specified `value`. + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .is('name', null) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + column + + + required + + + object + +

      +
      + +The column to filter on. + +
      + +
    • + + +
    • +

      + + value + + + required + + + boolean | null + +

      +
      + +The value to filter with. + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .is('name', null) +``` + + + + + + +### With `update()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .update({ name: 'Mordor' }) + .is('name', null) +``` + + + + + + +### With `delete()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .delete() + .is('name', null) +``` + + + + + + +### With `rpc()` + + + + + + + +```js +// Only valid if the Postgres function returns a table type. +const { data, error } = await supabase + .rpc('echo_all_cities') + .is('name', null) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/like.mdx b/apps/temp-docs/docs/javascript/like.mdx new file mode 100644 index 00000000000..fee839bf02f --- /dev/null +++ b/apps/temp-docs/docs/javascript/like.mdx @@ -0,0 +1,186 @@ +--- +id: like +title: ".like()" +slug: like +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose value in the stated `column` matches the supplied +`pattern` (case sensitive). + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .like('name', '%la%') +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + column + + + required + + + object + +

      +
      + +The column to filter on. + +
      + +
    • + + +
    • +

      + + pattern + + + required + + + string + +

      +
      + +The pattern to filter with. + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .like('name', '%la%') +``` + + + + + + +### With `update()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .update({ name: 'Mordor' }) + .like('name', '%la%') +``` + + + + + + +### With `delete()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .delete() + .like('name', '%la%') +``` + + + + + + +### With `rpc()` + + + + + + + +```js +// Only valid if the Postgres function returns a table type. +const { data, error } = await supabase + .rpc('echo_all_cities') + .like('name', '%la%') +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/limit.mdx b/apps/temp-docs/docs/javascript/limit.mdx new file mode 100644 index 00000000000..6d7f0708e65 --- /dev/null +++ b/apps/temp-docs/docs/javascript/limit.mdx @@ -0,0 +1,165 @@ +--- +id: limit +title: "limit()" +slug: limit +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Limits the result with the specified `count`. + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .limit(1) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + count + + + required + + + number + +

      +
      + +The maximum no. of rows to limit to. + +
      + +
    • + + +
    • +

      + + __namedParameters + + + required + + + object + +

      +
      + +No description provided. + +
      + +
        +
        Properties
        + +
      • +

        + + foreignTable + + + required + + + undefined | string + +

        +
        + +The foreign table to use (for foreign columns). + +
        + +
      • + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .limit(1) +``` + + + + + + +### With embedded resources + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .select('name, cities(name)') + .eq('name', 'United States') + .limit(1, { foreignTable: 'cities' }) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/lt.mdx b/apps/temp-docs/docs/javascript/lt.mdx new file mode 100644 index 00000000000..dff252d9bc3 --- /dev/null +++ b/apps/temp-docs/docs/javascript/lt.mdx @@ -0,0 +1,186 @@ +--- +id: lt +title: ".lt()" +slug: lt +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose value on the stated `column` is less than the +specified `value`. + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .lt('country_id', 250) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + column + + + required + + + object + +

      +
      + +The column to filter on. + +
      + +
    • + + +
    • +

      + + value + + + required + + + object + +

      +
      + +The value to filter with. + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .lt('country_id', 250) +``` + + + + + + +### With `update()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .update({ name: 'Mordor' }) + .lt('country_id', 250) +``` + + + + + + +### With `delete()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .delete() + .lt('country_id', 250) +``` + + + + + + +### With `rpc()` + + + + + + + +```js +// Only valid if the Postgres function returns a table type. +const { data, error } = await supabase + .rpc('echo_all_cities') + .lt('country_id', 250) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/lte.mdx b/apps/temp-docs/docs/javascript/lte.mdx new file mode 100644 index 00000000000..cd783f12d9d --- /dev/null +++ b/apps/temp-docs/docs/javascript/lte.mdx @@ -0,0 +1,186 @@ +--- +id: lte +title: ".lte()" +slug: lte +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose value on the stated `column` is less than or equal +to the specified `value`. + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .lte('country_id', 250) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + column + + + required + + + object + +

      +
      + +The column to filter on. + +
      + +
    • + + +
    • +

      + + value + + + required + + + object + +

      +
      + +The value to filter with. + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .lte('country_id', 250) +``` + + + + + + +### With `update()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .update({ name: 'Mordor' }) + .lte('country_id', 250) +``` + + + + + + +### With `delete()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .delete() + .lte('country_id', 250) +``` + + + + + + +### With `rpc()` + + + + + + + +```js +// Only valid if the Postgres function returns a table type. +const { data, error } = await supabase + .rpc('echo_all_cities') + .lte('country_id', 250) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/match.mdx b/apps/temp-docs/docs/javascript/match.mdx new file mode 100644 index 00000000000..2c705811778 --- /dev/null +++ b/apps/temp-docs/docs/javascript/match.mdx @@ -0,0 +1,165 @@ +--- +id: match +title: ".match()" +slug: match +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose columns match the specified `query` object. + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .match({name: 'Beijing', country_id: 156}) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + query + + + required + + + Record + +

      +
      + +The object to filter with, with column names as keys mapped + to their filter values. + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .match({name: 'Beijing', country_id: 156}) +``` + + + + + + +### With `update()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .update({ name: 'Mordor' }) + .match({name: 'Beijing', country_id: 156}) +``` + + + + + + +### With `delete()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .delete() + .match({name: 'Beijing', country_id: 156}) +``` + + + + + + +### With `rpc()` + + + + + + + +```js +// Only valid if the Postgres function returns a table type. +const { data, error } = await supabase + .rpc('echo_all_cities') + .match({name: 'Beijing', country_id: 156}) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/maybesingle.mdx b/apps/temp-docs/docs/javascript/maybesingle.mdx new file mode 100644 index 00000000000..8e41b958d20 --- /dev/null +++ b/apps/temp-docs/docs/javascript/maybesingle.mdx @@ -0,0 +1,75 @@ +--- +id: maybesingle +title: "maybeSingle()" +slug: maybesingle +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Retrieves at most one row from the result. Result must be at most one row +(e.g. using `eq` on a UNIQUE column), otherwise this will result in an +error. + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .eq('name', 'Singapore') + .maybeSingle() +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .eq('name', 'Singapore') + .maybeSingle() +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/neq.mdx b/apps/temp-docs/docs/javascript/neq.mdx new file mode 100644 index 00000000000..3793d89dea2 --- /dev/null +++ b/apps/temp-docs/docs/javascript/neq.mdx @@ -0,0 +1,186 @@ +--- +id: neq +title: ".neq()" +slug: neq +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose value on the stated `column` doesn't match the +specified `value`. + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .neq('name', 'The shire') +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + column + + + required + + + object + +

      +
      + +The column to filter on. + +
      + +
    • + + +
    • +

      + + value + + + required + + + object + +

      +
      + +The value to filter with. + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .neq('name', 'The shire') +``` + + + + + + +### With `update()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .update({ name: 'Mordor' }) + .neq('name', 'San Francisco') +``` + + + + + + +### With `delete()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .delete() + .neq('name', 'Mordor') +``` + + + + + + +### With `rpc()` + + + + + + + +```js +// Only valid if the Postgres function returns a table type. +const { data, error } = await supabase + .rpc('echo_all_cities') + .neq('name', 'Lagos') +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/not.mdx b/apps/temp-docs/docs/javascript/not.mdx new file mode 100644 index 00000000000..2d9ce2cae81 --- /dev/null +++ b/apps/temp-docs/docs/javascript/not.mdx @@ -0,0 +1,206 @@ +--- +id: not +title: ".not()" +slug: not +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows which doesn't satisfy the filter. + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .not('name', 'eq', 'Paris') +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + column + + + required + + + object + +

      +
      + +The column to filter on. + +
      + +
    • + + +
    • +

      + + operator + + + required + + + FilterOperator + +

      +
      + +The operator to filter with. + +
      + +
    • + + +
    • +

      + + value + + + required + + + any + +

      +
      + +The value to filter with. + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .not('name', 'eq', 'Paris') +``` + + + + + + +### With `update()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .update({ name: 'Mordor' }) + .not('name', 'eq', 'Paris') +``` + + + + + + +### With `delete()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .delete() + .not('name', 'eq', 'Paris') +``` + + + + + + +### With `rpc()` + + + + + + + +```js +// Only valid if the Postgres function returns a table type. +const { data, error } = await supabase + .rpc('echo_all_cities') + .not('name', 'eq', 'Paris') +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/or.mdx b/apps/temp-docs/docs/javascript/or.mdx new file mode 100644 index 00000000000..f4dcc9ec923 --- /dev/null +++ b/apps/temp-docs/docs/javascript/or.mdx @@ -0,0 +1,187 @@ +--- +id: or +title: ".or()" +slug: or +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows satisfying at least one of the filters. + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .or('id.eq.20,id.eq.30') +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + filters + + + required + + + string + +

      +
      + +The filters to use, separated by commas. + +
      + +
    • + + +
    • +

      + + __namedParameters + + + required + + + object + +

      +
      + +No description provided. + +
      + +
        +
        Properties
        + +
      • +

        + + foreignTable + + + required + + + undefined | string + +

        +
        + +The foreign table to use (if `column` is a foreign column). + +
        + +
      • + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .or('id.eq.20,id.eq.30') +``` + + + + + + +### Use `or` with `and` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .or('id.gt.20,and(name.eq.New Zealand,name.eq.France)') +``` + + + + + + +### Use `or` on foreign tables + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .select('id, cities(*)') + .or('name.eq.Wellington,name.eq.Paris', { foreignTable: "cities" }) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/order.mdx b/apps/temp-docs/docs/javascript/order.mdx new file mode 100644 index 00000000000..c8b536b8bc0 --- /dev/null +++ b/apps/temp-docs/docs/javascript/order.mdx @@ -0,0 +1,207 @@ +--- +id: order +title: "order()" +slug: order +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Orders the result with the specified `column`. + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name', 'country_id') + .order('id', { ascending: false }) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + column + + + required + + + object + +

      +
      + +The column to order on. + +
      + +
    • + + +
    • +

      + + __namedParameters + + + required + + + object + +

      +
      + +No description provided. + +
      + +
        +
        Properties
        + +
      • +

        + + nullsFirst + + + required + + + boolean + +

        +
        + +If `true`, `null`s appear first. + +
        + +
      • + + +
      • +

        + + foreignTable + + + required + + + undefined | string + +

        +
        + +The foreign table to use (if `column` is a foreign column). + +
        + +
      • + + +
      • +

        + + ascending + + + required + + + boolean + +

        +
        + +If `true`, the result will be in ascending order. + +
        + +
      • + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name', 'country_id') + .order('id', { ascending: false }) +``` + + + + + + +### With embedded resources + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .select('name, cities(name)') + .eq('name', 'United States') + .order('name', {foreignTable: 'cities'}) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/overlaps.mdx b/apps/temp-docs/docs/javascript/overlaps.mdx new file mode 100644 index 00000000000..b396a179145 --- /dev/null +++ b/apps/temp-docs/docs/javascript/overlaps.mdx @@ -0,0 +1,140 @@ +--- +id: overlaps +title: ".overlaps()" +slug: overlaps +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .select('name, id, main_exports') + .overlaps('main_exports', ['computers', 'minerals']) +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .select('name, id, main_exports') + .overlaps('main_exports', ['computers', 'minerals']) +``` + + + + + + +### With `update()` + + + + + + + +```js +let countries = await supabase + .from('countries') + .update({ name: 'Mordor' }) + .overlaps('main_exports', ['computers', 'minerals']) +``` + + + + + + +### With `delete()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .delete() + .overlaps('main_exports', ['computers', 'minerals']) +``` + + + + + + +### With `rpc()` + + + + + + + +```js +// Only valid if the Postgres function returns a table type. +const { data, error } = await supabase + .rpc('echo_all_countries') + .overlaps('main_exports', ['computers', 'minerals']) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/range.mdx b/apps/temp-docs/docs/javascript/range.mdx new file mode 100644 index 00000000000..00b8532b0f2 --- /dev/null +++ b/apps/temp-docs/docs/javascript/range.mdx @@ -0,0 +1,162 @@ +--- +id: range +title: "range()" +slug: range +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Limits the result to rows within the specified range, inclusive. + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .range(0,3) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + from + + + required + + + number + +

      +
      + +The starting index from which to limit the result, inclusive. + +
      + +
    • + + +
    • +

      + + to + + + required + + + number + +

      +
      + +The last index to which to limit the result, inclusive. + +
      + +
    • + + +
    • +

      + + __namedParameters + + + required + + + object + +

      +
      + +No description provided. + +
      + +
        +
        Properties
        + +
      • +

        + + foreignTable + + + required + + + undefined | string + +

        +
        + +The foreign table to use (for foreign columns). + +
        + +
      • + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .range(0,3) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/rangeadjacent.mdx b/apps/temp-docs/docs/javascript/rangeadjacent.mdx new file mode 100644 index 00000000000..5197c6baf77 --- /dev/null +++ b/apps/temp-docs/docs/javascript/rangeadjacent.mdx @@ -0,0 +1,140 @@ +--- +id: rangeadjacent +title: ".rangeAdjacent()" +slug: rangeadjacent +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .select('name, id, population_range_millions') + .rangeAdjacent('population_range_millions', [70, 185]) +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .select('name, id, population_range_millions') + .rangeAdjacent('population_range_millions', [70, 185]) +``` + + + + + + +### With `update()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .update({ name: 'Mordor' }) + .rangeAdjacent('population_range_millions', [70, 185]) +``` + + + + + + +### With `delete()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .delete() + .rangeAdjacent('population_range_millions', [70, 185]) +``` + + + + + + +### With `rpc()` + + + + + + + +```js +// Only valid if the Postgres function returns a table type. +const { data, error } = await supabase + .rpc('echo_all_countries') + .rangeAdjacent('population_range_millions', [70, 185]) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/rangegt.mdx b/apps/temp-docs/docs/javascript/rangegt.mdx new file mode 100644 index 00000000000..c152a4222a1 --- /dev/null +++ b/apps/temp-docs/docs/javascript/rangegt.mdx @@ -0,0 +1,140 @@ +--- +id: rangegt +title: ".rangeGt()" +slug: rangegt +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .select('name, id, population_range_millions') + .rangeGt('population_range_millions', [150, 250]) +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .select('name, id, population_range_millions') + .rangeGt('population_range_millions', [150, 250]) +``` + + + + + + +### With `update()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .update({ name: 'Mordor' }) + .rangeGt('population_range_millions', [150, 250]) +``` + + + + + + +### With `delete()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .delete() + .rangeGt('population_range_millions', [150, 250]) +``` + + + + + + +### With `rpc()` + + + + + + + +```js +// Only valid if the Postgres function returns a table type. +const { data, error } = await supabase + .rpc('echo_all_countries') + .rangeGt('population_range_millions', [150, 250]) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/rangegte.mdx b/apps/temp-docs/docs/javascript/rangegte.mdx new file mode 100644 index 00000000000..1d7fd697384 --- /dev/null +++ b/apps/temp-docs/docs/javascript/rangegte.mdx @@ -0,0 +1,140 @@ +--- +id: rangegte +title: ".rangeGte()" +slug: rangegte +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .select('name, id, population_range_millions') + .rangeGte('population_range_millions', [150, 250]) +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .select('name, id, population_range_millions') + .rangeGte('population_range_millions', [150, 250]) +``` + + + + + + +### With `update()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .update({ name: 'Mordor' }) + .rangeGte('population_range_millions', [150, 250]) +``` + + + + + + +### With `delete()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .delete() + .rangeGte('population_range_millions', [150, 250]) +``` + + + + + + +### With `rpc()` + + + + + + + +```js +// Only valid if the Postgres function returns a table type. +const { data, error } = await supabase + .rpc('echo_all_countries') + .rangeGte('population_range_millions', [150, 250]) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/rangelt.mdx b/apps/temp-docs/docs/javascript/rangelt.mdx new file mode 100644 index 00000000000..3663dacc60b --- /dev/null +++ b/apps/temp-docs/docs/javascript/rangelt.mdx @@ -0,0 +1,140 @@ +--- +id: rangelt +title: ".rangeLt()" +slug: rangelt +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .select('name, id, population_range_millions') + .rangeLt('population_range_millions', [150, 250]) +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .select('name, id, population_range_millions') + .rangeLt('population_range_millions', [150, 250]) +``` + + + + + + +### With `update()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .update({ name: 'Mordor' }) + .rangeLt('population_range_millions', [150, 250]) +``` + + + + + + +### With `delete()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .delete() + .rangeLt('population_range_millions', [150, 250]) +``` + + + + + + +### With `rpc()` + + + + + + + +```js +// Only valid if the Postgres function returns a table type. +const { data, error } = await supabase + .rpc('echo_all_countries') + .rangeLt('population_range_millions', [150, 250]) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/rangelte.mdx b/apps/temp-docs/docs/javascript/rangelte.mdx new file mode 100644 index 00000000000..538d45770f3 --- /dev/null +++ b/apps/temp-docs/docs/javascript/rangelte.mdx @@ -0,0 +1,140 @@ +--- +id: rangelte +title: ".rangeLte()" +slug: rangelte +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .select('name, id, population_range_millions') + .rangeLte('population_range_millions', [150, 250]) +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .select('name, id, population_range_millions') + .rangeLte('population_range_millions', [150, 250]) +``` + + + + + + +### With `update()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .update({ name: 'Mordor' }) + .rangeLte('population_range_millions', [150, 250]) +``` + + + + + + +### With `delete()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .delete() + .rangeLte('population_range_millions', [150, 250]) +``` + + + + + + +### With `rpc()` + + + + + + + +```js +// Only valid if the Postgres function returns a table type. +const { data, error } = await supabase + .rpc('echo_all_countries') + .rangeLte('population_range_millions', [150, 250]) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/removeallsubscriptions.mdx b/apps/temp-docs/docs/javascript/removeallsubscriptions.mdx new file mode 100644 index 00000000000..6786350333a --- /dev/null +++ b/apps/temp-docs/docs/javascript/removeallsubscriptions.mdx @@ -0,0 +1,66 @@ +--- +id: removeallsubscriptions +title: "removeAllSubscriptions()" +slug: removeallsubscriptions +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Removes all subscriptions and disconnects the Websocket connection. + + + + + +```js +supabase.removeAllSubscriptions() +``` + + + + + + + + + + +## Notes + +- Removing subscriptions is a great way to maintain the performance of your project's database. Supabase will automatically handle cleanup 30 seconds after a user is disconnected, but unused subscriptions may cause degradation as more users are simultaneously subscribed. + + + + + + + + + + +## Examples + +### Removes all subscriptions + + + + + + + +```js +supabase.removeAllSubscriptions() +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/removesubscription.mdx b/apps/temp-docs/docs/javascript/removesubscription.mdx new file mode 100644 index 00000000000..53c2a6b7a94 --- /dev/null +++ b/apps/temp-docs/docs/javascript/removesubscription.mdx @@ -0,0 +1,90 @@ +--- +id: removesubscription +title: "removeSubscription()" +slug: removesubscription +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Removes an active subscription and returns the number of open connections. + + + + + +```js +supabase.removeSubscription(mySubscription) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + subscription + + + required + + + RealtimeSubscription + +

      +
      + +The subscription you want to remove. + +
      + +
    • + +
    + + +## Notes + +- Removing subscriptions is a great way to maintain the performance of your project's database. Supabase will automatically handle cleanup 30 seconds after a user is disconnected, but unused subscriptions may cause degradation as more users are simultaneously subscribed. + + + + + + + + + + +## Examples + +### Remove a subscription + + + + + + + +```js +supabase.removeSubscription(mySubscription) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/reset-password-email.mdx b/apps/temp-docs/docs/javascript/reset-password-email.mdx new file mode 100644 index 00000000000..7dad6d33ed3 --- /dev/null +++ b/apps/temp-docs/docs/javascript/reset-password-email.mdx @@ -0,0 +1,151 @@ +--- +id: reset-password-email +title: "Reset Password (Email)" +slug: reset-password-email +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Sends a reset request to an email address. + + + + + +```js +const { data, error } = supabase.auth.api + .resetPasswordForEmail('user@email.com') +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + email + + + required + + + string + +

      +
      + +The email address of the user. + +
      + +
    • + + +
    • +

      + + options + + + required + + + object + +

      +
      + +No description provided. + +
      + +
        +
        Properties
        + +
      • +

        + + redirectTo + + + optional + + + string + +

        +
        + +No description provided. + +
        + +
      • + +
      + +
    • + +
    + + +## Notes + +Sends a reset request to an email address. + +When the user clicks the reset link in the email they will be forwarded to: + +`#access_token=x&refresh_token=y&expires_in=z&token_type=bearer&type=recovery` + +Your app must detect `type=recovery` in the fragment and display a password reset form to the user. + +You should then use the access_token in the url and new password to update the user as follows: + +```js +const { error, data } = await supabase.auth.api + .updateUser(access_token, { password : new_password }) +``` + + + + + + + + + + +## Examples + +### Reset password + + + + + + + +```js +const { data, error } = supabase.auth.api + .resetPasswordForEmail('user@email.com') +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/rpc.mdx b/apps/temp-docs/docs/javascript/rpc.mdx new file mode 100644 index 00000000000..5a664ee1a86 --- /dev/null +++ b/apps/temp-docs/docs/javascript/rpc.mdx @@ -0,0 +1,274 @@ +--- +id: rpc +title: "Postgres functions: rpc()" +slug: rpc +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +You can call Postgres functions as a "Remote Procedure Call". + +That's a fancy way of saying that you can put some logic into your database then call it from anywhere. +It's especially useful when the logic rarely changes - like password resets and updates. + + + + + + +```js +const { data, error } = await supabase + .rpc('hello_world') +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + fn + + + required + + + string + +

      +
      + +The function name to call. + +
      + +
    • + + +
    • +

      + + params + + + optional + + + undefined | object + +

      +
      + +The parameters to pass to the function call. + +
      + +
    • + + +
    • +

      + + __namedParameters + + + required + + + object + +

      +
      + +No description provided. + +
      + +
        +
        Properties
        + +
      • +

        + + head + + + required + + + boolean + +

        +
        + +When set to true, no data will be returned. + +
        + +
      • + + +
      • +

        + + count + + + required + + + null | exact | planned | estimated + +

        +
        + +Count algorithm to use to count rows in a table. + +
        + +
      • + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### Call a Postgres function + +This is an example of invoking a Postgres function. + + + + + +```js +const { data, error } = await supabase + .rpc('hello_world') +``` + + + + + + +### With Parameters + + + + + + + +```js +const { data, error } = await supabase + .rpc('echo_city', { name: 'The Shire' }) +``` + + + + + + +### Bulk processing + +You can process large payloads at once using [array parameters](https://postgrest.org/en/stable/api.html#calling-functions-with-array-parameters). + + + + + +```js +const { data, error } = await postgrest + .rpc('echo_cities', { names: ['The Shire', 'Mordor'] }) +``` + + + + + + +### With filters + +Postgres functions that return tables can also be combined with +[Modifiers](/docs/reference/javascript/using-modifiers) and +[Filters](/docs/reference/javascript/using-filters). + + + + + + +```js +const { data, error } = await supabase + .rpc('echo_all_cities') + .select('name, population') + .eq('name', 'The Shire') +``` + + + + + + +### With count option + +You can specify a count option to get the row count along with your data. +Allowed values for count option are `null`, `exact`, `planned` and `estimated`. + + + + + + +```js +const { data, error, count } = await supabase + .rpc('hello_world', {}, { count: 'exact' }) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/select.mdx b/apps/temp-docs/docs/javascript/select.mdx new file mode 100644 index 00000000000..37ee18cf1c9 --- /dev/null +++ b/apps/temp-docs/docs/javascript/select.mdx @@ -0,0 +1,388 @@ +--- +id: select +title: "Fetch data: select()" +slug: select +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Performs vertical filtering with SELECT. + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select() +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + columns + + + optional + + + string + +

      +
      + +The columns to retrieve, separated by commas. + +
      + +
    • + + +
    • +

      + + __namedParameters + + + required + + + object + +

      +
      + +No description provided. + +
      + +
        +
        Properties
        + +
      • +

        + + head + + + required + + + boolean + +

        +
        + +When set to true, select will void data. + +
        + +
      • + + +
      • +

        + + count + + + required + + + null | exact | planned | estimated + +

        +
        + +Count algorithm to use to count rows in a table. + +
        + +
      • + +
      + +
    • + +
    + + +## Notes + +- By default, Supabase projects will return a maximum of 1,000 rows. This setting can be changed in Project API Settings. It's recommended that you keep it low to limit the payload size of accidental or malicious requests. You can use `range()` queries to paginate through your data. +- `select()` can be combined with [Modifiers](/docs/reference/javascript/using-modifiers) +- `select()` can be combined with [Filters](/docs/reference/javascript/using-filters) + + + + + + + + + + +## Examples + +### Getting your data + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select() +``` + + + + + + +### Selecting specific columns + +You can select specific fields from your tables. + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name') +``` + + + + + + +### Query foreign tables + +If your database has foreign key relationships, you can query related tables too. + + + + + +```js +const { data, error } = await supabase + .from('countries') + .select(` + name, + cities ( + name + ) + `) +``` + + + + + + +### Query the same foreign table multiple times + +Sometimes you will need to query the same foreign table twice. +In this case, you can use the name of the joined column to identify +which join you intend to use. For convenience, you can also give an +alias for each column. For example, if we had a shop of products, +and we wanted to get the supplier and the purchaser at the same time +(both in the users) table: + + + + + + +```js +const { data, error } = await supabase + .from('products') + .select(` + id, + supplier:supplier_id ( name ), + purchaser:purchaser_id ( name ) + `) +``` + + + + + + +### Filtering with inner joins + +If you want to filter a table based on a child table's values you can use the `!inner()` function. For example, if you wanted +to select all rows in a `message` table which belong to a user with the `username` "Jane": + + + + + + +```js +const { data, error } = await supabase + .from('messages') + .select('*, users!inner(*)') + .eq('users.username', 'Jane') +``` + + + + + + +### Querying with count option + +You can get the number of rows by using the count option. +Allowed values for count option are `null`, [exact](https://postgrest.org/en/stable/api.html#exact-count), [planned](https://postgrest.org/en/stable/api.html#planned-count) and [estimated](https://postgrest.org/en/stable/api.html#estimated-count). + + + + + + +```js +const { data, error, count } = await supabase + .from('cities') + .select('name', { count: 'exact' }) // if you don't want to return any rows, you can use { count: 'exact', head: true } +``` + + + + + + +### Querying JSON data + +If you have data inside of a JSONB column, you can apply select +and query filters to the data values. Postgres offers a +[number of operators](https://www.postgresql.org/docs/current/functions-json.html) +for querying JSON data. Also see +[PostgREST docs](http://postgrest.org/en/v7.0.0/api.html#json-columns) for more details. + + + + + + +```js +const { data, error } = await supabase + .from('users') + .select(` + id, name, + address->street + `) + .eq('address->postcode', 90210) +``` + + + + + + +### Return data as CSV + +By default the data is returned in JSON format, however you can also request for it to be returned as Comma Separated Values. + + + + + + +```js +const { data, error } = await supabase + .from('users') + .select() + .csv() +``` + + + + + + +### Aborting requests in-flight + +You can use an [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController) to abort requests. Note that `status` and `statusText` doesn't mean anything for aborted requests, since the request wasn't actually fulfilled. + + + + + + +```js +const ac = new AbortController() +supabase + .from('very_big_table') + .select() + .abortSignal(ac.signal) + .then(console.log) +ac.abort() +// { +// error: { +// message: 'FetchError: The user aborted a request.', +// details: '', +// hint: '', +// code: '' +// }, +// data: null, +// body: null, +// count: null, +// status: 400, +// statusText: 'Bad Request' +// } +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/single.mdx b/apps/temp-docs/docs/javascript/single.mdx new file mode 100644 index 00000000000..abcc6a619cc --- /dev/null +++ b/apps/temp-docs/docs/javascript/single.mdx @@ -0,0 +1,74 @@ +--- +id: single +title: "single()" +slug: single +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Retrieves only one row from the result. Result must be one row (e.g. using +`limit`), otherwise this will result in an error. + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .limit(1) + .single() +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .limit(1) + .single() +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/storage-createbucket.mdx b/apps/temp-docs/docs/javascript/storage-createbucket.mdx new file mode 100644 index 00000000000..9da8ce977ad --- /dev/null +++ b/apps/temp-docs/docs/javascript/storage-createbucket.mdx @@ -0,0 +1,142 @@ +--- +id: storage-createbucket +title: "createBucket()" +slug: storage-createbucket +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Creates a new Storage bucket + + + + + +```js +const { data, error } = await supabase + .storage + .createBucket('avatars', { public: false }) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + id + + + required + + + string + +

      +
      + +A unique identifier for the bucket you are creating. + +
      + +
    • + + +
    • +

      + + options + + + required + + + object + +

      +
      + +No description provided. + +
      + +
        +
        Properties
        + +
      • +

        + + public + + + required + + + boolean + +

        +
        + +No description provided. + +
        + +
      • + +
      + +
    • + +
    + + +## Notes + +- Policy permissions required: + - `buckets` permissions: `insert` + - `objects` permissions: none + + + + + + + + + + +## Examples + +### Create bucket + + + + + + + +```js +const { data, error } = await supabase + .storage + .createBucket('avatars', { public: false }) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/storage-deletebucket.mdx b/apps/temp-docs/docs/javascript/storage-deletebucket.mdx new file mode 100644 index 00000000000..b246d8b6339 --- /dev/null +++ b/apps/temp-docs/docs/javascript/storage-deletebucket.mdx @@ -0,0 +1,97 @@ +--- +id: storage-deletebucket +title: "deleteBucket()" +slug: storage-deletebucket +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Deletes an existing bucket. A bucket can't be deleted with existing objects inside it. +You must first `empty()` the bucket. + + + + + +```js +const { data, error } = await supabase + .storage + .deleteBucket('avatars') +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + id + + + required + + + string + +

      +
      + +The unique identifier of the bucket you would like to delete. + +
      + +
    • + +
    + + +## Notes + +- Policy permissions required: + - `buckets` permissions: `select` and `delete` + - `objects` permissions: none + + + + + + + + + + +## Examples + +### Delete bucket + + + + + + + +```js +const { data, error } = await supabase + .storage + .deleteBucket('avatars') +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/storage-emptybucket.mdx b/apps/temp-docs/docs/javascript/storage-emptybucket.mdx new file mode 100644 index 00000000000..698b18d97e1 --- /dev/null +++ b/apps/temp-docs/docs/javascript/storage-emptybucket.mdx @@ -0,0 +1,96 @@ +--- +id: storage-emptybucket +title: "emptyBucket()" +slug: storage-emptybucket +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Removes all objects inside a single bucket. + + + + + +```js +const { data, error } = await supabase + .storage + .emptyBucket('avatars') +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + id + + + required + + + string + +

      +
      + +The unique identifier of the bucket you would like to empty. + +
      + +
    • + +
    + + +## Notes + +- Policy permissions required: + - `buckets` permissions: `select` + - `objects` permissions: `select` and `delete` + + + + + + + + + + +## Examples + +### Empty bucket + + + + + + + +```js +const { data, error } = await supabase + .storage + .emptyBucket('avatars') +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/storage-from-createsignedurl.mdx b/apps/temp-docs/docs/javascript/storage-from-createsignedurl.mdx new file mode 100644 index 00000000000..0be5d2db714 --- /dev/null +++ b/apps/temp-docs/docs/javascript/storage-from-createsignedurl.mdx @@ -0,0 +1,119 @@ +--- +id: storage-from-createsignedurl +title: "from.createSignedUrl()" +slug: storage-from-createsignedurl +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Create signed url to download file without requiring permissions. This URL can be valid for a set number of seconds. + + + + + +```js +const { signedURL, error } = await supabase + .storage + .from('avatars') + .createSignedUrl('folder/avatar1.png', 60) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + path + + + required + + + string + +

      +
      + +The file path to be downloaded, including the current file name. For example `folder/image.png`. + +
      + +
    • + + +
    • +

      + + expiresIn + + + required + + + number + +

      +
      + +The number of seconds until the signed URL expires. For example, `60` for a URL which is valid for one minute. + +
      + +
    • + +
    + + +## Notes + +- Policy permissions required: + - `buckets` permissions: none + - `objects` permissions: `select` + + + + + + + + + + +## Examples + +### Create Signed URL + + + + + + + +```js +const { signedURL, error } = await supabase + .storage + .from('avatars') + .createSignedUrl('folder/avatar1.png', 60) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/storage-from-download.mdx b/apps/temp-docs/docs/javascript/storage-from-download.mdx new file mode 100644 index 00000000000..4222d61947c --- /dev/null +++ b/apps/temp-docs/docs/javascript/storage-from-download.mdx @@ -0,0 +1,98 @@ +--- +id: storage-from-download +title: "from.download()" +slug: storage-from-download +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Downloads a file. + + + + + +```js +const { data, error } = await supabase + .storage + .from('avatars') + .download('folder/avatar1.png') +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + path + + + required + + + string + +

      +
      + +The file path to be downloaded, including the path and file name. For example `folder/image.png`. + +
      + +
    • + +
    + + +## Notes + +- Policy permissions required: + - `buckets` permissions: none + - `objects` permissions: `select` + + + + + + + + + + +## Examples + +### Download file + + + + + + + +```js +const { data, error } = await supabase + .storage + .from('avatars') + .download('folder/avatar1.png') +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/storage-from-getpublicurl.mdx b/apps/temp-docs/docs/javascript/storage-from-getpublicurl.mdx new file mode 100644 index 00000000000..81820c8a65a --- /dev/null +++ b/apps/temp-docs/docs/javascript/storage-from-getpublicurl.mdx @@ -0,0 +1,99 @@ +--- +id: storage-from-getpublicurl +title: "from.getPublicUrl()" +slug: storage-from-getpublicurl +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Retrieve URLs for assets in public buckets + + + + + +```js +const { publicURL, error } = supabase + .storage + .from('public-bucket') + .getPublicUrl('folder/avatar1.png') +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + path + + + required + + + string + +

      +
      + +The file path to be downloaded, including the path and file name. For example `folder/image.png`. + +
      + +
    • + +
    + + +## Notes + +- The bucket needs to be set to public, either via [updateBucket()](/docs/reference/javascript/storage-updatebucket) or by going to Storage on [app.supabase.io](https://app.supabase.io), clicking the overflow menu on a bucket and choosing "Make public" +- Policy permissions required: + - `buckets` permissions: none + - `objects` permissions: none + + + + + + + + + + +## Examples + +### Returns the URL for an asset in a public bucket + + + + + + + +```js +const { publicURL, error } = supabase + .storage + .from('public-bucket') + .getPublicUrl('folder/avatar1.png') +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/storage-from-list.mdx b/apps/temp-docs/docs/javascript/storage-from-list.mdx new file mode 100644 index 00000000000..bda57dd68a5 --- /dev/null +++ b/apps/temp-docs/docs/javascript/storage-from-list.mdx @@ -0,0 +1,148 @@ +--- +id: storage-from-list +title: "from.list()" +slug: storage-from-list +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Lists all the files within a bucket. + + + + + +```js +const { data, error } = await supabase + .storage + .from('avatars') + .list('folder', { + limit: 100, + offset: 0, + sortBy: { column: 'name', order: 'asc' }, + }) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + path + + + optional + + + undefined | string + +

      +
      + +The folder path. + +
      + +
    • + + +
    • +

      + + options + + + optional + + + SearchOptions + +

      +
      + +Search options, including `limit`, `offset`, and `sortBy`. + +
      + +
    • + + +
    • +

      + + parameters + + + optional + + + FetchParameters + +

      +
      + +Fetch parameters, currently only supports `signal`, which is an AbortController's signal + +
      + +
    • + +
    + + +## Notes + +- Policy permissions required: + - `buckets` permissions: none + - `objects` permissions: `select` + + + + + + + + + + +## Examples + +### List files in a bucket + + + + + + + +```js +const { data, error } = await supabase + .storage + .from('avatars') + .list('folder', { + limit: 100, + offset: 0, + sortBy: { column: 'name', order: 'asc' }, + }) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/storage-from-move.mdx b/apps/temp-docs/docs/javascript/storage-from-move.mdx new file mode 100644 index 00000000000..8c00b50ebeb --- /dev/null +++ b/apps/temp-docs/docs/javascript/storage-from-move.mdx @@ -0,0 +1,119 @@ +--- +id: storage-from-move +title: "from.move()" +slug: storage-from-move +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Moves an existing file, optionally renaming it at the same time. + + + + + +```js +const { data, error } = await supabase + .storage + .from('avatars') + .move('public/avatar1.png', 'private/avatar2.png') +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + fromPath + + + required + + + string + +

      +
      + +The original file path, including the current file name. For example `folder/image.png`. + +
      + +
    • + + +
    • +

      + + toPath + + + required + + + string + +

      +
      + +The new file path, including the new file name. For example `folder/image-copy.png`. + +
      + +
    • + +
    + + +## Notes + +- Policy permissions required: + - `buckets` permissions: none + - `objects` permissions: `update` and `select` + + + + + + + + + + +## Examples + +### Move file + + + + + + + +```js +const { data, error } = await supabase + .storage + .from('avatars') + .move('public/avatar1.png', 'private/avatar2.png') +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/storage-from-remove.mdx b/apps/temp-docs/docs/javascript/storage-from-remove.mdx new file mode 100644 index 00000000000..0df1e3bd7cf --- /dev/null +++ b/apps/temp-docs/docs/javascript/storage-from-remove.mdx @@ -0,0 +1,98 @@ +--- +id: storage-from-remove +title: "from.remove()" +slug: storage-from-remove +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Deletes files within the same bucket + + + + + +```js +const { data, error } = await supabase + .storage + .from('avatars') + .remove(['folder/avatar1.png']) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + paths + + + required + + + object + +

      +
      + +An array of files to be deleted, including the path and file name. For example [`folder/image.png`]. + +
      + +
    • + +
    + + +## Notes + +- Policy permissions required: + - `buckets` permissions: none + - `objects` permissions: `delete` and `select` + + + + + + + + + + +## Examples + +### Delete file + + + + + + + +```js +const { data, error } = await supabase + .storage + .from('avatars') + .remove(['folder/avatar1.png']) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/storage-from-update.mdx b/apps/temp-docs/docs/javascript/storage-from-update.mdx new file mode 100644 index 00000000000..11d4fb2be31 --- /dev/null +++ b/apps/temp-docs/docs/javascript/storage-from-update.mdx @@ -0,0 +1,179 @@ +--- +id: storage-from-update +title: "from.update()" +slug: storage-from-update +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Replaces an existing file at the specified path with a new one. + + + + + +```js +const avatarFile = event.target.files[0] +const { data, error } = await supabase + .storage + .from('avatars') + .update('public/avatar1.png', avatarFile, { + cacheControl: '3600', + upsert: false + }) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + path + + + required + + + string + +

      +
      + +The relative file path. Should be of the format `folder/subfolder/filename.png`. The bucket must already exist before attempting to upload. + +
      + +
    • + + +
    • +

      + + fileBody + + + required + + + ArrayBuffer | ArrayBufferView | Blob | Buffer | File | FormData | ReadableStream | ReadableStream | URLSearchParams | string + +

      +
      + +The body of the file to be stored in the bucket. + +
      + +
    • + + +
    • +

      + + fileOptions + + + optional + + + FileOptions + +

      +
      + +HTTP headers. +`cacheControl`: string, the `Cache-Control: max-age=` seconds value. +`contentType`: string, the `Content-Type` header value. Should be specified if using a `fileBody` that is neither `Blob` nor `File` nor `FormData`, otherwise will default to `text/plain;charset=UTF-8`. +`upsert`: boolean, whether to perform an upsert. + +
      + +
    • + +
    + + +## Notes + +- Policy permissions required: + - `buckets` permissions: none + - `objects` permissions: `update` and `select` +- For React Native, using either `Blob`, `File` or `FormData` does not work as intended. Update file using `ArrayBuffer` from base64 file data instead, see example below. + + + + + + + + + + +## Examples + +### Update file + + + + + + + +```js +const avatarFile = event.target.files[0] +const { data, error } = await supabase + .storage + .from('avatars') + .update('public/avatar1.png', avatarFile, { + cacheControl: '3600', + upsert: false + }) +``` + + + + + + +### Update file using `ArrayBuffer` from base64 file data + + + + + + + +```js +import {decode} from 'base64-arraybuffer' + +const { data, error } = await supabase + .storage + .from('avatars') + .update('public/avatar1.png', decode('base64FileData'), { + contentType: 'image/png' + }) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/storage-from-upload.mdx b/apps/temp-docs/docs/javascript/storage-from-upload.mdx new file mode 100644 index 00000000000..bc5fe41832e --- /dev/null +++ b/apps/temp-docs/docs/javascript/storage-from-upload.mdx @@ -0,0 +1,179 @@ +--- +id: storage-from-upload +title: "from.upload()" +slug: storage-from-upload +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Uploads a file to an existing bucket. + + + + + +```js +const avatarFile = event.target.files[0] +const { data, error } = await supabase + .storage + .from('avatars') + .upload('public/avatar1.png', avatarFile, { + cacheControl: '3600', + upsert: false + }) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + path + + + required + + + string + +

      +
      + +The relative file path. Should be of the format `folder/subfolder/filename.png`. The bucket must already exist before attempting to upload. + +
      + +
    • + + +
    • +

      + + fileBody + + + required + + + ArrayBuffer | ArrayBufferView | Blob | Buffer | File | FormData | ReadableStream | ReadableStream | URLSearchParams | string + +

      +
      + +The body of the file to be stored in the bucket. + +
      + +
    • + + +
    • +

      + + fileOptions + + + optional + + + FileOptions + +

      +
      + +HTTP headers. +`cacheControl`: string, the `Cache-Control: max-age=` seconds value. +`contentType`: string, the `Content-Type` header value. Should be specified if using a `fileBody` that is neither `Blob` nor `File` nor `FormData`, otherwise will default to `text/plain;charset=UTF-8`. +`upsert`: boolean, whether to perform an upsert. + +
      + +
    • + +
    + + +## Notes + +- Policy permissions required: + - `buckets` permissions: none + - `objects` permissions: `insert` +- For React Native, using either `Blob`, `File` or `FormData` does not work as intended. Upload file using `ArrayBuffer` from base64 file data instead, see example below. + + + + + + + + + + +## Examples + +### Upload file + + + + + + + +```js +const avatarFile = event.target.files[0] +const { data, error } = await supabase + .storage + .from('avatars') + .upload('public/avatar1.png', avatarFile, { + cacheControl: '3600', + upsert: false + }) +``` + + + + + + +### Upload file using `ArrayBuffer` from base64 file data + + + + + + + +```js +import {decode} from 'base64-arraybuffer' + +const { data, error } = await supabase + .storage + .from('avatars') + .upload('public/avatar1.png', decode('base64FileData'), { + contentType: 'image/png' + }) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/storage-getbucket.mdx b/apps/temp-docs/docs/javascript/storage-getbucket.mdx new file mode 100644 index 00000000000..96da99dac06 --- /dev/null +++ b/apps/temp-docs/docs/javascript/storage-getbucket.mdx @@ -0,0 +1,96 @@ +--- +id: storage-getbucket +title: "getBucket()" +slug: storage-getbucket +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Retrieves the details of an existing Storage bucket. + + + + + +```js +const { data, error } = await supabase + .storage + .getBucket('avatars') +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + id + + + required + + + string + +

      +
      + +The unique identifier of the bucket you would like to retrieve. + +
      + +
    • + +
    + + +## Notes + +- Policy permissions required: + - `buckets` permissions: `select` + - `objects` permissions: none + + + + + + + + + + +## Examples + +### Get bucket + + + + + + + +```js +const { data, error } = await supabase + .storage + .getBucket('avatars') +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/storage-listbuckets.mdx b/apps/temp-docs/docs/javascript/storage-listbuckets.mdx new file mode 100644 index 00000000000..f78bb44a61e --- /dev/null +++ b/apps/temp-docs/docs/javascript/storage-listbuckets.mdx @@ -0,0 +1,72 @@ +--- +id: storage-listbuckets +title: "listBuckets()" +slug: storage-listbuckets +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Retrieves the details of all Storage buckets within an existing product. + + + + + +```js +const { data, error } = await supabase + .storage + .listBuckets() +``` + + + + + + + + + + +## Notes + +- Policy permissions required: + - `buckets` permissions: `select` + - `objects` permissions: none + + + + + + + + + + +## Examples + +### List buckets + + + + + + + +```js +const { data, error } = await supabase + .storage + .listBuckets() +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/storage-updatebucket.mdx b/apps/temp-docs/docs/javascript/storage-updatebucket.mdx new file mode 100644 index 00000000000..903aa7c4415 --- /dev/null +++ b/apps/temp-docs/docs/javascript/storage-updatebucket.mdx @@ -0,0 +1,142 @@ +--- +id: storage-updatebucket +title: "updateBucket()" +slug: storage-updatebucket +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Updates a new Storage bucket + + + + + +```js +const { data, error } = await supabase + .storage + .updateBucket('avatars', { public: false }) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + id + + + required + + + string + +

      +
      + +A unique identifier for the bucket you are creating. + +
      + +
    • + + +
    • +

      + + options + + + required + + + object + +

      +
      + +No description provided. + +
      + +
        +
        Properties
        + +
      • +

        + + public + + + required + + + boolean + +

        +
        + +No description provided. + +
        + +
      • + +
      + +
    • + +
    + + +## Notes + +- Policy permissions required: + - `buckets` permissions: `update` + - `objects` permissions: none + + + + + + + + + + +## Examples + +### Update bucket + + + + + + + +```js +const { data, error } = await supabase + .storage + .updateBucket('avatars', { public: false }) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/subscribe.mdx b/apps/temp-docs/docs/javascript/subscribe.mdx new file mode 100644 index 00000000000..7d0139bae12 --- /dev/null +++ b/apps/temp-docs/docs/javascript/subscribe.mdx @@ -0,0 +1,281 @@ +--- +id: subscribe +title: "on().subscribe()" +slug: subscribe +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Subscribe to realtime changes in your databse. + + + + + +```js +const mySubscription = supabase + .from('*') + .on('*', payload => { + console.log('Change received!', payload) + }) + .subscribe() +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + event + + + required + + + SupabaseEventTypes + +

      +
      + +The database event which you would like to receive updates for, or you can use the special wildcard `*` to listen to all changes. + +
      + +
    • + + +
    • +

      + + callback + + + required + + + object + +

      +
      + +A callback that will handle the payload that is sent whenever your database changes. + +
      + +
    • + +
    + + +## Notes + +- Realtime is disabled by default for new Projects for better database performance and security. You can turn it on by [managing replication](/docs/guides/api#managing-realtime). +- If you want to receive the "previous" data for updates and deletes, you will need to set `REPLICA IDENTITY` to `FULL`, like this: `ALTER TABLE your_table REPLICA IDENTITY FULL;` + + + + + + + + + + +## Examples + +### Listen to all database changes + + + + + + + +```js +const mySubscription = supabase + .from('*') + .on('*', payload => { + console.log('Change received!', payload) + }) + .subscribe() +``` + + + + + + +### Listening to a specific table + + + + + + + +```js +const mySubscription = supabase + .from('countries') + .on('*', payload => { + console.log('Change received!', payload) + }) + .subscribe() +``` + + + + + + +### Listening to inserts + + + + + + + +```js +const mySubscription = supabase + .from('countries') + .on('INSERT', payload => { + console.log('Change received!', payload) + }) + .subscribe() +``` + + + + + + +### Listening to updates + +By default, Supabase will send only the updated record. If you want to receive the previous values as well you can +enable full replication for the table you are listening too: + +```sql +alter table "your_table" replica identity full; +``` + + + + + + +```js +const mySubscription = supabase + .from('countries') + .on('UPDATE', payload => { + console.log('Change received!', payload) + }) + .subscribe() +``` + + + + + + +### Listening to deletes + +By default, Supabase does not send deleted records. If you want to receive the deleted record you can +enable full replication for the table you are listening too: + +```sql +alter table "your_table" replica identity full; +``` + + + + + + +```js +const mySubscription = supabase + .from('countries') + .on('DELETE', payload => { + console.log('Change received!', payload) + }) + .subscribe() +``` + + + + + + +### Listening to multiple events + +You can chain listeners if you want to listen to multiple events for each table. + + + + + +```js +const mySubscription = supabase + .from('countries') + .on('INSERT', handleRecordInserted) + .on('DELETE', handleRecordDeleted) + .subscribe() +``` + + + + + + +### Listening to row level changes + +You can listen to individual rows using the format `{table}:{col}=eq.{val}` - where `{col}` is the column name, and `{val}` is the value which you want to match. + + + + + +```js +const mySubscription = supabase + .from('countries:id=eq.200') + .on('UPDATE', handleRecordUpdated) + .subscribe() +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/textsearch.mdx b/apps/temp-docs/docs/javascript/textsearch.mdx new file mode 100644 index 00000000000..6354b2f39a6 --- /dev/null +++ b/apps/temp-docs/docs/javascript/textsearch.mdx @@ -0,0 +1,234 @@ +--- +id: textsearch +title: ".textSearch()" +slug: textsearch +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose tsvector value on the stated `column` matches +to_tsquery(`query`). + + + +## Parameters + + +
      + +
    • +

      + + column + + + required + + + object + +

      +
      + +The column to filter on. + +
      + +
    • + + +
    • +

      + + query + + + required + + + string + +

      +
      + +The Postgres tsquery string to filter with. + +
      + +
    • + + +
    • +

      + + __namedParameters + + + required + + + object + +

      +
      + +No description provided. + +
      + +
        +
        Properties
        + +
      • +

        + + config + + + required + + + undefined | string + +

        +
        + +The text search configuration to use. + +
        + +
      • + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### Text search + + + + + + + +```js +const { data, error } = await supabase + .from('quotes') + .select('catchphrase') + .textSearch('catchphrase', `'fat' & 'cat'`, { + config: 'english' + }) +``` + + + + + + +### Basic normalization + +Uses PostgreSQL's `plainto_tsquery` function. + + + + + +```js +const { data, error } = await supabase + .from('quotes') + .select('catchphrase') + .textSearch('catchphrase', `'fat' & 'cat'`, { + type: 'plain', + config: 'english' + }) +``` + + + + + + +### Full normalization + +Uses PostgreSQL's `phraseto_tsquery` function. + + + + + +```js +const { data, error } = await supabase + .from('quotes') + .select('catchphrase') + .textSearch('catchphrase', `'fat' & 'cat'`, { + type: 'phrase', + config: 'english' + }) +``` + + + + + + +### Full normalization + +Uses PostgreSQL's `websearch_to_tsquery` function. +This function will never raise syntax errors, which makes it possible to use raw user-supplied input for search, and can be used +with advanced operators. + +- `unquoted text`: text not inside quote marks will be converted to terms separated by & operators, as if processed by plainto_tsquery. +- `"quoted text"`: text inside quote marks will be converted to terms separated by <-> operators, as if processed by phraseto_tsquery. +- `OR`: the word “or” will be converted to the | operator. +- `-`: a dash will be converted to the ! operator. + + + + + + +```js +const { data, error } = await supabase + .from('quotes') + .select('catchphrase') + .textSearch('catchphrase', `'fat or cat'`, { + type: 'websearch', + config: 'english' + }) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/update.mdx b/apps/temp-docs/docs/javascript/update.mdx new file mode 100644 index 00000000000..dca58efa64d --- /dev/null +++ b/apps/temp-docs/docs/javascript/update.mdx @@ -0,0 +1,195 @@ +--- +id: update +title: "Modify data: update()" +slug: update +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Performs an UPDATE on the table. + + + + + +```js +const { data, error } = await supabase + .from('cities') + .update({ name: 'Middle Earth' }) + .match({ name: 'Auckland' }) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + values + + + required + + + Partial + +

      +
      + +The values to update. + +
      + +
    • + + +
    • +

      + + __namedParameters + + + required + + + object + +

      +
      + +No description provided. + +
      + +
        +
        Properties
        + +
      • +

        + + returning + + + required + + + minimal | representation + +

        +
        + +By default the updated record is returned. Set this to 'minimal' if you don't need this value. + +
        + +
      • + + +
      • +

        + + count + + + required + + + null | exact | planned | estimated + +

        +
        + +Count algorithm to use to count rows in a table. + +
        + +
      • + +
      + +
    • + +
    + + +## Notes + +- `update()` should always be combined with [Filters](/docs/reference/javascript/using-filters) to target the item(s) you wish to update. + + + + + + + + + + +## Examples + +### Updating your data + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .update({ name: 'Middle Earth' }) + .match({ name: 'Auckland' }) +``` + + + + + + +### Updating JSON data + +Postgres offers a +[number of operators](https://www.postgresql.org/docs/current/functions-json.html) +for working with JSON data. Right now it is only possible to update an entire JSON document, +but we are [working on ideas](https://github.com/PostgREST/postgrest/issues/465) for updating individual keys. + + + + + + +```js +const { data, error } = await supabase + .from('users') + .update(` + address: { + street: 'Melrose Place', + postcode: 90210 + } + `) + .eq('address->postcode', 90210) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/upsert.mdx b/apps/temp-docs/docs/javascript/upsert.mdx new file mode 100644 index 00000000000..a0b1edc28ae --- /dev/null +++ b/apps/temp-docs/docs/javascript/upsert.mdx @@ -0,0 +1,281 @@ +--- +id: upsert +title: "Upsert data: upsert()" +slug: upsert +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Performs an UPSERT into the table. + + + + + +```js +const { data, error } = await supabase + .from('messages') + .upsert({ id: 3, message: 'foo', username: 'supabot' }) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + values + + + required + + + Partial | array + +

      +
      + +The values to insert. + +
      + +
    • + + +
    • +

      + + __namedParameters + + + required + + + object + +

      +
      + +No description provided. + +
      + +
        +
        Properties
        + +
      • +

        + + returning + + + required + + + minimal | representation + +

        +
        + +By default the new record is returned. Set this to 'minimal' if you don't need this value. + +
        + +
      • + + +
      • +

        + + onConflict + + + required + + + undefined | string + +

        +
        + +By specifying the `on_conflict` query parameter, you can make UPSERT work on a column(s) that has a UNIQUE constraint. + +
        + +
      • + + +
      • +

        + + ignoreDuplicates + + + required + + + boolean + +

        +
        + +Specifies if duplicate rows should be ignored and not inserted. + +
        + +
      • + + +
      • +

        + + count + + + required + + + null | exact | planned | estimated + +

        +
        + +Count algorithm to use to count rows in a table. + +
        + +
      • + +
      + +
    • + +
    + + +## Notes + +- Primary keys should be included in the data payload in order for an update to work correctly. +- Primary keys must be natural, not surrogate. There are however, [workarounds](https://github.com/PostgREST/postgrest/issues/1118) for surrogate primary keys. + + + + + + + + + + +## Examples + +### Upsert your data + + + + + + + +```js +const { data, error } = await supabase + .from('messages') + .upsert({ id: 3, message: 'foo', username: 'supabot' }) +``` + + + + + + +### Bulk Upsert your data + + + + + + + +```js +const { data, error } = await supabase + .from('messages') + .upsert([ + { id: 3, message: 'foo', username: 'supabot' }, + { id: 4, message: 'bar', username: 'supabot' } + ]) +``` + + + + + + +### Upserting into tables with constraints + +Running the following will cause supabase to upsert data into the `users` table. +If the username 'supabot' already exists, the `onConflict` argument tells supabase to overwrite that row +based on the column passed into `onConflict`. + + + + + + +```js +const { data, error } = await supabase + .from('users') + .upsert({ username: 'supabot' }, { onConflict: 'username' }) +``` + + + + + + +### Return the exact number of rows + + + + + + + +```js +const { data, error, count } = await supabase + .from('users') + .upsert({ + id: 3, message: 'foo', + username: 'supabot' + }, { + count: 'exact' + }) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/using-filters.mdx b/apps/temp-docs/docs/javascript/using-filters.mdx new file mode 100644 index 00000000000..b4ce9a4811e --- /dev/null +++ b/apps/temp-docs/docs/javascript/using-filters.mdx @@ -0,0 +1,61 @@ +--- +id: using-filters +title: "Using Filters" +slug: using-filters +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Filters can be used on `select()`, `update()`, and `delete()` queries. + +If a Postgres function returns a table response, you can also apply filters. + +### Applying Filters + +You must apply your filters to the end of your query. For example: + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .eq('name', 'The Shire') // Correct + +const { data, error } = await supabase + .from('cities') + .eq('name', 'The Shire') // Incorrect + .select('name, country_id') +``` + +### Chaining + +Filters can be chained together to produce advanced queries. For example: + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .gte('population', 1000) + .lt('population', 10000) +``` + +### Conditional Chaining + +Filters can be built up one step at a time and then executed. For example: + +```js +const filterByName = null +const filterPopLow = 1000 +const filterPopHigh = 10000 + +let query = supabase + .from('cities') + .select('name, country_id') + +if (filterByName) { query = query.eq('name', filterByName) } +if (filterPopLow) { query = query.gte('population', filterPopLow) } +if (filterPopHigh) { query = query.lt('population', filterPopHigh) } + +const { data, error } = await query +``` \ No newline at end of file diff --git a/apps/temp-docs/docs/javascript/using-modifiers.mdx b/apps/temp-docs/docs/javascript/using-modifiers.mdx new file mode 100644 index 00000000000..cad96411fd3 --- /dev/null +++ b/apps/temp-docs/docs/javascript/using-modifiers.mdx @@ -0,0 +1,13 @@ +--- +id: using-modifiers +title: "Using Modifiers" +slug: using-modifiers +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Modifiers can be used on `select()` queries. + +If a Postgres function returns a table response, you can also apply modifiers to the `rpc()` function. \ No newline at end of file diff --git a/apps/temp-docs/docs/postgres/changing-timezones.mdx b/apps/temp-docs/docs/postgres/changing-timezones.mdx new file mode 100644 index 00000000000..d05e32afc8b --- /dev/null +++ b/apps/temp-docs/docs/postgres/changing-timezones.mdx @@ -0,0 +1,119 @@ +--- +id: changing-timezones +title: "Changing Timezones" +slug: changing-timezones +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/postgres.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Data types. + + + + + + +```sql +alter database postgres +set timezone to 'America/New_York'; +``` + + + + + + + + + + +## Notes + +- View a full list of timezones on [Wikipedia](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones). + + + + + + + + + + +## Examples + +### Change timezone + + + + + + + +```sql +alter database postgres +set timezone to 'America/New_York'; +``` + + + + + + +### Full list of timezones + +Get a full list of timezones supported by your database. This will return the following columns: + +- `name`: Time zone name +- `abbrev`: Time zone abbreviation +- `utc_offset`: Offset from UTC (positive means east of Greenwich) +- `is_dst`: True if currently observing daylight savings + + + + + + +```sql +select name, abbrev, utc_offset, is_dst +from pg_timezone_names() +order by name; +``` + + + + + + +### Search for a specific timezone + +Use `ilike` (case insensitive search) to find specific timezones. + + + + + +```sql +select * +from pg_timezone_names() +where name ilike '%york%'; +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/postgres/columns.mdx b/apps/temp-docs/docs/postgres/columns.mdx new file mode 100644 index 00000000000..0ccaa830381 --- /dev/null +++ b/apps/temp-docs/docs/postgres/columns.mdx @@ -0,0 +1,95 @@ +--- +id: columns +title: "Columns" +slug: columns +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/postgres.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Creating columns. + + + + + + +```sql +create table table_name ( + id integer primary key, + data jsonb, + name text +); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### During table creation + + + + + + + +```sql +create table table_name ( + id integer primary key, + data jsonb, + name text +); +``` + + + + + + +### Create column + + + + + + + +```sql +alter table new_table +add new_column text; +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/postgres/connection-strings.mdx b/apps/temp-docs/docs/postgres/connection-strings.mdx new file mode 100644 index 00000000000..12e4f919c9c --- /dev/null +++ b/apps/temp-docs/docs/postgres/connection-strings.mdx @@ -0,0 +1,135 @@ +--- +id: connection-strings +title: "Connection Strings" +slug: connection-strings +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/postgres.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +There are various ways to connect to your database, depending on the configuration of your Postgres instance and the tool which you are connecting with. + + + + + + +```bash +postgres://postgres:postgres@localhost:5432/postgres +# or +postgresql://postgres:postgres@localhost:5432/postgres +``` + + + + + + + + + + +## Notes + +- [Official Documentation](https://www.postgresql.org/docs/current/libpq-connect.html). +- Avoid using special characters usernames and passwords. If you use special characters in a connection URL, you'll need to URL encode any special characters. + + + + + + + + + + +## Examples + +### Basic connection string + +If you're using a default setup, your postgres connection string will likely be in the format: + +`postgres://{user}:{password}@{host}:{port}/{database_name}` + + + + + + +```bash +postgres://postgres:postgres@localhost:5432/postgres +# or +postgresql://postgres:postgres@localhost:5432/postgres +``` + + + + + + +### JDBC + +See full [documentation](http://jdbc.postgresql.org/documentation/head/connect.html). + + + + + +```bash +jdbc:postgresql://{host}:{port}/{database_name} +``` + + + + + + +### ADO.NET + +See full [documentation](http://npgsql.projects.postgresql.org/docs/manual/UserManual.html). + + + + + +```bash +Server=host;Port=5432;User Id=username;Password=secret;Database=database_name; +``` + + + + + + +### PHP + +See full [documentation](http://php.net/manual/en/book.pgsql.php). + + + + + +```bash +host=hostname port=5432 dbname=databasename user=username password=secret +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/postgres/database-passwords.mdx b/apps/temp-docs/docs/postgres/database-passwords.mdx new file mode 100644 index 00000000000..9f58234b1a1 --- /dev/null +++ b/apps/temp-docs/docs/postgres/database-passwords.mdx @@ -0,0 +1,53 @@ +--- +id: database-passwords +title: "Database Passwords" +slug: database-passwords +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/postgres.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Manage the passwords of your database users using any super user. + + + + + + + + + + + + + + + + + + + + +## Examples + +### Password reset + + + + + + + +```sql +alter user postgres +with password 'new_password'; +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/postgres/database-users.mdx b/apps/temp-docs/docs/postgres/database-users.mdx new file mode 100644 index 00000000000..8ccca2ce94a --- /dev/null +++ b/apps/temp-docs/docs/postgres/database-users.mdx @@ -0,0 +1,53 @@ +--- +id: database-users +title: "Database Users" +slug: database-users +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/postgres.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Users and Roles are almost interchangeable. + + + + + + + + + + + + + + + + + + + + +## Examples + +### Create New User + + + + + + + +```sql +create user new_user +with password 'hello'; +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/postgres/index.mdx b/apps/temp-docs/docs/postgres/index.mdx new file mode 100644 index 00000000000..b6641472785 --- /dev/null +++ b/apps/temp-docs/docs/postgres/index.mdx @@ -0,0 +1,15 @@ +--- +id: index +title: "Getting started" +slug: getting-started +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/postgres.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + + +PostgreSQL, also known as Postgres, is a free and open-source relational +database management system emphasizing extensibility and SQL compliance. +It was originally named POSTGRES, referring to its origins as a successor +to the Ingres database developed at the University of California, Berkeley. \ No newline at end of file diff --git a/apps/temp-docs/docs/postgres/publications.mdx b/apps/temp-docs/docs/postgres/publications.mdx new file mode 100644 index 00000000000..87559a38e34 --- /dev/null +++ b/apps/temp-docs/docs/postgres/publications.mdx @@ -0,0 +1,210 @@ +--- +id: publications +title: "Publications" +slug: publications +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/postgres.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Publications are a way of grouping changes generated from a table or a group of tables. +These changes can then be sent to other systems (usually another Postgres database). + + + + + + + + + + + + + + + + + + + + +## Examples + +### Create a Publication + +This publication will contain all changes to all tables. + + + + + + +```sql +create publication publication_name +for all tables; +``` + + + + + + +### Create a Publication which listens to individual tables + + + + + + + +```sql +create publication publication_name +for table table_one, table_two; +``` + + + + + + +### Add tables to an existing publication + + + + + + + +```sql +alter publication publication_name +add table table_name; +``` + + + + + + +### Listens to inserts only + + + + + + + +```sql +create publication publication_name +for all tables +with (publish = 'insert'); +``` + + + + + + +### Listens to updates only + + + + + + + +```sql +create publication publication_name +for all tables +with (publish = 'update'); +``` + + + + + + +### Listens to deletions only + + + + + + + +```sql +create publication publication_name +for all tables +with (publish = 'delete'); +``` + + + + + + +### Remove a Publication + + + + + + + +```sql +drop publication if exists publication_name; +``` + + + + + + +### Recreate a Publication + +If you are planning to re-create a publication, it's best to do it in a transaction to ensure the operation succeeds. + + + + + + +```sql +begin; + -- remove the realtime publication + drop publication if exists publication_name; + + -- re-create the publication but don't enable it for any tables + create publication publication_name; +commit; +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/postgres/schemas.mdx b/apps/temp-docs/docs/postgres/schemas.mdx new file mode 100644 index 00000000000..ad4fbf6d9ef --- /dev/null +++ b/apps/temp-docs/docs/postgres/schemas.mdx @@ -0,0 +1,114 @@ +--- +id: schemas +title: "Schemas" +slug: schemas +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/postgres.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Schemas are like "folders". They help to keep your database organized. + +Schemas are particularly useful for security. You can set different permissions on each schema. +For example, you might want to use a `public` schema for user-facing data, and an `auth` schema for all logins and secured data. + + + + + + +```sql +create schema schema_name; +``` + + + + + + + + + + +## Notes + +- Schemas contain [tables](/docs/reference/postgres/tables), columns, triggers, functions, etc. +- Postgres comes with a `public` schema set up by default. +- It is best practice to use lowercase and underscores when naming schemas. For example: `schema_name`, not `Schema Name`. + + + + + + + + + + +## Examples + +### Creating a schema + + + + + + + +```sql +create schema schema_name; +``` + + + + + + +### Removing a schema + + + + + + + +```sql +drop schema if exists schema_name; +``` + + + + + + +### Using special characters + +Although it's not recommended, you can use uppercase and spaces when naming your schema by wrapping the name with double-quotes. +As a result, you will always need to use double-quotes when referencing your schema. + + + + + + +```sql +create schema "Schema Name"; +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/postgres/tables.mdx b/apps/temp-docs/docs/postgres/tables.mdx new file mode 100644 index 00000000000..05df802a961 --- /dev/null +++ b/apps/temp-docs/docs/postgres/tables.mdx @@ -0,0 +1,161 @@ +--- +id: tables +title: "Tables" +slug: tables +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/postgres.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Tables are similar to excel spreadsheets. They contain columns & rows of data. There are a few key differences from a spreadsheet however: + +- Every column is a strict type of data. When you set up a column, you must define what "data type" it is. +- Tables can be joined together through relationships. For example you can have a "users" table, which is joined to a "teams" table. + + + + + + +```sql +create table table_name ( + id integer primary key, + data jsonb, + name text +); + +# with schema +create table schema_name.table_name ( + id integer primary key, + data jsonb, + name text +); +``` + + + + + + + + + + +## Notes + +- Tables contain columns, rows, triggers, comments, +- It is best practice to use lowercase and underscores when naming tables. For example: `table_name`, not `Table Name`. +- Tables belong to [schemas](/docs/reference/postgres/schemas). If you don't explicitly pass the schema, Postgres will assume that you want to create the table in the `public` schema. + + + + + + + + + + +## Examples + +### Create table + + + + + + + +```sql +create table table_name ( + id integer primary key, + data jsonb, + name text +); + +# with schema +create table schema_name.table_name ( + id integer primary key, + data jsonb, + name text +); +``` + + + + + + +### Primary keys using multiple columns + + + + + + + +```sql +create table table_name ( + column_1 data_type, + column_2 data_type + -- Constraints: + primary key (column_1, column_2) +); +``` + + + + + + +### Multiple foreign keys to the same table + + + + + + + +```sql +alter table table_name + add constraint constraint_name_1 foreign key (column_1) references foreign_table(id), + add constraint constraint_name_2 foreign key (column_2) references foreign_table(id); +``` + + + + + + +### Delete a table + + + + + + + +```sql +delete table if exists table_name; +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/cli/.gitkeep b/apps/temp-docs/docs/reference/cli/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/apps/temp-docs/docs/reference/cli/about.mdx b/apps/temp-docs/docs/reference/cli/about.mdx new file mode 100644 index 00000000000..2b49cb7f3a9 --- /dev/null +++ b/apps/temp-docs/docs/reference/cli/about.mdx @@ -0,0 +1,25 @@ +--- +id: index +title: "Getting started" +slug: getting-started +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/cli.yml +--- + +The Supabase CLI can be found in our [CLI](https://github.com/supabase/cli) repository. + +The CLI is still under heavy development, but it will contain all the functionality for working with Supabase projects and the Supabase platform. + +- [x] Running Supabase locally +- [x] Self-hosting +- [ ] Managing database migrations (in progress) +- [ ] Pushing your local changes to production +- [ ] Manage your Supabase Account +- [ ] Manage your Supabase Projects +- [ ] Generating types directly from your database schema +- [ ] Generating API and validation schemas from your database + +## Installing the CLI + +```bash +npm install supabase -g +``` diff --git a/apps/temp-docs/docs/reference/cli/config-reference.mdx b/apps/temp-docs/docs/reference/cli/config-reference.mdx new file mode 100644 index 00000000000..98a85be9067 --- /dev/null +++ b/apps/temp-docs/docs/reference/cli/config-reference.mdx @@ -0,0 +1,35 @@ +--- +id: config-reference +title: "Config reference" +slug: config-reference +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/cli.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +The config file resides in `supabase/config.json` after you run `supabase init`. + +#### `projectId` (required) + +A string used to distinguish different Supabase projects on the same host. Defaults to the working directory name when running `supabase init`. + +#### `ports.api` (required) + +Host port used for the API URL. Defaults to `54321`. + +#### `ports.db` (required) + +Host port used for the DB URL. Defaults to `54322`. + +#### `ports.studio` (required) + +Host port used for Supabase Studio. Defaults to `54323`. + +#### `ports.inbucket` (optional) + +Host port used for the web interface of Inbucket email testing server. When not specified, emails are automatically confirmed. When specified, emails are not sent to the recipient, but rather monitored and accessible via the web interface. + +#### `dbVersion` (required) + +Server version number used for the database. This needs to match the server version number of the remote database you intend to link to with `supabase db remote set`. You can retrieve it by running `SHOW server_version_num`. \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/cli/index.mdx b/apps/temp-docs/docs/reference/cli/index.mdx new file mode 100644 index 00000000000..257df67ebac --- /dev/null +++ b/apps/temp-docs/docs/reference/cli/index.mdx @@ -0,0 +1,27 @@ +--- +id: index +title: "About" +slug: about +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/cli.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +The Supabase CLI can be found in our [CLI](https://github.com/supabase/cli) repository. + +- [x] Running Supabase locally +- [x] Managing database migrations +- [x] Pushing your local changes to production +- [ ] Manage your Supabase Account +- [ ] Manage your Supabase Projects +- [ ] Generating types directly from your database schema +- [ ] Generating API and validation schemas from your database + +## Installing the CLI + +Installation instructions can be found [here](https://github.com/supabase/cli#install-the-cli). + +## Support + +Report issues to our [issue tracker](https://github.com/supabase/cli/issues). \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/cli/supabase-db-branch-create.mdx b/apps/temp-docs/docs/reference/cli/supabase-db-branch-create.mdx new file mode 100644 index 00000000000..276da242581 --- /dev/null +++ b/apps/temp-docs/docs/reference/cli/supabase-db-branch-create.mdx @@ -0,0 +1,16 @@ +--- +id: supabase-db-branch-create +title: "supabase db branch create" +slug: supabase-db-branch-create +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/cli.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +``` +Create a branch. + +Usage: + supabase db branch create +``` \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/cli/supabase-db-branch-delete.mdx b/apps/temp-docs/docs/reference/cli/supabase-db-branch-delete.mdx new file mode 100644 index 00000000000..37ddb844a7c --- /dev/null +++ b/apps/temp-docs/docs/reference/cli/supabase-db-branch-delete.mdx @@ -0,0 +1,16 @@ +--- +id: supabase-db-branch-delete +title: "supabase db branch delete" +slug: supabase-db-branch-delete +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/cli.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +``` +Delete a branch. + +Usage: + supabase db branch delete +``` \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/cli/supabase-db-branch-list.mdx b/apps/temp-docs/docs/reference/cli/supabase-db-branch-list.mdx new file mode 100644 index 00000000000..9933f256e6e --- /dev/null +++ b/apps/temp-docs/docs/reference/cli/supabase-db-branch-list.mdx @@ -0,0 +1,16 @@ +--- +id: supabase-db-branch-list +title: "supabase db branch list" +slug: supabase-db-branch-list +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/cli.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +``` +List branches. + +Usage: + supabase db branch list +``` \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/cli/supabase-db-changes.mdx b/apps/temp-docs/docs/reference/cli/supabase-db-changes.mdx new file mode 100644 index 00000000000..2b4bdbe6cf1 --- /dev/null +++ b/apps/temp-docs/docs/reference/cli/supabase-db-changes.mdx @@ -0,0 +1,16 @@ +--- +id: supabase-db-changes +title: "supabase db changes" +slug: supabase-db-changes +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/cli.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +``` +Diffs the local database with current migrations, then print the diff to standard output. + +Usage: + supabase db changes +``` \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/cli/supabase-db-commit.mdx b/apps/temp-docs/docs/reference/cli/supabase-db-commit.mdx new file mode 100644 index 00000000000..8823a7fa6d3 --- /dev/null +++ b/apps/temp-docs/docs/reference/cli/supabase-db-commit.mdx @@ -0,0 +1,16 @@ +--- +id: supabase-db-commit +title: "supabase db commit" +slug: supabase-db-commit +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/cli.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +``` +Diffs the local database with current migrations, writing it as a new migration. + +Usage: + supabase db commit +``` \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/cli/supabase-db-push.mdx b/apps/temp-docs/docs/reference/cli/supabase-db-push.mdx new file mode 100644 index 00000000000..0b3435b4186 --- /dev/null +++ b/apps/temp-docs/docs/reference/cli/supabase-db-push.mdx @@ -0,0 +1,16 @@ +--- +id: supabase-db-push +title: "supabase db push" +slug: supabase-db-push +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/cli.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +``` +Push new migrations to the remote database. + +Usage: + supabase db push +``` \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/cli/supabase-db-remote-commit.mdx b/apps/temp-docs/docs/reference/cli/supabase-db-remote-commit.mdx new file mode 100644 index 00000000000..c09e1ee77e0 --- /dev/null +++ b/apps/temp-docs/docs/reference/cli/supabase-db-remote-commit.mdx @@ -0,0 +1,16 @@ +--- +id: supabase-db-remote-commit +title: "supabase db remote commit" +slug: supabase-db-remote-commit +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/cli.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +``` +Commit changes on the remote database since the last pushed migration. + +Usage: + supabase db remote commit +``` \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/cli/supabase-db-remote-set.mdx b/apps/temp-docs/docs/reference/cli/supabase-db-remote-set.mdx new file mode 100644 index 00000000000..93a240ee0a5 --- /dev/null +++ b/apps/temp-docs/docs/reference/cli/supabase-db-remote-set.mdx @@ -0,0 +1,16 @@ +--- +id: supabase-db-remote-set +title: "supabase db remote set" +slug: supabase-db-remote-set +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/cli.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +``` +Set the remote database to push migrations to. + +Usage: + supabase db remote set +``` \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/cli/supabase-db-reset.mdx b/apps/temp-docs/docs/reference/cli/supabase-db-reset.mdx new file mode 100644 index 00000000000..dea74ae7534 --- /dev/null +++ b/apps/temp-docs/docs/reference/cli/supabase-db-reset.mdx @@ -0,0 +1,16 @@ +--- +id: supabase-db-reset +title: "supabase db reset" +slug: supabase-db-reset +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/cli.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +``` +Resets the local database to reflect current migrations. Any changes on the local database that is not committed will be lost. + +Usage: + supabase db reset +``` \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/cli/supabase-db-switch.mdx b/apps/temp-docs/docs/reference/cli/supabase-db-switch.mdx new file mode 100644 index 00000000000..faf65f86268 --- /dev/null +++ b/apps/temp-docs/docs/reference/cli/supabase-db-switch.mdx @@ -0,0 +1,16 @@ +--- +id: supabase-db-switch +title: "supabase db switch" +slug: supabase-db-switch +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/cli.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +``` +Switch branches. + +Usage: + supabase db switch +``` \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/cli/supabase-eject.mdx b/apps/temp-docs/docs/reference/cli/supabase-eject.mdx new file mode 100644 index 00000000000..e7d12225dab --- /dev/null +++ b/apps/temp-docs/docs/reference/cli/supabase-eject.mdx @@ -0,0 +1,17 @@ +--- +id: supabase-eject +title: "supabase eject" +slug: supabase-eject +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/cli.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +```bash +supabase eject +``` + +Run in any folder to create a `docker` folder with a `docker-compose.yml`. This is useful for self-hosting or adding custom configuration. + +See our [Self Hosting](/docs/guides/hosting/overview) docs for more details. \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/cli/supabase-help.mdx b/apps/temp-docs/docs/reference/cli/supabase-help.mdx new file mode 100644 index 00000000000..8494f7305ee --- /dev/null +++ b/apps/temp-docs/docs/reference/cli/supabase-help.mdx @@ -0,0 +1,17 @@ +--- +id: supabase-help +title: "supabase help" +slug: supabase-help +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/cli.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +``` +Help provides help for any command in the application. +Simply type supabase help [path to command] for full details. + +Usage: + supabase help [command] +``` \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/cli/supabase-init.mdx b/apps/temp-docs/docs/reference/cli/supabase-init.mdx new file mode 100644 index 00000000000..21472d298d8 --- /dev/null +++ b/apps/temp-docs/docs/reference/cli/supabase-init.mdx @@ -0,0 +1,16 @@ +--- +id: supabase-init +title: "supabase init" +slug: supabase-init +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/cli.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +``` +Initialize a project to use Supabase CLI. + +Usage: + supabase init +``` \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/cli/supabase-migration-new.mdx b/apps/temp-docs/docs/reference/cli/supabase-migration-new.mdx new file mode 100644 index 00000000000..90d692a1598 --- /dev/null +++ b/apps/temp-docs/docs/reference/cli/supabase-migration-new.mdx @@ -0,0 +1,16 @@ +--- +id: supabase-migration-new +title: "supabase migration new" +slug: supabase-migration-new +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/cli.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +``` +Create an empty migration. + +Usage: + supabase migration new +``` \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/cli/supabase-start.mdx b/apps/temp-docs/docs/reference/cli/supabase-start.mdx new file mode 100644 index 00000000000..d7eb6395774 --- /dev/null +++ b/apps/temp-docs/docs/reference/cli/supabase-start.mdx @@ -0,0 +1,16 @@ +--- +id: supabase-start +title: "supabase start" +slug: supabase-start +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/cli.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +``` +Start the Supabase local development setup. + +Usage: + supabase start +``` \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/cli/supabase-stop.mdx b/apps/temp-docs/docs/reference/cli/supabase-stop.mdx new file mode 100644 index 00000000000..ca813c5a1c2 --- /dev/null +++ b/apps/temp-docs/docs/reference/cli/supabase-stop.mdx @@ -0,0 +1,15 @@ +--- +id: supabase-stop +title: "supabase stop" +slug: supabase-stop +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/cli.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +```bash +supabase stop +``` + +When you are finished with Supabase, run `supabase stop` to stop the Docker services. \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/.gitkeep b/apps/temp-docs/docs/reference/dart/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/apps/temp-docs/docs/reference/dart/auth-onauthstatechange.mdx b/apps/temp-docs/docs/reference/dart/auth-onauthstatechange.mdx new file mode 100644 index 00000000000..e495f9deeb2 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/auth-onauthstatechange.mdx @@ -0,0 +1,72 @@ +--- +id: auth-onauthstatechange +title: "auth.onAuthStateChange()" +slug: auth-onauthstatechange +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Receive a notification every time an auth event happens. + + + + + + +```dart +final subscription = supabase.auth.onAuthStateChange((event, session) { + print(session?.user?.id); + // handle auth state change +}); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### Listen to auth changes + + + + + + + +```dart +final subscription = supabase.auth.onAuthStateChange((event, session) { + print(session?.user?.id); + // handle auth state change +}); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/auth-session.mdx b/apps/temp-docs/docs/reference/dart/auth-session.mdx new file mode 100644 index 00000000000..361bb5d22fb --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/auth-session.mdx @@ -0,0 +1,66 @@ +--- +id: auth-session +title: "auth.session()" +slug: auth-session +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Returns the session data, if there is an active session. + + + + + + +```dart +final session = supabase.auth.session(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### Get the session data + + + + + + + +```dart +final session = supabase.auth.session(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/auth-signin.mdx b/apps/temp-docs/docs/reference/dart/auth-signin.mdx new file mode 100644 index 00000000000..b991760a4dc --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/auth-signin.mdx @@ -0,0 +1,124 @@ +--- +id: auth-signin +title: "auth.signIn()" +slug: auth-signin +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Log in an existing user, or login via a third-party provider. + + + + + + +```dart +final res = await supabase.auth.signIn(email: 'example@email.com', password: 'example-password'); + +final user = res.data?.user; +final error = res.error; +``` + + + + + + + + + + +## Notes + +- A user can sign up via email, phone number. +- If you provide `email` without a `password`, the user will be sent a magic link. +- The magic link's destination URL is determined by the SITE_URL config variable. To change this, you can go to Authentication -> Settings on [app.supabase.io](https://app.supabase.io) +- Similarly, if you provide `phone` without a `password`, the user will be sent a one time password. +- If you are looking to sign users in with OAuth in Flutter apps, go to [`signInWithProvider()`](/docs/reference/dart/auth-signinwithprovider). + + + + + + + + + + +## Examples + +### Sign in with email. + + + + + + + +```dart +final res = await supabase.auth.signIn(email: 'example@email.com', password: 'example-password'); + +final user = res.data?.user; +final error = res.error; +``` + + + + + + +### Sign in with magic link. + +If email is provided, but no password is provided, the user will be sent a "magic link" to their email address, which they can click to open your application with a valid session. By default, a given user can only request a Magic Link once every 60 seconds. + + + + + +```dart +final res = await supabase.auth.signIn(email: 'example@email.com'); + +final error = res.error; +``` + + + + + + +### Get OAuth sign in URL. + +Passing provider parameter to `signIn()` will return a URL to sign your user in via OAuth. +If you are looking to sign in a user via OAuth on Flutter app, go to [`signInWithProvider()`](/docs/reference/dart/auth-signinwithprovider). + + + + + + +```dart +final res = await supabase.auth.signIn(provider: Provider.github); + +final url = res.data?.url; +final error = res.error; +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/auth-signinwithprovider.mdx b/apps/temp-docs/docs/reference/dart/auth-signinwithprovider.mdx new file mode 100644 index 00000000000..62863ba012e --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/auth-signinwithprovider.mdx @@ -0,0 +1,129 @@ +--- +id: auth-signinwithprovider +title: "auth.signInWithProvider()" +slug: auth-signinwithprovider +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Signs the user in using third party OAuth providers. + + + + + + +```dart +final res = await supabase.auth.signInWithProvider(Provider.github); + +final error = res.error; +``` + + + + + + + + + + +## Notes + +- `auth.signInWithProvider()` is only available on `supabase_flutter` +- It will open the browser to the relevant login page. + + + + + + + + + + +## Examples + +### Sign in with provider. + + + + + + + +```dart +final res = await supabase.auth.signInWithProvider(Provider.github); + +final error = res.error; +``` + + + + + + +### With `redirectTo` + +Specify the redirect link to bring back the user via deeplink. +Note that `redirectTo` should be null for Flutter Web. + + + + + + +```dart +final res = await supabase.auth.signInWithProvider( + Provider.github, + options: AuthOptions( + redirectTo: kIsWeb + ? null + : 'io.supabase.flutter://reset-callback/'), +); + +final error = res.error; +``` + + + + + + +### With scopes + +If you need additional data from an OAuth provider, you can include a space-separated list of scopes in your request to get back an OAuth provider token. +You may also need to specify the scopes in the provider's OAuth app settings, depending on the provider. + + + + + + +```dart +const { user, session, error } = await supabase.auth.signIn({ + provider: 'github' +}, { + scopes: 'repo gist notifications' +}) +const oAuthToken = session.provider_token // use to access provider API +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/auth-signout.mdx b/apps/temp-docs/docs/reference/dart/auth-signout.mdx new file mode 100644 index 00000000000..d1458aec554 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/auth-signout.mdx @@ -0,0 +1,70 @@ +--- +id: auth-signout +title: "auth.signOut()" +slug: auth-signout +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Signs out the current user, if there is a logged in user. + + + + + + +```dart +final res = await supabase.auth.signOut(); + +final error = res.error; +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### Sign out + + + + + + + +```dart +final res = await supabase.auth.signOut(); + +final error = res.error; +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/auth-signup.mdx b/apps/temp-docs/docs/reference/dart/auth-signup.mdx new file mode 100644 index 00000000000..f1a87c75440 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/auth-signup.mdx @@ -0,0 +1,80 @@ +--- +id: auth-signup +title: "auth.signUp()" +slug: auth-signup +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Creates a new user. + + + + + + +```dart +final res = await supabase.auth.signUp('example@email.com', 'example-password'); + +final user = res.data?.user; +final error = res.error; +``` + + + + + + + + + + +## Notes + +- By default, the user will need to verify their email address before logging in. If you would like to change this, you can disable "Email Confirmations" by going to Authentication -> Settings on [app.supabase.io](https://app.supabase.io) +- If "Email Confirmations" is turned on, a `user` is returned but `session` will be null +- If "Email Confirmations" is turned off, both a `user` and a `session` will be returned +- When the user confirms their email address, they will be redirected to localhost:3000 by default. To change this, you can go to Authentication -> Settings on [app.supabase.io](https://app.supabase.io) + + + + + + + + + + +## Examples + +### Sign up. + + + + + + + +```dart +final res = await supabase.auth.signUp('example@email.com', 'example-password'); + +final user = res.data?.user; +final error = res.error; +``` + + + + + + +### Sign up with third-party providers. + +If you are using Flutter, you can sign up with OAuth providers using the [`signInWithProvider()`](/docs/reference/dart/auth-signinwithprovider) method available on `supabase_flutter`. \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/auth-update.mdx b/apps/temp-docs/docs/reference/dart/auth-update.mdx new file mode 100644 index 00000000000..95451f08b8e --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/auth-update.mdx @@ -0,0 +1,76 @@ +--- +id: auth-update +title: "auth.update()" +slug: auth-update +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Updates user data, if there is a logged in user. + + + + + + +```dart +final res = await supabase.auth.update( + UserAttributes(data: {'hello': 'world'}) +); + +final error = res.error; +``` + + + + + + + + + + +## Notes + +It's generally better to store user data in a table inside your public schema (i.e. `public.users`). +Use the `update()` method if you have data which rarely changes or is specific only to the logged in user. + + + + + + + + + + +## Examples + +### Update a user's metadata. + + + + + + + +```dart +final res = await supabase.auth.update( + UserAttributes(data: {'hello': 'world'}) +); + +final error = res.error; +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/auth-user.mdx b/apps/temp-docs/docs/reference/dart/auth-user.mdx new file mode 100644 index 00000000000..fb11208dea8 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/auth-user.mdx @@ -0,0 +1,66 @@ +--- +id: auth-user +title: "auth.user()" +slug: auth-user +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Returns the user data, if there is a logged in user. + + + + + + +```dart +final user = supabase.auth.user(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### Get the logged in user + + + + + + + +```dart +final user = supabase.auth.user(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/containedby.mdx b/apps/temp-docs/docs/reference/dart/containedby.mdx new file mode 100644 index 00000000000..0902ece9744 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/containedby.mdx @@ -0,0 +1,145 @@ +--- +id: containedby +title: ".containedBy()" +slug: containedby +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + + + + + + + +```dart +final res = await supabase + .from('countries') + .select('name, id, main_exports') + .containedBy('main_exports', ['cars', 'food', 'machine']) + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .select('name, id, main_exports') + .containedBy('main_exports', ['cars', 'food', 'machine']) + .execute(); +``` + + + + + + +### With `update()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .update({ 'name': 'Mordor' }) + .containedBy('main_exports', ['orks', 'surveillance', 'evil']) + .execute(); +``` + + + + + + +### With `delete()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .delete() + .containedBy('main_exports', ['cars', 'food', 'machine']) + .execute(); +``` + + + + + + +### With `rpc()` + + + + + + + +```dart +// Only valid if the Stored Procedure returns a table type. +final res = await supabase + .rpc('echo_all_countries') + .containedBy('main_exports', ['cars', 'food', 'machine']) + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/contains.mdx b/apps/temp-docs/docs/reference/dart/contains.mdx new file mode 100644 index 00000000000..c350feeecbc --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/contains.mdx @@ -0,0 +1,145 @@ +--- +id: contains +title: ".contains()" +slug: contains +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + + + + + + + +```dart +final res = await supabase + .from('countries') + .select('name, id, main_exports') + .contains('main_exports', ['oil']) + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .select('name, id, main_exports') + .contains('main_exports', ['oil']) + .execute(); +``` + + + + + + +### With `update()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .update({ 'name': 'Mordor' }) + .contains('main_exports', ['oil']) + .execute(); +``` + + + + + + +### With `delete()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .delete() + .contains('main_exports', ['oil']) + .execute(); +``` + + + + + + +### With `rpc()` + + + + + + + +```dart +// Only valid if the Stored Procedure returns a table type. +final res = await supabase + .rpc('echo_all_countries') + .contains('main_exports', ['oil']) + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/delete.mdx b/apps/temp-docs/docs/reference/dart/delete.mdx new file mode 100644 index 00000000000..37b570eefa3 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/delete.mdx @@ -0,0 +1,76 @@ +--- +id: delete +title: "Delete data: delete()" +slug: delete +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Performs a DELETE on the table. + + + + + + +```dart +final res = await supabase + .from('cities') + .delete() + .match({ 'id': 666 }) + .execute(); +``` + + + + + + + + + + +## Notes + +TODO update link to dart +- `delete()` should always be combined with [Filters](/docs/reference/javascript/using-filters) to target the item(s) you wish to delete. + + + + + + + + + + +## Examples + +### Delete records + + + + + + + +```dart +final res = await supabase + .from('cities') + .delete() + .match({ 'id': 666 }) + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/eq.mdx b/apps/temp-docs/docs/reference/dart/eq.mdx new file mode 100644 index 00000000000..b631453c7f3 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/eq.mdx @@ -0,0 +1,146 @@ +--- +id: eq +title: ".eq()" +slug: eq +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose value on the stated `column` exactly matches the specified `value`. + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .eq('name', 'The shire') + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .eq('name', 'The shire') + .execute(); +``` + + + + + + +### With `update()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .update({ 'name': 'Mordor' }) + .eq('name', 'San Francisco') + .execute(); +``` + + + + + + +### With `delete()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .delete() + .eq('name', 'Mordor') + .execute(); +``` + + + + + + +### With `rpc()` + + + + + + + +```dart +// Only valid if the Stored Procedure returns a table type. +final res = await supabase + .rpc('echo_all_cities') + .eq('name', 'San Francisco') + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/filter.mdx b/apps/temp-docs/docs/reference/dart/filter.mdx new file mode 100644 index 00000000000..b637f533442 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/filter.mdx @@ -0,0 +1,170 @@ +--- +id: filter +title: ".filter()" +slug: filter +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose `column` satisfies the filter. + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .filter('name', 'in', '("Paris","Tokyo")') + .execute(); +``` + + + + + + + + + + +## Notes + +- `.filter()` expects you to use the raw [PostgREST syntax](https://postgrest.org/en/stable/api.html#horizontal-filtering-rows) for the filter values, so it should only be used as an escape hatch in case other filters don't work. + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .filter('name', 'in', '("Paris","Tokyo")') + .execute(); +``` + + + + + + +### With `update()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .update({ 'name': 'Mordor' }) + .filter('name', 'in', '("Paris","Tokyo")') + .execute(); +``` + + + + + + +### With `delete()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .delete() + .filter('name', 'in', '("Paris","Tokyo")') + .execute(); +``` + + + + + + +### With `rpc()` + + + + + + + +```dart +// Only valid if the Stored Procedure returns a table type. +final res = await supabase + .rpc('echo_all_cities') + .filter('name', 'in', '("Paris","Tokyo")') +``` + + + + + + +### Filter embedded resources + + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, countries ( name )') + .filter('countries.name', 'in', '("France","Japan")') + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/getsubscriptions.mdx b/apps/temp-docs/docs/reference/dart/getsubscriptions.mdx new file mode 100644 index 00000000000..1ddf8924852 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/getsubscriptions.mdx @@ -0,0 +1,66 @@ +--- +id: getsubscriptions +title: "getSubscriptions()" +slug: getsubscriptions +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Returns an array of all your subscriptions. + + + + + + +```dart +final subscriptions = supabase.getSubscriptions(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### Get all subscriptions + + + + + + + +```dart +final subscriptions = supabase.getSubscriptions(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/gt.mdx b/apps/temp-docs/docs/reference/dart/gt.mdx new file mode 100644 index 00000000000..4c211f5b871 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/gt.mdx @@ -0,0 +1,146 @@ +--- +id: gt +title: ".gt()" +slug: gt +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose value on the stated `column` is greater than the specified `value`. + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .gt('country_id', 250) + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .gt('country_id', 250) + .execute(); +``` + + + + + + +### With `update()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .update({ 'name': 'Mordor' }) + .gt('country_id', 250) + .execute(); +``` + + + + + + +### With `delete()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .delete() + .gt('country_id', 250) + .execute(); +``` + + + + + + +### With `rpc()` + + + + + + + +```dart +// Only valid if the Stored Procedure returns a table type. +final res = await supabase + .rpc('echo_all_cities') + .gt('country_id', 250) + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/gte.mdx b/apps/temp-docs/docs/reference/dart/gte.mdx new file mode 100644 index 00000000000..1effd302292 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/gte.mdx @@ -0,0 +1,146 @@ +--- +id: gte +title: ".gte()" +slug: gte +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose value on the stated `column` is greater than or equal to the specified `value`. + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .gte('country_id', 250) + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .gte('country_id', 250) + .execute(); +``` + + + + + + +### With `update()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .update({ 'name': 'Mordor' }) + .gte('country_id', 250) + .execute(); +``` + + + + + + +### With `delete()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .delete() + .gte('country_id', 250) + .execute(); +``` + + + + + + +### With `rpc()` + + + + + + + +```dart +// Only valid if the Stored Procedure returns a table type. +final res = await supabase + .rpc('echo_all_cities') + .gte('country_id', 250) + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/ilike.mdx b/apps/temp-docs/docs/reference/dart/ilike.mdx new file mode 100644 index 00000000000..35fa42c2602 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/ilike.mdx @@ -0,0 +1,146 @@ +--- +id: ilike +title: ".ilike()" +slug: ilike +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose value in the stated `column` matches the supplied `pattern` (case insensitive). + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .ilike('name', '%la%') + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .ilike('name', '%la%') + .execute(); +``` + + + + + + +### With `update()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .update({ 'name': 'Mordor' }) + .ilike('name', '%la%') + .execute(); +``` + + + + + + +### With `delete()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .delete() + .ilike('name', '%la%') + .execute(); +``` + + + + + + +### With `rpc()` + + + + + + + +```dart +// Only valid if the Stored Procedure returns a table type. +final res = await supabase + .rpc('echo_all_cities') + .ilike('name', '%la%') + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/in_.mdx b/apps/temp-docs/docs/reference/dart/in_.mdx new file mode 100644 index 00000000000..23d18ca4ed3 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/in_.mdx @@ -0,0 +1,148 @@ +--- +id: in_ +title: ".in_()" +slug: in_ +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose value on the stated `column` is found on the specified `values`. + +`is_` and `in_` filter methods are suffixed with `_` to avoid collisions with reserved keywords. + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .in_('name', ['Rio de Janeiro', 'San Francisco']) + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .in_('name', ['Rio de Janeiro', 'San Francisco']) + .execute(); +``` + + + + + + +### With `update()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .update({ 'name': 'Mordor' }) + .in_('name', ['Rio de Janeiro', 'San Francisco']) + .execute(); +``` + + + + + + +### With `delete()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .delete() + .in_('name', ['Rio de Janeiro', 'San Francisco']) + .execute(); +``` + + + + + + +### With `rpc()` + + + + + + + +```dart +// Only valid if the Stored Procedure returns a table type. +final res = await supabase + .rpc('echo_all_cities') + .in_('name', ['Rio de Janeiro', 'San Francisco']) + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/index.mdx b/apps/temp-docs/docs/reference/dart/index.mdx new file mode 100644 index 00000000000..acffea0ac94 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/index.mdx @@ -0,0 +1,12 @@ +--- +id: index +title: "Getting started" +slug: getting-started +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + + +Supabase Dart. \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/initializing.mdx b/apps/temp-docs/docs/reference/dart/initializing.mdx new file mode 100644 index 00000000000..87b3b493a6c --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/initializing.mdx @@ -0,0 +1,84 @@ +--- +id: initializing +title: "Initializing" +slug: initializing +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +## Dart +You can initialize a new Supabase client using the `SupabaseClient()` method. + +The Supabase client is your entrypoint to the rest of the Supabase functionality +and is the easiest way to interact with everything we offer within the Supabase ecosystem. + + +## Flutter + +For `supabase_flutter`, you will be using the static `initialize()` method on `Supabase` class. + + + + + + + + + + + + + + + + + + + + +## Examples + +### Dart SupabaseClient() + + + + + + + +```dart +final supabase = SupabaseClient('https://xyzcompany.supabase.co', 'public-anon-key'); +``` + + + + + + +### Flutter initialize() + + + + + + + +```dart title="main.dart" +Future main() async { + await Supabase.initialize(url: 'https://xyzcompany.supabase.co', anonKey: 'public-anon-key'); + runApp(MyApp()); +} +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/insert.mdx b/apps/temp-docs/docs/reference/dart/insert.mdx new file mode 100644 index 00000000000..c5422081ee2 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/insert.mdx @@ -0,0 +1,102 @@ +--- +id: insert +title: "Create data: insert()" +slug: insert +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Performs an INSERT into the table. + + + + + + +```dart +final res = await supabase + .from('cities') + .insert([ + {'name': 'The Shire', 'country_id': 554} + ]).execute(); +``` + + + + + + + + + + +## Notes + +- By default, every time you run `insert()`, the client library will make a `select` to return the full record. +This is convenient, but it can also cause problems if your Policies are not configured to allow the `select` operation. +If you are using Row Level Security and you are encountering problems, try setting the `returning` param to `minimal`. + + + + + + + + + + +## Examples + +### Create a record + + + + + + + +```dart +final res = await supabase + .from('cities') + .insert([ + {'name': 'The Shire', 'country_id': 554} + ]).execute(); +``` + + + + + + +### Bulk create + + + + + + + +```dart +final res = await supabase + .from('cities') + .insert([ + {'name': 'The Shire', 'country_id': 554}, + {'name': 'Rohan', 'country_id': 555}, + ]).execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/installing.mdx b/apps/temp-docs/docs/reference/dart/installing.mdx new file mode 100644 index 00000000000..290000ecd86 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/installing.mdx @@ -0,0 +1,32 @@ +--- +id: installing +title: "Installing" +slug: installing +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +## Dart + +Dart libraries are built and supported by the community. + +```bash +dart pub add supabase +``` + +Find the source code on [GitHub](https://github.com/supabase/supabase-dart). + +## Flutter + +For Flutter project, you can use [supabase_flutter](https://github.com/supabase/supabase-flutter). + +```bash +flutter pub add supabase_flutter +``` + +`supabase_flutter` plugin uses `supabase` plugin internally, and it adds some Flutter specific functionality such as handling deeplinks coming back from magic link verifications. +If you are creating a Flutter application, we recommend using `supabase_flutter` instead of `supabase`. + +For the most part `supabase_flutter` shares the same API as `supabase` with few exceptions such as initialization or OAuth sign in. \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/is_.mdx b/apps/temp-docs/docs/reference/dart/is_.mdx new file mode 100644 index 00000000000..c1d5af70780 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/is_.mdx @@ -0,0 +1,148 @@ +--- +id: is_ +title: ".is_()" +slug: is_ +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +A check for exact equality (null, true, false), finds all rows whose value on the stated `column` exactly match the specified `value`. + +`is_` and `in_` filter methods are suffixed with `_` to avoid collisions with reserved keywords. + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .is_('name', null) + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .is_('name', null) + .execute(); +``` + + + + + + +### With `update()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .update({ 'name': 'Mordor' }) + .is_('name', null) + .execute(); +``` + + + + + + +### With `delete()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .delete() + .is_('name', null) + .execute(); +``` + + + + + + +### With `rpc()` + + + + + + + +```dart +// Only valid if the Stored Procedure returns a table type. +final res = await supabase + .rpc('echo_all_cities') + .is_('name', null) + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/like.mdx b/apps/temp-docs/docs/reference/dart/like.mdx new file mode 100644 index 00000000000..4fae8c3c8c7 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/like.mdx @@ -0,0 +1,191 @@ +--- +id: like +title: ".like()" +slug: like +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose value in the stated `column` matches the supplied `pattern` (case sensitive). + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .like('name', '%la%') + .execute(); +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + column + + + required + + + object + +

      +
      + +The column to filter on. + +
      + +
    • + + +
    • +

      + + pattern + + + required + + + string + +

      +
      + +The pattern to filter with. + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .like('name', '%la%') + .execute(); +``` + + + + + + +### With `update()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .update({ 'name': 'Mordor' }) + .like('name', '%la%') + .execute(); +``` + + + + + + +### With `delete()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .delete() + .like('name', '%la%') + .execute(); +``` + + + + + + +### With `rpc()` + + + + + + + +```dart +// Only valid if the Stored Procedure returns a table type. +final res = await supabase + .rpc('echo_all_cities') + .like('name', '%la%') + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/limit.mdx b/apps/temp-docs/docs/reference/dart/limit.mdx new file mode 100644 index 00000000000..2a22a201405 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/limit.mdx @@ -0,0 +1,99 @@ +--- +id: limit +title: "limit()" +slug: limit +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Limits the result with the specified count. + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .limit(1) + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .limit(1) + .execute(); +``` + + + + + + +### With embedded resources + + + + + + + +```dart +final res = await supabase + .from('countries') + .select('name, cities(name)') + .eq('name', 'United States') + .limit(1, foreignTable: 'cities' ) + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/lt.mdx b/apps/temp-docs/docs/reference/dart/lt.mdx new file mode 100644 index 00000000000..b98cd7589b7 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/lt.mdx @@ -0,0 +1,146 @@ +--- +id: lt +title: ".lt()" +slug: lt +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose value on the stated `column` is less than the specified `value`. + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .lt('country_id', 250) + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .lt('country_id', 250) + .execute(); +``` + + + + + + +### With `update()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .update({ 'name': 'Mordor' }) + .lt('country_id', 250) + .execute(); +``` + + + + + + +### With `delete()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .delete() + .lt('country_id', 250) + .execute(); +``` + + + + + + +### With `rpc()` + + + + + + + +```dart +// Only valid if the Stored Procedure returns a table type. +final res = await supabase + .rpc('echo_all_cities') + .lt('country_id', 250) + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/lte.mdx b/apps/temp-docs/docs/reference/dart/lte.mdx new file mode 100644 index 00000000000..8337ccc9a89 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/lte.mdx @@ -0,0 +1,191 @@ +--- +id: lte +title: ".lte()" +slug: lte +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose value on the stated `column` is less than or equal to the specified `value`. + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .lte('country_id', 250) + .execute(); +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + column + + + required + + + object + +

      +
      + +The column to filter on. + +
      + +
    • + + +
    • +

      + + value + + + required + + + object + +

      +
      + +The value to filter with. + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .lte('country_id', 250) + .execute(); +``` + + + + + + +### With `update()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .update({ 'name': 'Mordor' }) + .lte('country_id', 250) + .execute(); +``` + + + + + + +### With `delete()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .delete() + .lte('country_id', 250) + .execute(); +``` + + + + + + +### With `rpc()` + + + + + + + +```dart +// Only valid if the Stored Procedure returns a table type. +final res = await supabase + .rpc('echo_all_cities') + .lte('country_id', 250) + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/match.mdx b/apps/temp-docs/docs/reference/dart/match.mdx new file mode 100644 index 00000000000..69f9a18c47d --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/match.mdx @@ -0,0 +1,146 @@ +--- +id: match +title: ".match()" +slug: match +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose columns match the specified `query` object. + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .match({'name': 'Beijing', 'country_id': 156}) + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .match({'name': 'Beijing', 'country_id': 156}) + .execute(); +``` + + + + + + +### With `update()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .update({ 'name': 'Mordor' }) + .match({'name': 'Beijing', 'country_id': 156}) + .execute(); +``` + + + + + + +### With `delete()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .delete() + .match({'name': 'Beijing', 'country_id': 156}) + .execute(); +``` + + + + + + +### With `rpc()` + + + + + + + +```dart +// Only valid if the Stored Procedure returns a table type. +final res = await supabase + .rpc('echo_all_cities') + .match({'name': 'Beijing', 'country_id': 156}) + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/neq.mdx b/apps/temp-docs/docs/reference/dart/neq.mdx new file mode 100644 index 00000000000..92654e12b36 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/neq.mdx @@ -0,0 +1,146 @@ +--- +id: neq +title: ".neq()" +slug: neq +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose value on the stated `column` doesn't match the specified `value`. + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .neq('name', 'The shire') + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .neq('name', 'The shire') + .execute(); +``` + + + + + + +### With `update()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .update({ 'name': 'Mordor' }) + .neq('name', 'San Francisco') + .execute(); +``` + + + + + + +### With `delete()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .delete() + .neq('name', 'Mordor') + .execute(); +``` + + + + + + +### With `rpc()` + + + + + + + +```dart +// Only valid if the Stored Procedure returns a table type. +final res = await supabase + .rpc('echo_all_cities') + .neq('name', 'Lagos') + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/not.mdx b/apps/temp-docs/docs/reference/dart/not.mdx new file mode 100644 index 00000000000..cc41b7f6038 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/not.mdx @@ -0,0 +1,146 @@ +--- +id: not +title: ".not()" +slug: not +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows which doesn't satisfy the filter. + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .not('name', 'eq', 'Paris') + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .not('name', 'eq', 'Paris') + .execute(); +``` + + + + + + +### With `update()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .update({ 'name': 'Mordor' }) + .not('name', 'eq', 'Paris') + .execute(); +``` + + + + + + +### With `delete()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .delete() + .not('name', 'eq', 'Paris') + .execute(); +``` + + + + + + +### With `rpc()` + + + + + + + +```dart +// Only valid if the Stored Procedure returns a table type. +final res = await supabase + .rpc('echo_all_cities) + .not('name', 'eq', 'Paris') + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/or.mdx b/apps/temp-docs/docs/reference/dart/or.mdx new file mode 100644 index 00000000000..4852ebc659b --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/or.mdx @@ -0,0 +1,98 @@ +--- +id: or +title: ".or()" +slug: or +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows satisfying at least one of the filters. + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .or('id.eq.20,id.eq.30') + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .or('id.eq.20,id.eq.30') + .execute(); +``` + + + + + + +### Use `or` with `and` + + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .or('id.gt.20,and(name.eq.New Zealand,name.eq.France)') + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/order.mdx b/apps/temp-docs/docs/reference/dart/order.mdx new file mode 100644 index 00000000000..18daaacd619 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/order.mdx @@ -0,0 +1,99 @@ +--- +id: order +title: "order()" +slug: order +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Orders the result with the specified column. + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .order('id', ascending: false ) + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .order('id', ascending: false ) + .execute(); +``` + + + + + + +### With embedded resources + + + + + + + +```dart +final res = await supabase + .from('countries') + .select('name, cities(name)') + .eq('name', 'United States') + .order('name', foreignTable: 'cities') + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/overlaps.mdx b/apps/temp-docs/docs/reference/dart/overlaps.mdx new file mode 100644 index 00000000000..d7ca0f689b2 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/overlaps.mdx @@ -0,0 +1,145 @@ +--- +id: overlaps +title: ".overlaps()" +slug: overlaps +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + + + + + + + +```dart +final res = await supabase + .from('countries') + .select('name, id, main_exports') + .overlaps('main_exports', ['computers', 'minerals']) + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .select('name, id, main_exports') + .overlaps('main_exports', ['computers', 'minerals']) + .execute(); +``` + + + + + + +### With `update()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .update({ 'name': 'Mordor' }) + .overlaps('main_exports', ['computers', 'minerals']) + .execute(); +``` + + + + + + +### With `delete()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .delete() + .overlaps('main_exports', ['computers', 'minerals']) + .execute(); +``` + + + + + + +### With `rpc()` + + + + + + + +```dart +// Only valid if the Stored Procedure returns a table type. +final res = await supabase + .rpc('echo_all_countries') + .overlaps('main_exports', ['computers', 'minerals']) + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/range.mdx b/apps/temp-docs/docs/reference/dart/range.mdx new file mode 100644 index 00000000000..affd16f8583 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/range.mdx @@ -0,0 +1,74 @@ +--- +id: range +title: "range()" +slug: range +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Limits the result to rows within the specified range, inclusive. + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .range(0,3) + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .range(0,3) + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/rangeadjacent.mdx b/apps/temp-docs/docs/reference/dart/rangeadjacent.mdx new file mode 100644 index 00000000000..f31f4f505e9 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/rangeadjacent.mdx @@ -0,0 +1,145 @@ +--- +id: rangeadjacent +title: ".rangeAdjacent()" +slug: rangeadjacent +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + + + + + + + +```dart +final res = await supabase + .from('countries') + .select('name, id, population_range_millions') + .rangeAdjacent('population_range_millions', '[70, 185]') + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .select('name, id, population_range_millions') + .rangeAdjacent('population_range_millions', '[70, 185]') + .execute(); +``` + + + + + + +### With `update()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .update({ 'name': 'Mordor' }) + .rangeAdjacent('population_range_millions', '[70, 185]') + .execute(); +``` + + + + + + +### With `delete()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .delete() + .rangeAdjacent('population_range_millions', '[70, 185]') + .execute(); +``` + + + + + + +### With `rpc()` + + + + + + + +```dart +// Only valid if the Stored Procedure returns a table type. +final res = await supabase + .rpc('echo_all_countries') + .rangeAdjacent('population_range_millions', '[70, 185]') + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/rangegt.mdx b/apps/temp-docs/docs/reference/dart/rangegt.mdx new file mode 100644 index 00000000000..6ddd4b34ed8 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/rangegt.mdx @@ -0,0 +1,145 @@ +--- +id: rangegt +title: ".rangeGt()" +slug: rangegt +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + + + + + + + +```dart +final res = await supabase + .from('countries') + .select('name, id, population_range_millions') + .rangeGt('population_range_millions', '[150, 250]') + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .select('name, id, population_range_millions') + .rangeGt('population_range_millions', '[150, 250]') + .execute(); +``` + + + + + + +### With `update()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .update({ 'name': 'Mordor' }) + .rangeGt('population_range_millions', '[150, 250]') + .execute(); +``` + + + + + + +### With `delete()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .delete() + .rangeGt('population_range_millions', '[150, 250]') + .execute(); +``` + + + + + + +### With `rpc()` + + + + + + + +```dart +// Only valid if the Stored Procedure returns a table type. +final res = await supabase + .rpc('echo_all_countries') + .rangeGt('population_range_millions', '[150, 250]') + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/rangegte.mdx b/apps/temp-docs/docs/reference/dart/rangegte.mdx new file mode 100644 index 00000000000..3a674440832 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/rangegte.mdx @@ -0,0 +1,145 @@ +--- +id: rangegte +title: ".rangeGte()" +slug: rangegte +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + + + + + + + +```dart +final res = await supabase + .from('countries') + .select('name, id, population_range_millions') + .rangeGte('population_range_millions', '[150, 250]') + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .select('name, id, population_range_millions') + .rangeGte('population_range_millions', '[150, 250]') + .execute(); +``` + + + + + + +### With `update()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .update({ 'name': 'Mordor' }) + .rangeGte('population_range_millions', '[150, 250]') + .execute(); +``` + + + + + + +### With `delete()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .delete() + .rangeGte('population_range_millions', '[150, 250]') + .execute(); +``` + + + + + + +### With `rpc()` + + + + + + + +```dart +// Only valid if the Stored Procedure returns a table type. +final res = await supabase + .rpc('echo_all_countries') + .rangeGte('population_range_millions', '[150, 250]') + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/rangelt.mdx b/apps/temp-docs/docs/reference/dart/rangelt.mdx new file mode 100644 index 00000000000..43cb40cbd68 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/rangelt.mdx @@ -0,0 +1,145 @@ +--- +id: rangelt +title: ".rangeLt()" +slug: rangelt +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + + + + + + + +```dart +final res = await supabase + .from('countries') + .select('name, id, population_range_millions') + .rangeLt('population_range_millions', '[150, 250]') + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .select('name, id, population_range_millions') + .rangeLt('population_range_millions', '[150, 250]') + .execute(); +``` + + + + + + +### With `update()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .update({ 'name': 'Mordor' }) + .rangeLt('population_range_millions', '[150, 250]') + .execute(); +``` + + + + + + +### With `delete()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .delete() + .rangeLt('population_range_millions', '[150, 250]') + .execute(); +``` + + + + + + +### With `rpc()` + + + + + + + +```dart +// Only valid if the Stored Procedure returns a table type. +final res = await supabase + .rpc('echo_all_countries') + .rangeLt('population_range_millions', '[150, 250]') + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/rangelte.mdx b/apps/temp-docs/docs/reference/dart/rangelte.mdx new file mode 100644 index 00000000000..c673b888736 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/rangelte.mdx @@ -0,0 +1,145 @@ +--- +id: rangelte +title: ".rangeLte()" +slug: rangelte +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + + + + + + + +```dart +final res = await supabase + .from('countries') + .select('name, id, population_range_millions') + .rangeLte('population_range_millions', '[150, 250]') + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .select('name, id, population_range_millions') + .rangeLte('population_range_millions', '[150, 250]') + .execute(); +``` + + + + + + +### With `update()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .update({ 'name': 'Mordor' }) + .rangeLte('population_range_millions', '[150, 250]') + .execute(); +``` + + + + + + +### With `delete()` + + + + + + + +```dart +final res = await supabase + .from('countries') + .delete() + .rangeLte('population_range_millions', '[150, 250]') + .execute(); +``` + + + + + + +### With `rpc()` + + + + + + + +```dart +// Only valid if the Stored Procedure returns a table type. +final res = await supabase + .rpc('echo_all_countries') + .rangeLte('population_range_millions', [150, 250]) + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/removesubscription.mdx b/apps/temp-docs/docs/reference/dart/removesubscription.mdx new file mode 100644 index 00000000000..76504e2880d --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/removesubscription.mdx @@ -0,0 +1,67 @@ +--- +id: removesubscription +title: "removeSubscription()" +slug: removesubscription +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Removes an active subscription and returns the number of open connections. + + + + + + +```dart +supabase.removeSubscription(mySubscription); +``` + + + + + + + + + + +## Notes + +- Removing subscriptions is a great way to maintain the performance of your project's database. Supabase will automatically handle cleanup 30 seconds after a user is disconnected, but unused subscriptions may cause degradation as more users are simultaneously subscribed. + + + + + + + + + + +## Examples + +### Remove a subscription + + + + + + + +```dart +supabase.removeSubscription(mySubscription); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/reset-password-email.mdx b/apps/temp-docs/docs/reference/dart/reset-password-email.mdx new file mode 100644 index 00000000000..27086ba3c05 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/reset-password-email.mdx @@ -0,0 +1,114 @@ +--- +id: reset-password-email +title: "Reset Password (Email)" +slug: reset-password-email +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Sends a reset request to an email address. + + + + + + +```dart +final res = await supabase.auth.api.resetPasswordForEmail('user@example.com'); + +final error = res.error; +``` + + + + + + + + + + +## Notes + +Sends a reset request to an email address. + +When the user clicks the reset link in the email they will be forwarded to: + +`#access_token=x&refresh_token=y&expires_in=z&token_type=bearer&type=recovery` + +Your app must detect `type=recovery` in the fragment and display a password reset form to the user. + +You should then use the access_token in the url and new password to update the user as follows: + +```dart +final res = await supabase.auth.api.updateUser( + accessToken, + UserAttributes(password: 'NEW_PASSWORD'), +); +``` + + + + + + + + + + +## Examples + +### Reset password + + + + + + + +```dart +final res = await supabase.auth.api.resetPasswordForEmail('user@example.com'); + +final error = res.error; +``` + + + + + + +### Reset password for Flutter + + + + + + + +You can pass `redirectTo` to open the app via deeplink when user opens the password reset email. +```dart +final res = await supabase.auth.api.resetPasswordForEmail( + 'user@example.com', + options: AuthOptions(redirectTo: kIsWeb + ? null + : 'io.supabase.flutter://reset-callback/'), +); + +final error = res.error; +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/rpc.mdx b/apps/temp-docs/docs/reference/dart/rpc.mdx new file mode 100644 index 00000000000..f24ef39b765 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/rpc.mdx @@ -0,0 +1,119 @@ +--- +id: rpc +title: "Stored Procedures: rpc()" +slug: rpc +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +You can call stored procedures as a "Remote Procedure Call". + +That's a fancy way of saying that you can put some logic into your database then call it from anywhere. +It's especially useful when the logic rarely changes - like password resets and updates. + + + + + + +```dart +final res = await supabase + .rpc('hello_world') + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### Call a stored procedure + +This is an example invoking a stored procedure. + + + + + +```dart +final res = await supabase + .rpc('hello_world') + .execute(); +``` + + + + + + +### With Parameters + + + + + + + +```dart +final res = await supabase + .rpc('echo_city', params: { 'name': 'The Shire' }) + .execute(); +``` + + + + + + +### With count option + +You can specify a count option to get the row count along with your data. +Allowed values for count option are `exact`, `planned` and `estimated`. + + + + + + +```dart +final res = await supabase + .rpc('hello_world') + .execute(count: CountOption.exact); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/select.mdx b/apps/temp-docs/docs/reference/dart/select.mdx new file mode 100644 index 00000000000..15037ea81b6 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/select.mdx @@ -0,0 +1,272 @@ +--- +id: select +title: "Fetch data: select()" +slug: select +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Performs vertical filtering with SELECT. + + + + + + +```dart +final res = await supabase + .from('cities') + .select() + .execute(); + +final data = res.data; +final error = res.error; +``` + + + + + + + + + + +## Notes + +- By default, Supabase projects will return a maximum of 1,000 rows. This setting can be changed in Project API Settings. It's recommended that you keep it low to limit the payload size of accidental or malicious requests. You can use `range()` queries to paginate through your data. +- `select()` can be combined with [Modifiers](/docs/reference/dart/using-modifiers) +- `select()` can be combined with [Filters](/docs/reference/dart/using-filters) + + + + + + + + + + +## Examples + +### Getting your data + + + + + + + +```dart +final res = await supabase + .from('cities') + .select() + .execute(); + +final data = res.data; +final error = res.error; +``` + + + + + + +### Selecting specific columns + +You can select specific fields from your tables. + + + + + +```dart +final res = await supabase + .from('cities') + .select('name') + .execute(); +``` + + + + + + +### Query foreign tables + +If your database has relationships, you can query related tables too. + + + + + +```dart +final res = await supabase + .from('countries') + .select(''' + name, + cities ( + name + ) + ''') + .execute(); +``` + + + + + + +### Query the same foreign table multiple times + +Sometimes you will need to query the same foreign table twice. +In this case, you can use the name of the joined column to identify +which join you intend to use. For convenience, you can also give an +alias for each column. For example, if we had a shop of products, +and we wanted to get the supplier and the purchaser at the same time +(both in the users) table: + + + + + + +```dart +final res = await supabase + .from('products') + .select(''' + id, + supplier:supplier_id ( name ), + purchaser:purchaser_id ( name ) + ''') + .execute(); +``` + + + + + + +### Filtering with inner joins + +If you want to filter a table based on a child table's values you can use the `!inner()` function. For example, if you wanted +to select all rows in a `message` table which belong to a user with the `username` "Jane": + + + + + + + +``` +Not yet implemented +``` + + + + + + +### Querying with count option + +You can get the number of rows by using the count option. +Allowed values for count option are [exact](https://postgrest.org/en/stable/api.html#exact-count), [planned](https://postgrest.org/en/stable/api.html#planned-count) and [estimated](https://postgrest.org/en/stable/api.html#estimated-count). + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name') + .execute(count: CountOption.exact); + +final count = res.count; +``` + + + + + + +### Querying JSON data + +If you have data inside of a JSONB column, you can apply select +and query filters to the data values. Postgres offers a +[number of operators](https://www.postgresql.org/docs/current/functions-json.html) +for querying JSON data. Also see +[PostgREST docs](http://postgrest.org/en/v7.0.0/api.html#json-columns) for more details. + + + + + + +```dart +final res = await supabase + .from('users') + .select(''' + id, name, + address->street + ''') + .eq('address->postcode', 90210) + .execute(); +``` + + + + + + +### Return data as CSV + +By default the data is returned in JSON format, however you can also request for it to be returned as Comma Separated Values. + + + + + + +```dart +final res = await supabase + .from('users') + .select() + .csv() + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/single.mdx b/apps/temp-docs/docs/reference/dart/single.mdx new file mode 100644 index 00000000000..8d201ae0dca --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/single.mdx @@ -0,0 +1,74 @@ +--- +id: single +title: "single()" +slug: single +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Retrieves only one row from the result. Result must be one row (e.g. using limit), otherwise this will result in an error. + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .single() + .execute(); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .single() + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/storage-createbucket.mdx b/apps/temp-docs/docs/reference/dart/storage-createbucket.mdx new file mode 100644 index 00000000000..01ea9fa63b0 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/storage-createbucket.mdx @@ -0,0 +1,73 @@ +--- +id: storage-createbucket +title: "createBucket()" +slug: storage-createbucket +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Creates a new Storage bucket + + + + + + +```dart +final res = await supabase + .storage + .createBucket('avatars'); +``` + + + + + + + + + + +## Notes + +- Policy permissions required: + - `buckets` permissions: `insert` + - `objects` permissions: none + + + + + + + + + + +## Examples + +### Create bucket + + + + + + + +```dart +final res = await supabase + .storage + .createBucket('avatars'); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/storage-deletebucket.mdx b/apps/temp-docs/docs/reference/dart/storage-deletebucket.mdx new file mode 100644 index 00000000000..60a020ac22b --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/storage-deletebucket.mdx @@ -0,0 +1,73 @@ +--- +id: storage-deletebucket +title: "deleteBucket()" +slug: storage-deletebucket +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Deletes an existing bucket. A bucket can't be deleted with existing objects inside it. You must first `empty()` the bucket. + + + + + + +```dart +final res = await supabase + .storage + .deleteBucket('avatars'); +``` + + + + + + + + + + +## Notes + +- Policy permissions required: + - `buckets` permissions: `select` and `delete` + - `objects` permissions: none + + + + + + + + + + +## Examples + +### Delete bucket + + + + + + + +```dart +final res = await supabase + .storage + .deleteBucket('avatars'); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/storage-emptybucket.mdx b/apps/temp-docs/docs/reference/dart/storage-emptybucket.mdx new file mode 100644 index 00000000000..0476cb9d25c --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/storage-emptybucket.mdx @@ -0,0 +1,73 @@ +--- +id: storage-emptybucket +title: "emptyBucket()" +slug: storage-emptybucket +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Removes all objects inside a single bucket. + + + + + + +```dart +final res = await supabase + .storage + .emptyBucket('avatars'); +``` + + + + + + + + + + +## Notes + +- Policy permissions required: + - `buckets` permissions: `select` + - `objects` permissions: `select` and `delete` + + + + + + + + + + +## Examples + +### Empty bucket + + + + + + + +```dart +final res = await supabase + .storage + .emptyBucket('avatars'); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/storage-from-createsignedurl.mdx b/apps/temp-docs/docs/reference/dart/storage-from-createsignedurl.mdx new file mode 100644 index 00000000000..9609d9a96c6 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/storage-from-createsignedurl.mdx @@ -0,0 +1,79 @@ +--- +id: storage-from-createsignedurl +title: "from.createSignedUrl()" +slug: storage-from-createsignedurl +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Create signed url to download file without requiring permissions. This URL can be valid for a set number of seconds. + + + + + + +```dart +final res = await supabase + .storage + .from('avatars') + .createSignedUrl('avatar1.png', 60); + +final signedURL = res.data; +``` + + + + + + + + + + +## Notes + +- Policy permissions required: + - `buckets` permissions: none + - `objects` permissions: `select` + + + + + + + + + + +## Examples + +### Create Signed URL + + + + + + + +```dart +final res = await supabase + .storage + .from('avatars') + .createSignedUrl('avatar1.png', 60); + +final signedURL = res.data; +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/storage-from-download.mdx b/apps/temp-docs/docs/reference/dart/storage-from-download.mdx new file mode 100644 index 00000000000..f5173ee7804 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/storage-from-download.mdx @@ -0,0 +1,75 @@ +--- +id: storage-from-download +title: "from.download()" +slug: storage-from-download +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Downloads a file. + + + + + + +```dart +final res = await supabase + .storage + .from('avatars') + .download('avatar1.png'); +``` + + + + + + + + + + +## Notes + +- Policy permissions required: + - `buckets` permissions: none + - `objects` permissions: `select` + + + + + + + + + + +## Examples + +### Download file + + + + + + + +```dart +final res = await supabase + .storage + .from('avatars') + .download('avatar1.png'); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/storage-from-getpublicurl.mdx b/apps/temp-docs/docs/reference/dart/storage-from-getpublicurl.mdx new file mode 100644 index 00000000000..0629c3576bf --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/storage-from-getpublicurl.mdx @@ -0,0 +1,80 @@ +--- +id: storage-from-getpublicurl +title: "from.getPublicUrl()" +slug: storage-from-getpublicurl +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Retrieve URLs for assets in public buckets + + + + + + +```dart +final res = supabase + .storage + .from('public-bucket') + .getPublicUrl('avatar1.png'); + +final publicURL = res.data; +``` + + + + + + + + + + +## Notes + +- The bucket needs to be set to public, either via [updateBucket()](/docs/reference/javascript/storage-updatebucket) or by going to Storage on [app.supabase.io](https://app.supabase.io), clicking the overflow menu on a bucket and choosing "Make public" +- Policy permissions required: + - `buckets` permissions: none + - `objects` permissions: none + + + + + + + + + + +## Examples + +### Returns the URL for an asset in a public bucket + + + + + + + +```dart +final res = supabase + .storage + .from('public-bucket') + .getPublicUrl('avatar1.png'); + +final publicURL = res.data; +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/storage-from-list.mdx b/apps/temp-docs/docs/reference/dart/storage-from-list.mdx new file mode 100644 index 00000000000..36c9dc50985 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/storage-from-list.mdx @@ -0,0 +1,75 @@ +--- +id: storage-from-list +title: "from.list()" +slug: storage-from-list +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Lists all the files within a bucket. + + + + + + +```dart +final res = await supabase + .storage + .from('avatars') + .list(); +``` + + + + + + + + + + +## Notes + +- Policy permissions required: + - `buckets` permissions: none + - `objects` permissions: `select` + + + + + + + + + + +## Examples + +### List files in a bucket + + + + + + + +```dart +final res = await supabase + .storage + .from('avatars') + .list(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/storage-from-move.mdx b/apps/temp-docs/docs/reference/dart/storage-from-move.mdx new file mode 100644 index 00000000000..7c14443d94a --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/storage-from-move.mdx @@ -0,0 +1,75 @@ +--- +id: storage-from-move +title: "from.move()" +slug: storage-from-move +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Moves an existing file, optionally renaming it at the same time. + + + + + + +```dart +final res = await supabase + .storage + .from('avatars') + .move('public/avatar1.png', 'private/avatar2.png'); +``` + + + + + + + + + + +## Notes + +- Policy permissions required: + - `buckets` permissions: none + - `objects` permissions: `update` and `select` + + + + + + + + + + +## Examples + +### Move file + + + + + + + +```dart +final res = await supabase + .storage + .from('avatars') + .move('public/avatar1.png', 'private/avatar2.png'); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/storage-from-remove.mdx b/apps/temp-docs/docs/reference/dart/storage-from-remove.mdx new file mode 100644 index 00000000000..083be494c4e --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/storage-from-remove.mdx @@ -0,0 +1,75 @@ +--- +id: storage-from-remove +title: "from.remove()" +slug: storage-from-remove +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Deletes files within the same bucket + + + + + + +```dart +final res = await supabase + .storage + .from('avatars') + .remove(['avatar1.png']); +``` + + + + + + + + + + +## Notes + +- Policy permissions required: + - `buckets` permissions: none + - `objects` permissions: `delete` and `select` + + + + + + + + + + +## Examples + +### Delete file + + + + + + + +```dart +final res = await supabase + .storage + .from('avatars') + .remove(['avatar1.png']); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/storage-from-update.mdx b/apps/temp-docs/docs/reference/dart/storage-from-update.mdx new file mode 100644 index 00000000000..cbe7ccccfd9 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/storage-from-update.mdx @@ -0,0 +1,83 @@ +--- +id: storage-from-update +title: "from.update()" +slug: storage-from-update +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Replaces an existing file at the specified path with a new one. + + + + + + +```dart +final avatarFile = File('path/to/file'); +final res = await supabase + .storage + .from('avatars') + .update('public/avatar1.png', avatarFile, fileOptions: FileOptions( + cacheControl: '3600', + upsert: false + )); +``` + + + + + + + + + + +## Notes + +- Policy permissions required: + - `buckets` permissions: none + - `objects` permissions: `update` and `select` + + + + + + + + + + +## Examples + +### Update file + + + + + + + +```dart +final avatarFile = File('path/to/file'); +final res = await supabase + .storage + .from('avatars') + .update('public/avatar1.png', avatarFile, fileOptions: FileOptions( + cacheControl: '3600', + upsert: false + )); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/storage-from-upload.mdx b/apps/temp-docs/docs/reference/dart/storage-from-upload.mdx new file mode 100644 index 00000000000..59b18350554 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/storage-from-upload.mdx @@ -0,0 +1,152 @@ +--- +id: storage-from-upload +title: "from.upload()" +slug: storage-from-upload +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Uploads a file to an existing bucket. + + + + + + +```dart +final avatarFile = File('path/to/file'); +final res = await supabase + .storage + .from('avatars') + .upload('public/avatar1.png', avatarFile, fileOptions: FileOptions( + cacheControl: '3600', + upsert: false + )); +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + path + + + required + + + string + +

      +
      + +The relative file path. Should be of the format `folder/subfolder/filename.png`. The bucket must already exist before attempting to upload. + +
      + +
    • + + +
    • +

      + + fileBody + + + required + + + ArrayBuffer | ArrayBufferView | Blob | Buffer | File | FormData | ReadableStream | ReadableStream | URLSearchParams | string + +

      +
      + +The body of the file to be stored in the bucket. + +
      + +
    • + + +
    • +

      + + fileOptions + + + optional + + + FileOptions + +

      +
      + +HTTP headers. +`cacheControl`: string, the `Cache-Control: max-age=` seconds value. +`contentType`: string, the `Content-Type` header value. Should be specified if using a `fileBody` that is neither `Blob` nor `File` nor `FormData`, otherwise will default to `text/plain;charset=UTF-8`. +`upsert`: boolean, whether to perform an upsert. + +
      + +
    • + +
    + + +## Notes + +- Policy permissions required: + - `buckets` permissions: none + - `objects` permissions: `insert` + + + + + + + + + + +## Examples + +### Upload file + + + + + + + +```dart +final avatarFile = File('path/to/file'); +final res = await supabase + .storage + .from('avatars') + .upload('public/avatar1.png', avatarFile, fileOptions: FileOptions( + cacheControl: '3600', + upsert: false + )); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/storage-getbucket.mdx b/apps/temp-docs/docs/reference/dart/storage-getbucket.mdx new file mode 100644 index 00000000000..77608338562 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/storage-getbucket.mdx @@ -0,0 +1,97 @@ +--- +id: storage-getbucket +title: "getBucket()" +slug: storage-getbucket +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Retrieves the details of an existing Storage bucket. + + + + + + +```dart +final res = await supabase + .storage + .getBucket('avatars') +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + id + + + required + + + string + +

      +
      + +The unique identifier of the bucket you would like to retrieve. + +
      + +
    • + +
    + + +## Notes + +- Policy permissions required: + - `buckets` permissions: `select` + - `objects` permissions: none + + + + + + + + + + +## Examples + +### Get bucket + + + + + + + +```dart +final res = await supabase + .storage + .getBucket('avatars') +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/storage-listbuckets.mdx b/apps/temp-docs/docs/reference/dart/storage-listbuckets.mdx new file mode 100644 index 00000000000..c6b8d028480 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/storage-listbuckets.mdx @@ -0,0 +1,73 @@ +--- +id: storage-listbuckets +title: "listBuckets()" +slug: storage-listbuckets +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Retrieves the details of all Storage buckets within an existing product. + + + + + + +```dart +final res = await supabase + .storage + .listBuckets() +``` + + + + + + + + + + +## Notes + +- Policy permissions required: + - `buckets` permissions: `select` + - `objects` permissions: none + + + + + + + + + + +## Examples + +### List buckets + + + + + + + +```dart +final res = await supabase + .storage + .listBuckets() +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/storage-updatebucket.mdx b/apps/temp-docs/docs/reference/dart/storage-updatebucket.mdx new file mode 100644 index 00000000000..c89037e2f2d --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/storage-updatebucket.mdx @@ -0,0 +1,73 @@ +--- +id: storage-updatebucket +title: "updateBucket()" +slug: storage-updatebucket +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Updates a new Storage bucket + + + + + + +```dart +final res = await supabase + .storage + .updateBucket('avatars', { public: false }); +``` + + + + + + + + + + +## Notes + +- Policy permissions required: + - `buckets` permissions: `update` + - `objects` permissions: none + + + + + + + + + + +## Examples + +### Update bucket + + + + + + + +```dart +final res = await supabase + .storage + .updateBucket('avatars', { public: false }); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/stream.mdx b/apps/temp-docs/docs/reference/dart/stream.mdx new file mode 100644 index 00000000000..167b41e13c4 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/stream.mdx @@ -0,0 +1,147 @@ +--- +id: stream +title: "stream()" +slug: stream +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Notifies of data at the queried table. + + + + + + +```dart +supabase + .from('countries') + .stream() + .execute(); +``` + + + + + + + + + + +## Notes + +- `stream()` will emit the initial data as well as any further change on the database as `Stream` of `List>` by combining Postgrest and Realtime. + + + + + + + + + + +## Examples + +### Listening to a specific table + + + + + + + +```dart +supabase + .from('countries') + .stream() + .execute(); +``` + + + + + + +### Listening to a specific rows within a table + +You can listen to individual rows using the format `{table}:{col}=eq.{val}` - where `{col}` is the column name, and `{val}` is the value which you want to match. +This syntax is the as how you can filter data in Realtime + + + + + + +```dart +supabase + .from('countries:id=eq.120') + .stream() + .execute(); +``` + + + + + + +### With `order()` + + + + + + + +```dart +supabase + .from('countries') + .stream() + .order('name', ascending: false) + .execute(); +``` + + + + + + +### With `limit()` + + + + + + + +```dart +supabase + .from('countries') + .stream() + .order('name', ascending: false) + .limit(10) + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/subscribe.mdx b/apps/temp-docs/docs/reference/dart/subscribe.mdx new file mode 100644 index 00000000000..6c109f64659 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/subscribe.mdx @@ -0,0 +1,237 @@ +--- +id: subscribe +title: "on().subscribe()" +slug: subscribe +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Subscribe to realtime changes in your database. + + + + + + +```dart +final mySubscription = supabase + .from('countries') + .on(SupabaseEventTypes.all, (payload) { + // Handle realtime payload + }) + .subscribe(); +``` + + + + + + + + + + +## Notes + +- Realtime is disabled by default for new Projects for better database performance and security. You can turn it on by [managing replication](/docs/guides/api#managing-realtime). +- If you want to receive the "previous" data for updates and deletes, you will need to set `REPLICA IDENTITY` to `FULL`, like this: `ALTER TABLE your_table REPLICA IDENTITY FULL;` + + + + + + + + + + +## Examples + +### Listen to all database changes + + + + + + + +```dart +final mySubscription = supabase + .from('countries') + .on(SupabaseEventTypes.all, (payload) { + // Handle realtime payload + }) + .subscribe(); +``` + + + + + + +### Listening to a specific table + + + + + + + +```dart +final mySubscription = supabase + .from('countries') + .on(SupabaseEventTypes.all, (payload) { + // Handle realtime payload + }) + .subscribe(); +``` + + + + + + +### Listening to inserts + + + + + + + +```dart +final mySubscription = supabase + .from('countries') + .on(SupabaseEventTypes.insert, (payload) { + // Handle realtime payload + }) + .subscribe(); +``` + + + + + + +### Listening to updates + +By default, Supabase will send only the updated record. If you want to receive the previous values as well you can +enable full replication for the table you are listening too: + +```sql +alter table "your_table" replica identity full; +``` + + + + + + +```dart +final mySubscription = supabase + .from('countries') + .on(SupabaseEventTypes.update, (payload) { + // Handle realtime payload + }) + .subscribe(); +``` + + + + + + +### Listening to deletes + +By default, Supabase does not send deleted records. If you want to receive the deleted record you can +enable full replication for the table you are listening too: + +```sql +alter table "your_table" replica identity full; +``` + + + + + + +```dart +final mySubscription = supabase + .from('countries') + .on(SupabaseEventTypes.delete, (payload) { + // Handle realtime payload + }) + .subscribe(); +``` + + + + + + +### Listening to multiple events + +You can chain listeners if you want to listen to multiple events for each table. + + + + + +```dart +final mySubscription = supabase + .from('countries') + .on(SupabaseEventTypes.insert, handleInsert) + .on(SupabaseEventTypes.delete, handleDelete) + .subscribe(); +``` + + + + + + +### Listening to row level changes + +You can listen to individual rows using the format `{table}:{col}=eq.{val}` - where `{col}` is the column name, and `{val}` is the value which you want to match. + + + + + +```dart +final mySubscription = supabase + .from('countries:id=eq.200') + .on(SupabaseEventTypes.update, handleRecordUpdated) + .subscribe(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/textsearch.mdx b/apps/temp-docs/docs/reference/dart/textsearch.mdx new file mode 100644 index 00000000000..edda6a8dd14 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/textsearch.mdx @@ -0,0 +1,147 @@ +--- +id: textsearch +title: ".textSearch()" +slug: textsearch +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose tsvector value on the stated `column` matches to_tsquery(query). + + + + + + + + + + + + + + + + + + + + +## Examples + +### Text search + + + + + + + +```dart +final res = await supabase + .from('quotes') + .select('catchphrase') + .textSearch('catchphrase', "'fat' & 'cat'", + config: 'english' + ) + .execute(); +``` + + + + + + +### Basic normalization + +Uses PostgreSQL's `plainto_tsquery` function. + + + + + +```dart +final res = await supabase + .from('quotes') + .select('catchphrase') + .textSearch('catchphrase', "'fat' & 'cat'", + type: TextSearchType.plain, + config: 'english' + ) + .execute(); +``` + + + + + + +### Full normalization + +Uses PostgreSQL's `phraseto_tsquery` function. + + + + + +```dart +final res = await supabase + .from('quotes') + .select('catchphrase') + .textSearch('catchphrase', "'fat' & 'cat'", + type: TextSearchType.phrase, + config: 'english' + ) + .execute(); +``` + + + + + + +### Full normalization + +Uses PostgreSQL's `websearch_to_tsquery` function. +This function will never raise syntax errors, which makes it possible to use raw user-supplied input for search, and can be used +with advanced operators. + +- `unquoted text`: text not inside quote marks will be converted to terms separated by & operators, as if processed by plainto_tsquery. +- `"quoted text"`: text inside quote marks will be converted to terms separated by <-> operators, as if processed by phraseto_tsquery. +- `OR`: the word “or” will be converted to the | operator. +- `-`: a dash will be converted to the ! operator. + + + + + + +```dart +final res = await supabase + .from('quotes') + .select('catchphrase') + .textSearch('catchphrase', "'fat or cat'", + type: TextSearchType.websearch, + config: 'english' + ) + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/update.mdx b/apps/temp-docs/docs/reference/dart/update.mdx new file mode 100644 index 00000000000..18519852ff0 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/update.mdx @@ -0,0 +1,109 @@ +--- +id: update +title: "Modify data: update()" +slug: update +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Performs an UPDATE on the table. + + + + + + +```dart +final res = await supabase + .from('cities') + .update({ 'name': 'Middle Earth' }) + .match({ 'name': 'Auckland' }) + .execute(); +``` + + + + + + + + + + +## Notes + +TODO update the link to dart +- `update()` should always be combined with [Filters](/docs/reference/javascript/using-filters) to target the item(s) you wish to update. + + + + + + + + + + +## Examples + +### Updating your data + + + + + + + +```dart +final res = await supabase + .from('cities') + .update({ 'name': 'Middle Earth' }) + .match({ 'name': 'Auckland' }) + .execute(); +``` + + + + + + +### Updating JSON data + +Postgres offers a +[number of operators](https://www.postgresql.org/docs/current/functions-json.html) +for working with JSON data. Right now it is only possible to update an entire JSON document, +but we are [working on ideas](https://github.com/PostgREST/postgrest/issues/465) for updating individual keys. + + + + + + +```dart +final res = await supabase + .from('users') + .update({ + 'address': { + 'street': 'Melrose Place', + 'postcode': 90210 + } + }) + .eq('address->postcode', 90210) + .execute(); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/upsert.mdx b/apps/temp-docs/docs/reference/dart/upsert.mdx new file mode 100644 index 00000000000..085eab75a02 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/upsert.mdx @@ -0,0 +1,128 @@ +--- +id: upsert +title: "Upsert data: upsert()" +slug: upsert +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Performs an UPSERT into the table. + + + + + + +```dart +final res = await supabase + .from('messages') + .upsert({ 'id': 3, 'message': 'foo', 'username': 'supabot' }) + .execute(); +``` + + + + + + + + + + +## Notes + +- Primary keys should be included in the data payload in order for an update to work correctly. +- Primary keys must be natural, not surrogate. There are however, [workarounds](https://github.com/PostgREST/postgrest/issues/1118) for surrogate primary keys. + + + + + + + + + + +## Examples + +### Upsert your data + + + + + + + +```dart +final res = await supabase + .from('messages') + .upsert({ 'id': 3, 'message': 'foo', 'username': 'supabot' }) + .execute(); +``` + + + + + + +### Upserting into tables with constraints + +Running the following will cause supabase to upsert data into the `users` table. +If the username 'supabot' already exists, the `onConflict` argument tells supabase to overwrite that row +based on the column passed into `onConflict`. + + + + + + +```dart +final res = await supabase + .from('users') + .upsert({ 'username': 'supabot' }, { 'onConflict': 'username' }) + .execute(); +``` + + + + + + +### Return the exact number of rows + +Allowed values for count option are `exact`, `planned` and `estimated`. + + + + + + +```dart +final res = await supabase + .from('users') + .upsert({ + 'id': 3, + 'message': 'foo', + 'username': 'supabot' + }) + .execute(count: CountOption.exact); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/using-filters.mdx b/apps/temp-docs/docs/reference/dart/using-filters.mdx new file mode 100644 index 00000000000..3296a3ee251 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/using-filters.mdx @@ -0,0 +1,44 @@ +--- +id: using-filters +title: "Using Filters" +slug: using-filters +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Filters can be used on `select()`, `update()`, and `delete()` queries. + +If a Stored Procedure returns a table response, you can also apply filters. + +### Applying Filters + +You must apply your filters to the end of your query. For example: + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .eq('name', 'The Shire') // Correct + .execute(); + +final res = await supabase + .from('cities') + .eq('name', 'The Shire') // Incorrect + .select('name, country_id') + .execute(); +``` + +### Chaining + +Filters can be chained together to produce advanced queries. For example: + +```dart +final res = await supabase + .from('cities') + .select('name, country_id') + .gte('population', 1000) + .lt('population', 10000) + .execute(); +``` \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/dart/using-modifiers.mdx b/apps/temp-docs/docs/reference/dart/using-modifiers.mdx new file mode 100644 index 00000000000..8aefaf43501 --- /dev/null +++ b/apps/temp-docs/docs/reference/dart/using-modifiers.mdx @@ -0,0 +1,13 @@ +--- +id: using-modifiers +title: "Using Modifiers" +slug: using-modifiers +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/dart.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Modifiers can be used on `select()` queries. + +If a Stored Procedure returns a table response, you can also apply modifiers to the `rpc()` function. \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/.gitkeep b/apps/temp-docs/docs/reference/javascript/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/apps/temp-docs/docs/reference/javascript/auth-api-createuser.mdx b/apps/temp-docs/docs/reference/javascript/auth-api-createuser.mdx new file mode 100644 index 00000000000..95eb40e21dd --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/auth-api-createuser.mdx @@ -0,0 +1,97 @@ +--- +id: auth-api-createuser +title: "createUser()" +slug: auth-api-createuser +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Creates a new user. + +This function should only be called on a server. Never expose your `service_role` key in the browser. + + + + + +```js +const { data: user, error } = await supabase.auth.api.createUser({ + name: 'Yoda' +}) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + attributes + + + required + + + UserAttributes + +

      +
      + +The data you want to create the user with. + +
      + +
    • + +
    + + +## Notes + +- Requires a `service_role` key. +- This function should be called on a server. Never expose your `service_role` key in the browser. + + + + + + + + + + +## Examples + +### Create a new user. + + + + + + + +```js +const { data: user, error } = await supabase.auth.api.createUser({ + name: 'Yoda' +}) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/auth-api-deleteuser.mdx b/apps/temp-docs/docs/reference/javascript/auth-api-deleteuser.mdx new file mode 100644 index 00000000000..4cd5536d508 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/auth-api-deleteuser.mdx @@ -0,0 +1,120 @@ +--- +id: auth-api-deleteuser +title: "deleteUser()" +slug: auth-api-deleteuser +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Delete a user. Requires a `service_role` key. + +This function should only be called on a server. Never expose your `service_role` key in the browser. + + + + + +```js +const { data: user, error } = await supabase.auth.api.deleteUser( + '715ed5db-f090-4b8c-a067-640ecee36aa0', + 'YOUR_SERVICE_ROLE_KEY' +) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + uid + + + required + + + string + +

      +
      + +The user uid you want to remove. + +
      + +
    • + + +
    • +

      + + jwt + + + required + + + string + +

      +
      + +A valid JWT. Must be a full-access API key (e.g. service_role key). + +
      + +
    • + +
    + + +## Notes + +- Requires a `service_role` key. +- This function should be called on a server. Never expose your `service_role` key in the browser. + + + + + + + + + + +## Examples + +### Remove a user completely. + + + + + + + +```js +const { data: user, error } = await supabase.auth.api.deleteUser( + '715ed5db-f090-4b8c-a067-640ecee36aa0', + 'YOUR_SERVICE_ROLE_KEY' +) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/auth-api-generatelink.mdx b/apps/temp-docs/docs/reference/javascript/auth-api-generatelink.mdx new file mode 100644 index 00000000000..bfb612aef93 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/auth-api-generatelink.mdx @@ -0,0 +1,189 @@ +--- +id: auth-api-generatelink +title: "generateLink()" +slug: auth-api-generatelink +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Generates links to be sent via email or other. + + + +## Parameters + + +
      + +
    • +

      + + type + + + required + + + signup | magiclink | recovery | invite + +

      +
      + +The link type ("signup" or "magiclink" or "recovery" or "invite"). + +
      + +
    • + + +
    • +

      + + email + + + required + + + string + +

      +
      + +The user's email. + +
      + +
    • + + +
    • +

      + + options + + + required + + + object + +

      +
      + +No description provided. + +
      + +
        +
        Properties
        + +
      • +

        + + data + + + optional + + + object + +

        +
        + +No description provided. + +
        + +
      • + + +
      • +

        + + password + + + optional + + + string + +

        +
        + +No description provided. + +
        + +
      • + + +
      • +

        + + redirectTo + + + optional + + + string + +

        +
        + +No description provided. + +
        + +
      • + +
      + +
    • + +
    + + +## Notes + +- Requires a `service_role` key. +- This function should only be called on a server. Never expose your `service_role` key in the browser. + + + + + + + + + + +## Examples + +### Generate invite link. + + + + + + + +```js +const { data: user, error } = await supabase.auth.api.generateLink({ + type: 'invite', + email: 'email@example.com' +}) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/auth-api-getuser.mdx b/apps/temp-docs/docs/reference/javascript/auth-api-getuser.mdx new file mode 100644 index 00000000000..0d10b1bbca8 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/auth-api-getuser.mdx @@ -0,0 +1,96 @@ +--- +id: auth-api-getuser +title: "getUser()" +slug: auth-api-getuser +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Gets the user details. + + + + + +```js +const { user, error } = await supabase.auth.api.getUser( + 'ACCESS_TOKEN_JWT', +) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + jwt + + + required + + + string + +

      +
      + +A valid, logged-in JWT. + +
      + +
    • + +
    + + +## Notes + +- Fetches the user object from the database instead of local storage. +- Note that user() fetches the user object from local storage which might not be the most updated. +- Requires the user's access_token. + + + + + + + + + + +## Examples + +### Fetch the user object using the access_token jwt. + + + + + + + +```js +const { user, error } = await supabase.auth.api.getUser( + 'ACCESS_TOKEN_JWT', +) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/auth-api-inviteuserbyemail.mdx b/apps/temp-docs/docs/reference/javascript/auth-api-inviteuserbyemail.mdx new file mode 100644 index 00000000000..1ed7271198f --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/auth-api-inviteuserbyemail.mdx @@ -0,0 +1,146 @@ +--- +id: auth-api-inviteuserbyemail +title: "inviteUserByEmail()" +slug: auth-api-inviteuserbyemail +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Sends an invite link to an email address. + + + +## Parameters + + +
      + +
    • +

      + + email + + + required + + + string + +

      +
      + +The email address of the user. + +
      + +
    • + + +
    • +

      + + options + + + required + + + object + +

      +
      + +No description provided. + +
      + +
        +
        Properties
        + +
      • +

        + + data + + + optional + + + object + +

        +
        + +No description provided. + +
        + +
      • + + +
      • +

        + + redirectTo + + + optional + + + string + +

        +
        + +No description provided. + +
        + +
      • + +
      + +
    • + +
    + + +## Notes + +- Requires a `service_role` key. +- This function should only be called on a server. Never expose your `service_role` key in the browser. + + + + + + + + + + +## Examples + +### Basic example. + + + + + + + +```js +const { data: user, error } = await supabase.auth + .api + .inviteUserByEmail('email@example.com') +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/auth-api-resetpasswordforemail.mdx b/apps/temp-docs/docs/reference/javascript/auth-api-resetpasswordforemail.mdx new file mode 100644 index 00000000000..68ad2d890fc --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/auth-api-resetpasswordforemail.mdx @@ -0,0 +1,125 @@ +--- +id: auth-api-resetpasswordforemail +title: "resetPasswordForEmail()" +slug: auth-api-resetpasswordforemail +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Sends a reset request to an email address. + + + +## Parameters + + +
      + +
    • +

      + + email + + + required + + + string + +

      +
      + +The email address of the user. + +
      + +
    • + + +
    • +

      + + options + + + required + + + object + +

      +
      + +No description provided. + +
      + +
        +
        Properties
        + +
      • +

        + + redirectTo + + + optional + + + string + +

        +
        + +No description provided. + +
        + +
      • + +
      + +
    • + +
    + + +## Notes + +- Requires a `service_role` key. +- This function should only be called on a server. Never expose your `service_role` key in the browser. + + + + + + + + + + +## Examples + +### Basic example. + + + + + + + +```js +const { data: user, error } = await supabase.auth + .api + .resetPasswordForEmail('email@example.com') +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/auth-api-sendmobileotp.mdx b/apps/temp-docs/docs/reference/javascript/auth-api-sendmobileotp.mdx new file mode 100644 index 00000000000..671a54b7545 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/auth-api-sendmobileotp.mdx @@ -0,0 +1,79 @@ +--- +id: auth-api-sendmobileotp +title: "sendMobileOTP()" +slug: auth-api-sendmobileotp +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Sends a mobile OTP via SMS. Will register the account if it doesn't already exist + + + +## Parameters + + +
      + +
    • +

      + + phone + + + required + + + string + +

      +
      + +The user's phone number WITH international prefix + +
      + +
    • + +
    + + +## Notes + +- Requires a `service_role` key. +- This function should only be called on a server. Never expose your `service_role` key in the browser. + + + + + + + + + + +## Examples + +### Basic example. + + + + + + + +```js +const { data: user, error } = await supabase.auth + .api + .sendMobileOTP('12345879') +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/auth-onauthstatechange.mdx b/apps/temp-docs/docs/reference/javascript/auth-onauthstatechange.mdx new file mode 100644 index 00000000000..baa6bd540d5 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/auth-onauthstatechange.mdx @@ -0,0 +1,93 @@ +--- +id: auth-onauthstatechange +title: "onAuthStateChange()" +slug: auth-onauthstatechange +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Receive a notification every time an auth event happens. + + + + + +```js +supabase.auth.onAuthStateChange((event, session) => { + console.log(event, session) +}) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + callback + + + required + + + object + +

      +
      + +No description provided. + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### Listen to auth changes + + + + + + + +```js +supabase.auth.onAuthStateChange((event, session) => { + console.log(event, session) +}) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/auth-session.mdx b/apps/temp-docs/docs/reference/javascript/auth-session.mdx new file mode 100644 index 00000000000..fb1f1287b30 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/auth-session.mdx @@ -0,0 +1,65 @@ +--- +id: auth-session +title: "session()" +slug: auth-session +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Returns the session data, if there is an active session. + + + + + +```js +const session = supabase.auth.session() +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### Get the session data + + + + + + + +```js +const session = supabase.auth.session() +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/auth-setauth.mdx b/apps/temp-docs/docs/reference/javascript/auth-setauth.mdx new file mode 100644 index 00000000000..4a86aaffe4f --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/auth-setauth.mdx @@ -0,0 +1,160 @@ +--- +id: auth-setauth +title: "setAuth()" +slug: auth-setauth +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Overrides the JWT on the current client. The JWT will then be sent in all subsequent network requests. + + + + + +```js +function apiFunction(req, res) { + // Assuming the access token was sent as a header "X-Supabase-Auth" + const { access_token } = req.get('X-Supabase-Auth') + + // You can now use it within a Supabase Client + const supabase = createClient("https://xyzcompany.supabase.co", "public-anon-key") + const { user, error } = supabase.auth.setAuth(access_token) + + // This client will now send requests as this user + const { data } = await supabase.from('your_table').select() +} +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + access_token + + + required + + + string + +

      +
      + +a jwt access token + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### Basic example. + +This is most useful on server-side functions where you cannot log the user in, but have access to the user's access token. + + + + + +```js +function apiFunction(req, res) { + // Assuming the access token was sent as a header "X-Supabase-Auth" + const { access_token } = req.get('X-Supabase-Auth') + + // You can now use it within a Supabase Client + const supabase = createClient("https://xyzcompany.supabase.co", "public-anon-key") + const { user, error } = supabase.auth.setAuth(access_token) + + // This client will now send requests as this user + const { data } = await supabase.from('your_table').select() +} +``` + + + + + + +### With Express. + + + + + + + +```js + +/** +* Make a request from the client to your server function +*/ +async function makeApiRequest() { + const token = newClient.session()?.access_token + + await fetch('https://example.com/withAuth', { + method: 'GET', + withCredentials: true, + credentials: 'include', + headers: { + 'Content-Type': 'application/json' + 'Authorization': bearer, // Your own auth + 'X-Supabase-Auth': token, // Set the Supabase user + } + }) +} + +/** +* Use the Auth token in your server-side function. +*/ +async function apiFunction(req, res) { + const { access_token } = req.get('X-Supabase-Auth') + + // You can now use it within a Supabase Client + const supabase = createClient("https://xyzcompany.supabase.co", "public-anon-key") + const { user, error } = supabase.auth.setAuth(access_token) + + // This client will now send requests as this user + const { data } = await supabase.from('your_table').select() +} +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/auth-signin.mdx b/apps/temp-docs/docs/reference/javascript/auth-signin.mdx new file mode 100644 index 00000000000..d19f85cc52b --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/auth-signin.mdx @@ -0,0 +1,297 @@ +--- +id: auth-signin +title: "signIn()" +slug: auth-signin +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Log in an existing user, or login via a third-party provider. + + + + + +```js +const { user, session, error } = await supabase.auth.signIn({ + email: 'example@email.com', + password: 'example-password', +}) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + __namedParameters + + + required + + + UserCredentials + +

      +
      + +No description provided. + +
      + +
    • + + +
    • +

      + + options + + + required + + + object + +

      +
      + +No description provided. + +
      + +
        +
        Properties
        + +
      • +

        + + redirectTo + + + optional + + + string + +

        +
        + +No description provided. + +
        + +
      • + + +
      • +

        + + scopes + + + optional + + + string + +

        +
        + +No description provided. + +
        + +
      • + +
      + +
    • + +
    + + +## Notes + +- A user can sign up either via email or OAuth. +- If you provide `email` without a `password`, the user will be sent a magic link. +- The magic link's destination URL is determined by the SITE_URL config variable. To change this, you can go to Authentication -> Settings on [app.supabase.io](https://app.supabase.io) +- Specifying a `provider` will open the browser to the relevant login page. + + + + + + + + + + +## Examples + +### Sign in with email. + + + + + + + +```js +const { user, session, error } = await supabase.auth.signIn({ + email: 'example@email.com', + password: 'example-password', +}) +``` + + + + + + +### Sign in with magic link. + +If no password is provided, the user will be sent a "magic link" to their email address, which they can click to open your application with a valid session. By default, a given user can only request a Magic Link once every 60 seconds. + + + + + +```js +const { user, session, error } = await supabase.auth.signIn({ + email: 'example@email.com' +}) +``` + + + + + + +### Sign in using third-party providers. + +Supabase supports OAuth logins. + + + + + +```js +const { user, session, error } = await supabase.auth.signIn({ + // provider can be 'github', 'google', 'gitlab', or 'bitbucket' + provider: 'github' +}) +``` + + + + + + +### Sign in with redirect. + +Sometimes you want to control where the user is redirected to after they are logged in. Supabase supports this for +any URL path on your website (the base domain must be the same as the domain in your Auth settings). + + + + + + +```js +const { user, session, error } = await supabase.auth.signIn({ + provider: 'github' +}, { + redirectTo: 'https://example.com/welcome' +}) +``` + + + + + + +### Sign in with scopes. + +If you need additional data from an OAuth provider, you can include a space-separated list of scopes in your request to get back an OAuth provider token. +You may also need to specify the scopes in the provider's OAuth app settings, depending on the provider. + + + + + + +```js +const { user, session, error } = await supabase.auth.signIn({ + provider: 'github' +}, { + scopes: 'repo gist notifications' +}) +const oAuthToken = session.provider_token // use to access provider API +``` + + + + + + +### Sign in using a refresh token (e.g. in React Native). + +If you are completing a sign up or login in a React Native app you can pass the refresh token obtained from the provider to obtain a session. + + + + + + +```js +// An example using Expo's `AuthSession` +const redirectUri = AuthSession.makeRedirectUri({ useProxy: false }); +const provider = 'google'; + +AuthSession.startAsync({ + authUrl: `https://MYSUPABASEAPP.supabase.co/auth/v1/authorize?provider=${provider}&redirect_to=${redirectUri}`, + returnUrl: redirectUri, +}).then(async (response: any) => { + if (!response) return; + const { user, session, error } = await supabase.auth.signIn({ + refreshToken: response.params?.refresh_token, + }); +}); +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/auth-signout.mdx b/apps/temp-docs/docs/reference/javascript/auth-signout.mdx new file mode 100644 index 00000000000..caa66f506bf --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/auth-signout.mdx @@ -0,0 +1,68 @@ +--- +id: auth-signout +title: "signOut()" +slug: auth-signout +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Inside a browser context, `signOut()` will remove the logged in user from the browser session +and log them out - removing all items from localstorage and then trigger a "SIGNED_OUT" event. + +For server-side management, you can disable sessions by passing a JWT through to `auth.api.signOut(JWT: string)` + + + + + +```js +const { error } = await supabase.auth.signOut() +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### Sign out + + + + + + + +```js +const { error } = await supabase.auth.signOut() +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/auth-signup.mdx b/apps/temp-docs/docs/reference/javascript/auth-signup.mdx new file mode 100644 index 00000000000..89e17586e34 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/auth-signup.mdx @@ -0,0 +1,205 @@ +--- +id: auth-signup +title: "signUp()" +slug: auth-signup +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Creates a new user. + + + + + +```js +const { user, session, error } = await supabase.auth.signUp({ + email: 'example@email.com', + password: 'example-password', +}) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + __namedParameters + + + required + + + UserCredentials + +

      +
      + +No description provided. + +
      + +
    • + + +
    • +

      + + options + + + required + + + object + +

      +
      + +No description provided. + +
      + +
        +
        Properties
        + +
      • +

        + + data + + + optional + + + object + +

        +
        + +No description provided. + +
        + +
      • + + +
      • +

        + + redirectTo + + + optional + + + string + +

        +
        + +No description provided. + +
        + +
      • + +
      + +
    • + +
    + + +## Notes + +- By default, the user will need to verify their email address before logging in. If you would like to change this, you can disable "Email Confirmations" by going to Authentication -> Settings on [app.supabase.io](https://app.supabase.io) +- If "Email Confirmations" is turned on, a `user` is returned but `session` will be null +- If "Email Confirmations" is turned off, both a `user` and a `session` will be returned +- When the user confirms their email address, they will be redirected to localhost:3000 by default. To change this, you can go to Authentication -> Settings on [app.supabase.io](https://app.supabase.io) +- If signUp() is called for an existing confirmed user: + - If "Enable email confirmations" is enabled on the "Authentication" -> "Settings" page, an obfuscated / fake user object will be returned. + - If "Enable email confirmations" is disabled, an error with a message "User already registered" will be returned. +- To check if a user already exists, refer to getUser(). + + + + + + + + + + +## Examples + +### Sign up. + + + + + + + +```js +const { user, session, error } = await supabase.auth.signUp({ + email: 'example@email.com', + password: 'example-password', +}) +``` + + + + + + +### Sign up with additional user meta data. + + + + + + + +```js +const { user, session, error } = await supabase.auth.signUp( + { + email: 'example@email.com', + password: 'example-password', + }, + { + data: { + first_name: 'John', + age: 27, + } + } +) +``` + + + + + + +### Sign up with third-party providers. + +You can sign up with OAuth providers using the [`signIn()`](/docs/reference/javascript/auth-signin#sign-in-using-third-party-providers) method. \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/auth-update.mdx b/apps/temp-docs/docs/reference/javascript/auth-update.mdx new file mode 100644 index 00000000000..bc7f9f6124a --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/auth-update.mdx @@ -0,0 +1,137 @@ +--- +id: auth-update +title: "update()" +slug: auth-update +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Updates user data, if there is a logged in user. + + + + + +```js +const { user, error } = await supabase.auth.update({email: 'new@email.com'}) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + attributes + + + required + + + UserAttributes + +

      +
      + +No description provided. + +
      + +
    • + +
    + + +## Notes + +User email: Email updates will send an email to both the user's current and new email with a confirmation link by default. +To toggle this behavior off and only send a single confirmation link to the new email, toggle "Double confirm email changes" under "Authentication" -> "Settings" off. + + +User metadata: It's generally better to store user data in a table inside your public schema (i.e. `public.users`). +Use the `update()` method if you have data which rarely changes or is specific only to the logged in user. + + + + + + + + + + +## Examples + +### Update email for authenticated user. + +Sends a "Confirm Email Change" email to the new email address. + + + + + +```js +const { user, error } = await supabase.auth.update({email: 'new@email.com'}) +``` + + + + + + +### Update password for authenticated user. + + + + + + + +```js +const { user, error } = await supabase.auth.update({password: 'new password'}) +``` + + + + + + +### Update a user's metadata. + + + + + + + +```js +const { user, error } = await supabase.auth.update({ + data: { hello: 'world' } +}) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/auth-user.mdx b/apps/temp-docs/docs/reference/javascript/auth-user.mdx new file mode 100644 index 00000000000..f0875580371 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/auth-user.mdx @@ -0,0 +1,68 @@ +--- +id: auth-user +title: "user()" +slug: auth-user +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Inside a browser context, `user()` will return the user data, if there is a logged in user. + +For server-side management, you can get a user through `auth.api.getUserByCookie()` + + + + + +```js +const user = supabase.auth.user() +``` + + + + + + + + + + +## Notes + +This method gets the user object from memory. + + + + + + + + + + +## Examples + +### Get the logged in user + + + + + + + +```js +const user = supabase.auth.user() +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/containedby.mdx b/apps/temp-docs/docs/reference/javascript/containedby.mdx new file mode 100644 index 00000000000..6e783d53d71 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/containedby.mdx @@ -0,0 +1,140 @@ +--- +id: containedby +title: ".containedBy()" +slug: containedby +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .select('name, id, main_exports') + .containedBy('main_exports', ['cars', 'food', 'machine']) +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .select('name, id, main_exports') + .containedBy('main_exports', ['cars', 'food', 'machine']) +``` + + + + + + +### With `update()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .update({ name: 'Mordor' }) + .containedBy('main_exports', ['orks', 'surveillance', 'evil']) +``` + + + + + + +### With `delete()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .delete() + .containedBy('main_exports', ['cars', 'food', 'machine']) +``` + + + + + + +### With `rpc()` + + + + + + + +```js +// Only valid if the Postgres function returns a table type. +const { data, error } = await supabase + .rpc('echo_all_countries') + .containedBy('main_exports', ['cars', 'food', 'machine']) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/contains.mdx b/apps/temp-docs/docs/reference/javascript/contains.mdx new file mode 100644 index 00000000000..9d46db6f9db --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/contains.mdx @@ -0,0 +1,140 @@ +--- +id: contains +title: ".contains()" +slug: contains +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .select('name, id, main_exports') + .contains('main_exports', ['oil']) +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .select('name, id, main_exports') + .contains('main_exports', ['oil']) +``` + + + + + + +### With `update()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .update({ name: 'Mordor' }) + .contains('main_exports', ['oil']) +``` + + + + + + +### With `delete()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .delete() + .contains('main_exports', ['oil']) +``` + + + + + + +### With `rpc()` + + + + + + + +```js +// Only valid if the Postgres function returns a table type. +const { data, error } = await supabase + .rpc('echo_all_countries') + .contains('main_exports', ['oil']) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/delete-user.mdx b/apps/temp-docs/docs/reference/javascript/delete-user.mdx new file mode 100644 index 00000000000..cb370409907 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/delete-user.mdx @@ -0,0 +1,118 @@ +--- +id: delete-user +title: "Delete User" +slug: delete-user +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Delete a user. Requires a `service_role` key. + +This function should only be called on a server. Never expose your `service_role` key in the browser. + + + + + +```js +const { user, error } = await supabase.auth.api.deleteUser( + '715ed5db-f090-4b8c-a067-640ecee36aa0', + 'YOUR_SERVICE_ROLE_KEY' +) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + uid + + + required + + + string + +

      +
      + +The user uid you want to remove. + +
      + +
    • + + +
    • +

      + + jwt + + + required + + + string + +

      +
      + +A valid JWT. Must be a full-access API key (e.g. service_role key). + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### Remove a user completely. + + + + + + + +```js +const { user, error } = await supabase.auth.api.deleteUser( + '715ed5db-f090-4b8c-a067-640ecee36aa0', + 'YOUR_SERVICE_ROLE_KEY' +) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/delete.mdx b/apps/temp-docs/docs/reference/javascript/delete.mdx new file mode 100644 index 00000000000..75b26387576 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/delete.mdx @@ -0,0 +1,147 @@ +--- +id: delete +title: "Delete data: delete()" +slug: delete +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Performs a DELETE on the table. + + + + + +```js +const { data, error } = await supabase + .from('cities') + .delete() + .match({ id: 666 }) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + __namedParameters + + + required + + + object + +

      +
      + +No description provided. + +
      + +
        +
        Properties
        + +
      • +

        + + returning + + + required + + + minimal | representation + +

        +
        + +If `true`, return the deleted row(s) in the response. + +
        + +
      • + + +
      • +

        + + count + + + required + + + null | exact | planned | estimated + +

        +
        + +Count algorithm to use to count rows in a table. + +
        + +
      • + +
      + +
    • + +
    + + +## Notes + +- `delete()` should always be combined with [filters](/docs/reference/javascript/using-filters) to target the item(s) you wish to delete. +- If you use `delete()` with filters and you have + [RLS](/docs/learn/auth-deep-dive/auth-row-level-security) enabled, only + rows visible through `SELECT` policies are deleted. Note that by default + no rows are visible, so you need at least one `SELECT`/`ALL` policy that + makes the rows visible. + + + + + + + + + + +## Examples + +### Delete records + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .delete() + .match({ id: 666 }) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/eq.mdx b/apps/temp-docs/docs/reference/javascript/eq.mdx new file mode 100644 index 00000000000..57a536977bf --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/eq.mdx @@ -0,0 +1,186 @@ +--- +id: eq +title: ".eq()" +slug: eq +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose value on the stated `column` exactly matches the +specified `value`. + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .eq('name', 'The shire') +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + column + + + required + + + object + +

      +
      + +The column to filter on. + +
      + +
    • + + +
    • +

      + + value + + + required + + + object + +

      +
      + +The value to filter with. + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .eq('name', 'The shire') +``` + + + + + + +### With `update()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .update({ name: 'Mordor' }) + .eq('name', 'San Francisco') +``` + + + + + + +### With `delete()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .delete() + .eq('name', 'Mordor') +``` + + + + + + +### With `rpc()` + + + + + + + +```js +// Only valid if the Postgres function returns a table type. +const { data, error } = await supabase + .rpc('echo_all_cities') + .eq('name', 'San Francisco') +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/filter.mdx b/apps/temp-docs/docs/reference/javascript/filter.mdx new file mode 100644 index 00000000000..4dcd39afe94 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/filter.mdx @@ -0,0 +1,230 @@ +--- +id: filter +title: ".filter()" +slug: filter +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose `column` satisfies the filter. + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .filter('name', 'in', '("Paris","Tokyo")') +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + column + + + required + + + object + +

      +
      + +The column to filter on. + +
      + +
    • + + +
    • +

      + + operator + + + required + + + FilterOperator + +

      +
      + +The operator to filter with. + +
      + +
    • + + +
    • +

      + + value + + + required + + + any + +

      +
      + +The value to filter with. + +
      + +
    • + +
    + + +## Notes + +- `.filter()` expects you to use the raw [PostgREST syntax](https://postgrest.org/en/stable/api.html#horizontal-filtering-rows) for the filter values, so it should only be used as an escape hatch in case other filters don't work. + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .filter('name', 'in', '("Paris","Tokyo")') +``` + + + + + + +### With `update()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .update({ name: 'Mordor' }) + .filter('name', 'in', '("Paris","Tokyo")') +``` + + + + + + +### With `delete()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .delete() + .filter('name', 'in', '("Paris","Tokyo")') +``` + + + + + + +### With `rpc()` + + + + + + + +```js +// Only valid if the Postgres function returns a table type. +const { data, error } = await supabase + .rpc('echo_all_cities') + .filter('name', 'in', '("Paris","Tokyo")') +``` + + + + + + +### Filter embedded resources + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, countries ( name )') + .filter('countries.name', 'in', '("France","Japan")') +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/generating-types.mdx b/apps/temp-docs/docs/reference/javascript/generating-types.mdx new file mode 100644 index 00000000000..70f24120dd4 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/generating-types.mdx @@ -0,0 +1,136 @@ +--- +id: generating-types +title: "Generating Types" +slug: generating-types +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Supabase will soon release native type generators that dump your database types for various languages. For now, we support TypeScript through a third-party tool. + +## Usage with TypeScript + +`supabase-js` ships with type definitions for usage with TypeScript and for convenient IntelliSense auto-complete and documentation in your editor. + +When using TypeScript, you can pass the type of database row as a type parameter to the `from` method to get better auto-completion support down the chain. +If you don't provide a type for the row you need to explicitly pass `from('tableName')`. + +```ts +type Message = { + id: number; + inserted_at: string; + message: string; + user_id: string; + channel_id: number; + author: { username: string }; +} + +const response = await supabase + .from('messages') // Message maps to the type of the row in your database. + .select('*, author:user_id(username)') + .match({ channel_id: 2 }) // Your IDE will be able to help with auto-completion. +response.data // Response data will be of type Array. + +// If you don't provide a type for the row you need to explicitly pass `from('tableName')`. +const response = await supabase + .from('messages') + .select('*, author:user_id(username)') + .match({ channel_id: 2 }) +response.data // Response data will be of type Array. +``` + +### Generate database types from OpenAPI specification + +Supabase generates an OpenAPI specification file for your database which can be used to generate your data types for usage with TypeScript. + +The OpenAPI specification for your Supabase project can be accessed as follows: + +```txt +https://your-project.supabase.co/rest/v1/?apikey=your-anon-key +``` + +Using the open source [openapi-typescript](https://github.com/drwpow/openapi-typescript#%EF%B8%8F-reading-specs-from-remote-resource) tool you can generate your types and store them locally: + +```bash +npx openapi-typescript https://your-project.supabase.co/rest/v1/?apikey=your-anon-key --output types/supabase.ts +``` + +Important notes: + +- Since the generator uses JSON API, there is no way to determine if a column is an Array. It will generate array types as `string`, even though Supabase handles this automatically and returns arrays. + You can fix this manually in the files by changing the type, e.g. `names: string` -> `names: string[]` +- The types won't automatically stay in sync with your database, so make sure to regenerate your types after your make changes to your database. + +After you have generated your types, you can use them in your TypeScript projects: + +```ts +import { NextApiRequest, NextApiResponse } from "next"; +import { createClient } from "@supabase/supabase-js"; +import { definitions } from "../../types/supabase"; + +const supabase = createClient( + process.env.NEXT_PUBLIC_SUPABASE_URL, + process.env.SUPABASE_SECRET_KEY +); + +export default async (req: NextApiRequest, res: NextApiResponse) => { + const allOnlineUsers = await supabase + .from("users") + .select("*") + .eq("status", "ONLINE"); + res.status(200).json(allOnlineUsers); +}; +``` + +### Update types automatically with GitHub Actions + +One way to keep your type definitions in sync with your database is to set up a GitHub action that runs on a schedule. + +Add a script to your package.json to generate the types: + +``` +"update-types": "npx openapi-typescript https://your-project.supabase.co/rest/v1/?apikey=your-anon-key --output types/database/index.ts" +``` + +In your repo, create the file `.github/workflows/update-types.yml`. Add the following snippet into this file to define the action. If there is a change to your definitions, this script will commit the change to your repo. + +```yml +name: Update database types + +on: + schedule: + # sets the action to run daily. You can modify this to run the action more or less frequently + - cron: '0 0 * * *' + +jobs: + update: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + persist-credentials: false + fetch-depth: 0 + - uses: actions/setup-node@v2.1.5 + with: + node-version: 14 + - run: npm run update-types + - name: check for file changes + id: git_status + run: | + echo "::set-output name=status::$(git status -s)" + - name: Commit files + if: ${{contains(steps.git_status.outputs.status, ' ')}} + run: | + git add types/database/index.ts + git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" + git config --local user.name "github-actions[bot]" + git commit -m "Update database types" -a + - name: Push changes + if: ${{contains(steps.git_status.outputs.status, ' ')}} + uses: ad-m/github-push-action@master + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + branch: ${{ github.ref }} +``` \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/getsubscriptions.mdx b/apps/temp-docs/docs/reference/javascript/getsubscriptions.mdx new file mode 100644 index 00000000000..7e98d88a575 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/getsubscriptions.mdx @@ -0,0 +1,65 @@ +--- +id: getsubscriptions +title: "getSubscriptions()" +slug: getsubscriptions +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Returns an array of all your subscriptions. + + + + + +```js +const subscriptions = supabase.getSubscriptions() +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### Get all subscriptions + + + + + + + +```js +const subscriptions = supabase.getSubscriptions() +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/gt.mdx b/apps/temp-docs/docs/reference/javascript/gt.mdx new file mode 100644 index 00000000000..159221aabd6 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/gt.mdx @@ -0,0 +1,186 @@ +--- +id: gt +title: ".gt()" +slug: gt +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose value on the stated `column` is greater than the +specified `value`. + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .gt('country_id', 250) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + column + + + required + + + object + +

      +
      + +The column to filter on. + +
      + +
    • + + +
    • +

      + + value + + + required + + + object + +

      +
      + +The value to filter with. + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .gt('country_id', 250) +``` + + + + + + +### With `update()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .update({ name: 'Mordor' }) + .gt('country_id', 250) +``` + + + + + + +### With `delete()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .delete() + .gt('country_id', 250) +``` + + + + + + +### With `rpc()` + + + + + + + +```js +// Only valid if the Postgres function returns a table type. +const { data, error } = await supabase + .rpc('echo_all_cities') + .gt('country_id', 250) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/gte.mdx b/apps/temp-docs/docs/reference/javascript/gte.mdx new file mode 100644 index 00000000000..eb67a61bcd8 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/gte.mdx @@ -0,0 +1,186 @@ +--- +id: gte +title: ".gte()" +slug: gte +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose value on the stated `column` is greater than or +equal to the specified `value`. + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .gte('country_id', 250) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + column + + + required + + + object + +

      +
      + +The column to filter on. + +
      + +
    • + + +
    • +

      + + value + + + required + + + object + +

      +
      + +The value to filter with. + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .gte('country_id', 250) +``` + + + + + + +### With `update()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .update({ name: 'Mordor' }) + .gte('country_id', 250) +``` + + + + + + +### With `delete()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .delete() + .gte('country_id', 250) +``` + + + + + + +### With `rpc()` + + + + + + + +```js +// Only valid if the Postgres function returns a table type. +const { data, error } = await supabase + .rpc('echo_all_cities') + .gte('country_id', 250) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/ilike.mdx b/apps/temp-docs/docs/reference/javascript/ilike.mdx new file mode 100644 index 00000000000..94090260f1e --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/ilike.mdx @@ -0,0 +1,186 @@ +--- +id: ilike +title: ".ilike()" +slug: ilike +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose value in the stated `column` matches the supplied +`pattern` (case insensitive). + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .ilike('name', '%la%') +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + column + + + required + + + object + +

      +
      + +The column to filter on. + +
      + +
    • + + +
    • +

      + + pattern + + + required + + + string + +

      +
      + +The pattern to filter with. + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .ilike('name', '%la%') +``` + + + + + + +### With `update()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .update({ name: 'Mordor' }) + .ilike('name', '%la%') +``` + + + + + + +### With `delete()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .delete() + .ilike('name', '%la%') +``` + + + + + + +### With `rpc()` + + + + + + + +```js +// Only valid if the Postgres function returns a table type. +const { data, error } = await supabase + .rpc('echo_all_cities') + .ilike('name', '%la%') +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/in.mdx b/apps/temp-docs/docs/reference/javascript/in.mdx new file mode 100644 index 00000000000..09c29d98692 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/in.mdx @@ -0,0 +1,186 @@ +--- +id: in +title: ".in()" +slug: in +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose value on the stated `column` is found on the +specified `values`. + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .in('name', ['Rio de Janeiro', 'San Francisco']) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + column + + + required + + + object + +

      +
      + +The column to filter on. + +
      + +
    • + + +
    • +

      + + values + + + required + + + object + +

      +
      + +The values to filter with. + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .in('name', ['Rio de Janeiro', 'San Francisco']) +``` + + + + + + +### With `update()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .update({ name: 'Mordor' }) + .in('name', ['Rio de Janeiro', 'San Francisco']) +``` + + + + + + +### With `delete()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .delete() + .in('name', ['Rio de Janeiro', 'San Francisco']) +``` + + + + + + +### With `rpc()` + + + + + + + +```js +// Only valid if the Postgres function returns a table type. +const { data, error } = await supabase + .rpc('echo_all_cities') + .in('name', ['Rio de Janeiro', 'San Francisco']) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/initializing.mdx b/apps/temp-docs/docs/reference/javascript/initializing.mdx new file mode 100644 index 00000000000..39bd9890b98 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/initializing.mdx @@ -0,0 +1,211 @@ +--- +id: initializing +title: "Initializing" +slug: initializing +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +You can initialize a new Supabase client using the `createClient()` method. + +The Supabase client is your entrypoint to the rest of the Supabase functionality +and is the easiest way to interact with everything we offer within the Supabase ecosystem. + + + + +## Parameters + + +
      + +
    • +

      + + supabaseUrl + + + required + + + string + +

      +
      + +The unique Supabase URL which is supplied when you create a new project in your project dashboard. + +
      + +
    • + + +
    • +

      + + supabaseKey + + + required + + + string + +

      +
      + +The unique Supabase Key which is supplied when you create a new project in your project dashboard. + +
      + +
    • + + +
    • +

      + + options + + + optional + + + SupabaseClientOptions + +

      +
      + +No description provided. + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### createClient() + + + + + + + +```js +import { createClient } from '@supabase/supabase-js' + +// Create a single supabase client for interacting with your database +const supabase = createClient('https://xyzcompany.supabase.co', 'public-anon-key') +``` + + + + + + +### With additional parameters + + + + + + + +```js +import { createClient } from '@supabase/supabase-js' + +const options = { + schema: 'public', + headers: { 'x-my-custom-header': 'my-app-name' }, + autoRefreshToken: true, + persistSession: true, + detectSessionInUrl: true +} +const supabase = createClient("https://xyzcompany.supabase.co", "public-anon-key", options) +``` + + + + + + +### API schemas + + + + + + + +```js +import { createClient } from '@supabase/supabase-js' + +// Provide a custom schema. Defaults to "public". +const supabase = createClient('https://xyzcompany.supabase.co', 'public-anon-key', { + schema: 'other_schema' +}) +``` + +By default the API server points to the `public` schema. You can enable other database schemas within the Dashboard. +Go to `Settings > API > Schema` and add the schema which you want to expose to the API. + +Note: each client connection can only access a single schema, so the code above can access the `other_schema` schema but cannot access the `public` schema. + + + + + + +### Custom `fetch` implementation + + + + + + + +```js +import { createClient } from '@supabase/supabase-js' + +const supabase = createClient('https://xyzcompany.supabase.co', 'public-anon-key', { + fetch: fetch.bind(globalThis) +}) +``` + +`supabase-js` uses the [`cross-fetch`](https://www.npmjs.com/package/cross-fetch) library to make HTTP requests, +but an alternative `fetch` implementation can be provided as an option. +This is most useful in environments where `cross-fetch` is not compatible (for instance Cloudflare Workers). + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/insert.mdx b/apps/temp-docs/docs/reference/javascript/insert.mdx new file mode 100644 index 00000000000..abaf8b0eda2 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/insert.mdx @@ -0,0 +1,179 @@ +--- +id: insert +title: "Create data: insert()" +slug: insert +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Performs an INSERT into the table. + + + + + +```js +const { data, error } = await supabase + .from('cities') + .insert([ + { name: 'The Shire', country_id: 554 } + ]) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + values + + + required + + + Partial | array + +

      +
      + +The values to insert. + +
      + +
    • + + +
    • +

      + + options + + + optional + + + undefined | reflection + +

      +
      + +No description provided. + +
      + +
    • + +
    + + +## Notes + +- By default, every time you run `insert()`, the client library will make a `select` to return the full record. +This is convenient, but it can also cause problems if your Policies are not configured to allow the `select` operation. +If you are using Row Level Security and you are encountering problems, try setting the `returning` param to `minimal`. + + + + + + + + + + +## Examples + +### Create a record + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .insert([ + { name: 'The Shire', country_id: 554 } + ]) +``` + + + + + + +### Bulk create + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .insert([ + { name: 'The Shire', country_id: 554 }, + { name: 'Rohan', country_id: 555 }, + ]) +``` + + + + + + +### Upsert + +For upsert, if set to true, primary key columns would need to be included +in the data parameter in order for an update to properly happen. Also, primary keys +used must be natural, not surrogate. There are however, +[workarounds](https://github.com/PostgREST/postgrest/issues/1118) +for surrogate primary keys. + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .insert( + [ + { name: 'The Shire', country_id: 554 }, + { name: 'Rohan', country_id: 555 }, + { name: 'City by the Bay', country_id:840} + ], + { upsert: true }) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/installing.mdx b/apps/temp-docs/docs/reference/javascript/installing.mdx new file mode 100644 index 00000000000..aeb6b0fff5a --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/installing.mdx @@ -0,0 +1,42 @@ +--- +id: installing +title: "Installing" +slug: installing +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +All JavaScript libraries are built directly by the Supabase team. + +Other languages are built by the community and supported by Supabase. + +## JavaScript + +Via NPM +```bash +npm install @supabase/supabase-js +``` + +Via Yarn +```bash +yarn add @supabase/supabase-js +``` + +Find the source code on [GitHub](https://github.com/supabase/supabase-js). + +Or via CDN +```js + +//or + +``` + +## Python + +```bash +pip install supabase-py +``` + +Find the source code on [GitHub](https://github.com/supabase/supabase-py). \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/is.mdx b/apps/temp-docs/docs/reference/javascript/is.mdx new file mode 100644 index 00000000000..fb75d615a60 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/is.mdx @@ -0,0 +1,186 @@ +--- +id: is +title: ".is()" +slug: is +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +A check for exact equality (null, true, false), finds all rows whose +value on the stated `column` exactly match the specified `value`. + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .is('name', null) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + column + + + required + + + object + +

      +
      + +The column to filter on. + +
      + +
    • + + +
    • +

      + + value + + + required + + + boolean | null + +

      +
      + +The value to filter with. + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .is('name', null) +``` + + + + + + +### With `update()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .update({ name: 'Mordor' }) + .is('name', null) +``` + + + + + + +### With `delete()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .delete() + .is('name', null) +``` + + + + + + +### With `rpc()` + + + + + + + +```js +// Only valid if the Postgres function returns a table type. +const { data, error } = await supabase + .rpc('echo_all_cities') + .is('name', null) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/like.mdx b/apps/temp-docs/docs/reference/javascript/like.mdx new file mode 100644 index 00000000000..fee839bf02f --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/like.mdx @@ -0,0 +1,186 @@ +--- +id: like +title: ".like()" +slug: like +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose value in the stated `column` matches the supplied +`pattern` (case sensitive). + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .like('name', '%la%') +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + column + + + required + + + object + +

      +
      + +The column to filter on. + +
      + +
    • + + +
    • +

      + + pattern + + + required + + + string + +

      +
      + +The pattern to filter with. + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .like('name', '%la%') +``` + + + + + + +### With `update()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .update({ name: 'Mordor' }) + .like('name', '%la%') +``` + + + + + + +### With `delete()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .delete() + .like('name', '%la%') +``` + + + + + + +### With `rpc()` + + + + + + + +```js +// Only valid if the Postgres function returns a table type. +const { data, error } = await supabase + .rpc('echo_all_cities') + .like('name', '%la%') +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/limit.mdx b/apps/temp-docs/docs/reference/javascript/limit.mdx new file mode 100644 index 00000000000..6d7f0708e65 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/limit.mdx @@ -0,0 +1,165 @@ +--- +id: limit +title: "limit()" +slug: limit +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Limits the result with the specified `count`. + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .limit(1) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + count + + + required + + + number + +

      +
      + +The maximum no. of rows to limit to. + +
      + +
    • + + +
    • +

      + + __namedParameters + + + required + + + object + +

      +
      + +No description provided. + +
      + +
        +
        Properties
        + +
      • +

        + + foreignTable + + + required + + + undefined | string + +

        +
        + +The foreign table to use (for foreign columns). + +
        + +
      • + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .limit(1) +``` + + + + + + +### With embedded resources + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .select('name, cities(name)') + .eq('name', 'United States') + .limit(1, { foreignTable: 'cities' }) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/lt.mdx b/apps/temp-docs/docs/reference/javascript/lt.mdx new file mode 100644 index 00000000000..dff252d9bc3 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/lt.mdx @@ -0,0 +1,186 @@ +--- +id: lt +title: ".lt()" +slug: lt +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose value on the stated `column` is less than the +specified `value`. + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .lt('country_id', 250) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + column + + + required + + + object + +

      +
      + +The column to filter on. + +
      + +
    • + + +
    • +

      + + value + + + required + + + object + +

      +
      + +The value to filter with. + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .lt('country_id', 250) +``` + + + + + + +### With `update()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .update({ name: 'Mordor' }) + .lt('country_id', 250) +``` + + + + + + +### With `delete()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .delete() + .lt('country_id', 250) +``` + + + + + + +### With `rpc()` + + + + + + + +```js +// Only valid if the Postgres function returns a table type. +const { data, error } = await supabase + .rpc('echo_all_cities') + .lt('country_id', 250) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/lte.mdx b/apps/temp-docs/docs/reference/javascript/lte.mdx new file mode 100644 index 00000000000..cd783f12d9d --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/lte.mdx @@ -0,0 +1,186 @@ +--- +id: lte +title: ".lte()" +slug: lte +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose value on the stated `column` is less than or equal +to the specified `value`. + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .lte('country_id', 250) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + column + + + required + + + object + +

      +
      + +The column to filter on. + +
      + +
    • + + +
    • +

      + + value + + + required + + + object + +

      +
      + +The value to filter with. + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .lte('country_id', 250) +``` + + + + + + +### With `update()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .update({ name: 'Mordor' }) + .lte('country_id', 250) +``` + + + + + + +### With `delete()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .delete() + .lte('country_id', 250) +``` + + + + + + +### With `rpc()` + + + + + + + +```js +// Only valid if the Postgres function returns a table type. +const { data, error } = await supabase + .rpc('echo_all_cities') + .lte('country_id', 250) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/match.mdx b/apps/temp-docs/docs/reference/javascript/match.mdx new file mode 100644 index 00000000000..2c705811778 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/match.mdx @@ -0,0 +1,165 @@ +--- +id: match +title: ".match()" +slug: match +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose columns match the specified `query` object. + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .match({name: 'Beijing', country_id: 156}) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + query + + + required + + + Record + +

      +
      + +The object to filter with, with column names as keys mapped + to their filter values. + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .match({name: 'Beijing', country_id: 156}) +``` + + + + + + +### With `update()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .update({ name: 'Mordor' }) + .match({name: 'Beijing', country_id: 156}) +``` + + + + + + +### With `delete()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .delete() + .match({name: 'Beijing', country_id: 156}) +``` + + + + + + +### With `rpc()` + + + + + + + +```js +// Only valid if the Postgres function returns a table type. +const { data, error } = await supabase + .rpc('echo_all_cities') + .match({name: 'Beijing', country_id: 156}) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/maybesingle.mdx b/apps/temp-docs/docs/reference/javascript/maybesingle.mdx new file mode 100644 index 00000000000..8e41b958d20 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/maybesingle.mdx @@ -0,0 +1,75 @@ +--- +id: maybesingle +title: "maybeSingle()" +slug: maybesingle +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Retrieves at most one row from the result. Result must be at most one row +(e.g. using `eq` on a UNIQUE column), otherwise this will result in an +error. + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .eq('name', 'Singapore') + .maybeSingle() +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .eq('name', 'Singapore') + .maybeSingle() +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/neq.mdx b/apps/temp-docs/docs/reference/javascript/neq.mdx new file mode 100644 index 00000000000..3793d89dea2 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/neq.mdx @@ -0,0 +1,186 @@ +--- +id: neq +title: ".neq()" +slug: neq +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose value on the stated `column` doesn't match the +specified `value`. + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .neq('name', 'The shire') +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + column + + + required + + + object + +

      +
      + +The column to filter on. + +
      + +
    • + + +
    • +

      + + value + + + required + + + object + +

      +
      + +The value to filter with. + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .neq('name', 'The shire') +``` + + + + + + +### With `update()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .update({ name: 'Mordor' }) + .neq('name', 'San Francisco') +``` + + + + + + +### With `delete()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .delete() + .neq('name', 'Mordor') +``` + + + + + + +### With `rpc()` + + + + + + + +```js +// Only valid if the Postgres function returns a table type. +const { data, error } = await supabase + .rpc('echo_all_cities') + .neq('name', 'Lagos') +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/not.mdx b/apps/temp-docs/docs/reference/javascript/not.mdx new file mode 100644 index 00000000000..2d9ce2cae81 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/not.mdx @@ -0,0 +1,206 @@ +--- +id: not +title: ".not()" +slug: not +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows which doesn't satisfy the filter. + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .not('name', 'eq', 'Paris') +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + column + + + required + + + object + +

      +
      + +The column to filter on. + +
      + +
    • + + +
    • +

      + + operator + + + required + + + FilterOperator + +

      +
      + +The operator to filter with. + +
      + +
    • + + +
    • +

      + + value + + + required + + + any + +

      +
      + +The value to filter with. + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .not('name', 'eq', 'Paris') +``` + + + + + + +### With `update()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .update({ name: 'Mordor' }) + .not('name', 'eq', 'Paris') +``` + + + + + + +### With `delete()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .delete() + .not('name', 'eq', 'Paris') +``` + + + + + + +### With `rpc()` + + + + + + + +```js +// Only valid if the Postgres function returns a table type. +const { data, error } = await supabase + .rpc('echo_all_cities') + .not('name', 'eq', 'Paris') +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/or.mdx b/apps/temp-docs/docs/reference/javascript/or.mdx new file mode 100644 index 00000000000..f4dcc9ec923 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/or.mdx @@ -0,0 +1,187 @@ +--- +id: or +title: ".or()" +slug: or +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows satisfying at least one of the filters. + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .or('id.eq.20,id.eq.30') +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + filters + + + required + + + string + +

      +
      + +The filters to use, separated by commas. + +
      + +
    • + + +
    • +

      + + __namedParameters + + + required + + + object + +

      +
      + +No description provided. + +
      + +
        +
        Properties
        + +
      • +

        + + foreignTable + + + required + + + undefined | string + +

        +
        + +The foreign table to use (if `column` is a foreign column). + +
        + +
      • + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .or('id.eq.20,id.eq.30') +``` + + + + + + +### Use `or` with `and` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .or('id.gt.20,and(name.eq.New Zealand,name.eq.France)') +``` + + + + + + +### Use `or` on foreign tables + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .select('id, cities(*)') + .or('name.eq.Wellington,name.eq.Paris', { foreignTable: "cities" }) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/order.mdx b/apps/temp-docs/docs/reference/javascript/order.mdx new file mode 100644 index 00000000000..c8b536b8bc0 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/order.mdx @@ -0,0 +1,207 @@ +--- +id: order +title: "order()" +slug: order +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Orders the result with the specified `column`. + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name', 'country_id') + .order('id', { ascending: false }) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + column + + + required + + + object + +

      +
      + +The column to order on. + +
      + +
    • + + +
    • +

      + + __namedParameters + + + required + + + object + +

      +
      + +No description provided. + +
      + +
        +
        Properties
        + +
      • +

        + + nullsFirst + + + required + + + boolean + +

        +
        + +If `true`, `null`s appear first. + +
        + +
      • + + +
      • +

        + + foreignTable + + + required + + + undefined | string + +

        +
        + +The foreign table to use (if `column` is a foreign column). + +
        + +
      • + + +
      • +

        + + ascending + + + required + + + boolean + +

        +
        + +If `true`, the result will be in ascending order. + +
        + +
      • + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name', 'country_id') + .order('id', { ascending: false }) +``` + + + + + + +### With embedded resources + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .select('name, cities(name)') + .eq('name', 'United States') + .order('name', {foreignTable: 'cities'}) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/overlaps.mdx b/apps/temp-docs/docs/reference/javascript/overlaps.mdx new file mode 100644 index 00000000000..b396a179145 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/overlaps.mdx @@ -0,0 +1,140 @@ +--- +id: overlaps +title: ".overlaps()" +slug: overlaps +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .select('name, id, main_exports') + .overlaps('main_exports', ['computers', 'minerals']) +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .select('name, id, main_exports') + .overlaps('main_exports', ['computers', 'minerals']) +``` + + + + + + +### With `update()` + + + + + + + +```js +let countries = await supabase + .from('countries') + .update({ name: 'Mordor' }) + .overlaps('main_exports', ['computers', 'minerals']) +``` + + + + + + +### With `delete()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .delete() + .overlaps('main_exports', ['computers', 'minerals']) +``` + + + + + + +### With `rpc()` + + + + + + + +```js +// Only valid if the Postgres function returns a table type. +const { data, error } = await supabase + .rpc('echo_all_countries') + .overlaps('main_exports', ['computers', 'minerals']) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/range.mdx b/apps/temp-docs/docs/reference/javascript/range.mdx new file mode 100644 index 00000000000..00b8532b0f2 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/range.mdx @@ -0,0 +1,162 @@ +--- +id: range +title: "range()" +slug: range +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Limits the result to rows within the specified range, inclusive. + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .range(0,3) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + from + + + required + + + number + +

      +
      + +The starting index from which to limit the result, inclusive. + +
      + +
    • + + +
    • +

      + + to + + + required + + + number + +

      +
      + +The last index to which to limit the result, inclusive. + +
      + +
    • + + +
    • +

      + + __namedParameters + + + required + + + object + +

      +
      + +No description provided. + +
      + +
        +
        Properties
        + +
      • +

        + + foreignTable + + + required + + + undefined | string + +

        +
        + +The foreign table to use (for foreign columns). + +
        + +
      • + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .range(0,3) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/rangeadjacent.mdx b/apps/temp-docs/docs/reference/javascript/rangeadjacent.mdx new file mode 100644 index 00000000000..5197c6baf77 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/rangeadjacent.mdx @@ -0,0 +1,140 @@ +--- +id: rangeadjacent +title: ".rangeAdjacent()" +slug: rangeadjacent +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .select('name, id, population_range_millions') + .rangeAdjacent('population_range_millions', [70, 185]) +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .select('name, id, population_range_millions') + .rangeAdjacent('population_range_millions', [70, 185]) +``` + + + + + + +### With `update()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .update({ name: 'Mordor' }) + .rangeAdjacent('population_range_millions', [70, 185]) +``` + + + + + + +### With `delete()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .delete() + .rangeAdjacent('population_range_millions', [70, 185]) +``` + + + + + + +### With `rpc()` + + + + + + + +```js +// Only valid if the Postgres function returns a table type. +const { data, error } = await supabase + .rpc('echo_all_countries') + .rangeAdjacent('population_range_millions', [70, 185]) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/rangegt.mdx b/apps/temp-docs/docs/reference/javascript/rangegt.mdx new file mode 100644 index 00000000000..c152a4222a1 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/rangegt.mdx @@ -0,0 +1,140 @@ +--- +id: rangegt +title: ".rangeGt()" +slug: rangegt +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .select('name, id, population_range_millions') + .rangeGt('population_range_millions', [150, 250]) +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .select('name, id, population_range_millions') + .rangeGt('population_range_millions', [150, 250]) +``` + + + + + + +### With `update()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .update({ name: 'Mordor' }) + .rangeGt('population_range_millions', [150, 250]) +``` + + + + + + +### With `delete()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .delete() + .rangeGt('population_range_millions', [150, 250]) +``` + + + + + + +### With `rpc()` + + + + + + + +```js +// Only valid if the Postgres function returns a table type. +const { data, error } = await supabase + .rpc('echo_all_countries') + .rangeGt('population_range_millions', [150, 250]) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/rangegte.mdx b/apps/temp-docs/docs/reference/javascript/rangegte.mdx new file mode 100644 index 00000000000..1d7fd697384 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/rangegte.mdx @@ -0,0 +1,140 @@ +--- +id: rangegte +title: ".rangeGte()" +slug: rangegte +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .select('name, id, population_range_millions') + .rangeGte('population_range_millions', [150, 250]) +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .select('name, id, population_range_millions') + .rangeGte('population_range_millions', [150, 250]) +``` + + + + + + +### With `update()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .update({ name: 'Mordor' }) + .rangeGte('population_range_millions', [150, 250]) +``` + + + + + + +### With `delete()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .delete() + .rangeGte('population_range_millions', [150, 250]) +``` + + + + + + +### With `rpc()` + + + + + + + +```js +// Only valid if the Postgres function returns a table type. +const { data, error } = await supabase + .rpc('echo_all_countries') + .rangeGte('population_range_millions', [150, 250]) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/rangelt.mdx b/apps/temp-docs/docs/reference/javascript/rangelt.mdx new file mode 100644 index 00000000000..3663dacc60b --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/rangelt.mdx @@ -0,0 +1,140 @@ +--- +id: rangelt +title: ".rangeLt()" +slug: rangelt +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .select('name, id, population_range_millions') + .rangeLt('population_range_millions', [150, 250]) +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .select('name, id, population_range_millions') + .rangeLt('population_range_millions', [150, 250]) +``` + + + + + + +### With `update()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .update({ name: 'Mordor' }) + .rangeLt('population_range_millions', [150, 250]) +``` + + + + + + +### With `delete()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .delete() + .rangeLt('population_range_millions', [150, 250]) +``` + + + + + + +### With `rpc()` + + + + + + + +```js +// Only valid if the Postgres function returns a table type. +const { data, error } = await supabase + .rpc('echo_all_countries') + .rangeLt('population_range_millions', [150, 250]) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/rangelte.mdx b/apps/temp-docs/docs/reference/javascript/rangelte.mdx new file mode 100644 index 00000000000..538d45770f3 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/rangelte.mdx @@ -0,0 +1,140 @@ +--- +id: rangelte +title: ".rangeLte()" +slug: rangelte +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .select('name, id, population_range_millions') + .rangeLte('population_range_millions', [150, 250]) +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .select('name, id, population_range_millions') + .rangeLte('population_range_millions', [150, 250]) +``` + + + + + + +### With `update()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .update({ name: 'Mordor' }) + .rangeLte('population_range_millions', [150, 250]) +``` + + + + + + +### With `delete()` + + + + + + + +```js +const { data, error } = await supabase + .from('countries') + .delete() + .rangeLte('population_range_millions', [150, 250]) +``` + + + + + + +### With `rpc()` + + + + + + + +```js +// Only valid if the Postgres function returns a table type. +const { data, error } = await supabase + .rpc('echo_all_countries') + .rangeLte('population_range_millions', [150, 250]) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/removeallsubscriptions.mdx b/apps/temp-docs/docs/reference/javascript/removeallsubscriptions.mdx new file mode 100644 index 00000000000..6786350333a --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/removeallsubscriptions.mdx @@ -0,0 +1,66 @@ +--- +id: removeallsubscriptions +title: "removeAllSubscriptions()" +slug: removeallsubscriptions +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Removes all subscriptions and disconnects the Websocket connection. + + + + + +```js +supabase.removeAllSubscriptions() +``` + + + + + + + + + + +## Notes + +- Removing subscriptions is a great way to maintain the performance of your project's database. Supabase will automatically handle cleanup 30 seconds after a user is disconnected, but unused subscriptions may cause degradation as more users are simultaneously subscribed. + + + + + + + + + + +## Examples + +### Removes all subscriptions + + + + + + + +```js +supabase.removeAllSubscriptions() +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/removesubscription.mdx b/apps/temp-docs/docs/reference/javascript/removesubscription.mdx new file mode 100644 index 00000000000..53c2a6b7a94 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/removesubscription.mdx @@ -0,0 +1,90 @@ +--- +id: removesubscription +title: "removeSubscription()" +slug: removesubscription +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Removes an active subscription and returns the number of open connections. + + + + + +```js +supabase.removeSubscription(mySubscription) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + subscription + + + required + + + RealtimeSubscription + +

      +
      + +The subscription you want to remove. + +
      + +
    • + +
    + + +## Notes + +- Removing subscriptions is a great way to maintain the performance of your project's database. Supabase will automatically handle cleanup 30 seconds after a user is disconnected, but unused subscriptions may cause degradation as more users are simultaneously subscribed. + + + + + + + + + + +## Examples + +### Remove a subscription + + + + + + + +```js +supabase.removeSubscription(mySubscription) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/reset-password-email.mdx b/apps/temp-docs/docs/reference/javascript/reset-password-email.mdx new file mode 100644 index 00000000000..7dad6d33ed3 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/reset-password-email.mdx @@ -0,0 +1,151 @@ +--- +id: reset-password-email +title: "Reset Password (Email)" +slug: reset-password-email +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Sends a reset request to an email address. + + + + + +```js +const { data, error } = supabase.auth.api + .resetPasswordForEmail('user@email.com') +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + email + + + required + + + string + +

      +
      + +The email address of the user. + +
      + +
    • + + +
    • +

      + + options + + + required + + + object + +

      +
      + +No description provided. + +
      + +
        +
        Properties
        + +
      • +

        + + redirectTo + + + optional + + + string + +

        +
        + +No description provided. + +
        + +
      • + +
      + +
    • + +
    + + +## Notes + +Sends a reset request to an email address. + +When the user clicks the reset link in the email they will be forwarded to: + +`#access_token=x&refresh_token=y&expires_in=z&token_type=bearer&type=recovery` + +Your app must detect `type=recovery` in the fragment and display a password reset form to the user. + +You should then use the access_token in the url and new password to update the user as follows: + +```js +const { error, data } = await supabase.auth.api + .updateUser(access_token, { password : new_password }) +``` + + + + + + + + + + +## Examples + +### Reset password + + + + + + + +```js +const { data, error } = supabase.auth.api + .resetPasswordForEmail('user@email.com') +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/rpc.mdx b/apps/temp-docs/docs/reference/javascript/rpc.mdx new file mode 100644 index 00000000000..5a664ee1a86 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/rpc.mdx @@ -0,0 +1,274 @@ +--- +id: rpc +title: "Postgres functions: rpc()" +slug: rpc +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +You can call Postgres functions as a "Remote Procedure Call". + +That's a fancy way of saying that you can put some logic into your database then call it from anywhere. +It's especially useful when the logic rarely changes - like password resets and updates. + + + + + + +```js +const { data, error } = await supabase + .rpc('hello_world') +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + fn + + + required + + + string + +

      +
      + +The function name to call. + +
      + +
    • + + +
    • +

      + + params + + + optional + + + undefined | object + +

      +
      + +The parameters to pass to the function call. + +
      + +
    • + + +
    • +

      + + __namedParameters + + + required + + + object + +

      +
      + +No description provided. + +
      + +
        +
        Properties
        + +
      • +

        + + head + + + required + + + boolean + +

        +
        + +When set to true, no data will be returned. + +
        + +
      • + + +
      • +

        + + count + + + required + + + null | exact | planned | estimated + +

        +
        + +Count algorithm to use to count rows in a table. + +
        + +
      • + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### Call a Postgres function + +This is an example of invoking a Postgres function. + + + + + +```js +const { data, error } = await supabase + .rpc('hello_world') +``` + + + + + + +### With Parameters + + + + + + + +```js +const { data, error } = await supabase + .rpc('echo_city', { name: 'The Shire' }) +``` + + + + + + +### Bulk processing + +You can process large payloads at once using [array parameters](https://postgrest.org/en/stable/api.html#calling-functions-with-array-parameters). + + + + + +```js +const { data, error } = await postgrest + .rpc('echo_cities', { names: ['The Shire', 'Mordor'] }) +``` + + + + + + +### With filters + +Postgres functions that return tables can also be combined with +[Modifiers](/docs/reference/javascript/using-modifiers) and +[Filters](/docs/reference/javascript/using-filters). + + + + + + +```js +const { data, error } = await supabase + .rpc('echo_all_cities') + .select('name, population') + .eq('name', 'The Shire') +``` + + + + + + +### With count option + +You can specify a count option to get the row count along with your data. +Allowed values for count option are `null`, `exact`, `planned` and `estimated`. + + + + + + +```js +const { data, error, count } = await supabase + .rpc('hello_world', {}, { count: 'exact' }) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/select.mdx b/apps/temp-docs/docs/reference/javascript/select.mdx new file mode 100644 index 00000000000..37ee18cf1c9 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/select.mdx @@ -0,0 +1,388 @@ +--- +id: select +title: "Fetch data: select()" +slug: select +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Performs vertical filtering with SELECT. + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select() +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + columns + + + optional + + + string + +

      +
      + +The columns to retrieve, separated by commas. + +
      + +
    • + + +
    • +

      + + __namedParameters + + + required + + + object + +

      +
      + +No description provided. + +
      + +
        +
        Properties
        + +
      • +

        + + head + + + required + + + boolean + +

        +
        + +When set to true, select will void data. + +
        + +
      • + + +
      • +

        + + count + + + required + + + null | exact | planned | estimated + +

        +
        + +Count algorithm to use to count rows in a table. + +
        + +
      • + +
      + +
    • + +
    + + +## Notes + +- By default, Supabase projects will return a maximum of 1,000 rows. This setting can be changed in Project API Settings. It's recommended that you keep it low to limit the payload size of accidental or malicious requests. You can use `range()` queries to paginate through your data. +- `select()` can be combined with [Modifiers](/docs/reference/javascript/using-modifiers) +- `select()` can be combined with [Filters](/docs/reference/javascript/using-filters) + + + + + + + + + + +## Examples + +### Getting your data + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select() +``` + + + + + + +### Selecting specific columns + +You can select specific fields from your tables. + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name') +``` + + + + + + +### Query foreign tables + +If your database has foreign key relationships, you can query related tables too. + + + + + +```js +const { data, error } = await supabase + .from('countries') + .select(` + name, + cities ( + name + ) + `) +``` + + + + + + +### Query the same foreign table multiple times + +Sometimes you will need to query the same foreign table twice. +In this case, you can use the name of the joined column to identify +which join you intend to use. For convenience, you can also give an +alias for each column. For example, if we had a shop of products, +and we wanted to get the supplier and the purchaser at the same time +(both in the users) table: + + + + + + +```js +const { data, error } = await supabase + .from('products') + .select(` + id, + supplier:supplier_id ( name ), + purchaser:purchaser_id ( name ) + `) +``` + + + + + + +### Filtering with inner joins + +If you want to filter a table based on a child table's values you can use the `!inner()` function. For example, if you wanted +to select all rows in a `message` table which belong to a user with the `username` "Jane": + + + + + + +```js +const { data, error } = await supabase + .from('messages') + .select('*, users!inner(*)') + .eq('users.username', 'Jane') +``` + + + + + + +### Querying with count option + +You can get the number of rows by using the count option. +Allowed values for count option are `null`, [exact](https://postgrest.org/en/stable/api.html#exact-count), [planned](https://postgrest.org/en/stable/api.html#planned-count) and [estimated](https://postgrest.org/en/stable/api.html#estimated-count). + + + + + + +```js +const { data, error, count } = await supabase + .from('cities') + .select('name', { count: 'exact' }) // if you don't want to return any rows, you can use { count: 'exact', head: true } +``` + + + + + + +### Querying JSON data + +If you have data inside of a JSONB column, you can apply select +and query filters to the data values. Postgres offers a +[number of operators](https://www.postgresql.org/docs/current/functions-json.html) +for querying JSON data. Also see +[PostgREST docs](http://postgrest.org/en/v7.0.0/api.html#json-columns) for more details. + + + + + + +```js +const { data, error } = await supabase + .from('users') + .select(` + id, name, + address->street + `) + .eq('address->postcode', 90210) +``` + + + + + + +### Return data as CSV + +By default the data is returned in JSON format, however you can also request for it to be returned as Comma Separated Values. + + + + + + +```js +const { data, error } = await supabase + .from('users') + .select() + .csv() +``` + + + + + + +### Aborting requests in-flight + +You can use an [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController) to abort requests. Note that `status` and `statusText` doesn't mean anything for aborted requests, since the request wasn't actually fulfilled. + + + + + + +```js +const ac = new AbortController() +supabase + .from('very_big_table') + .select() + .abortSignal(ac.signal) + .then(console.log) +ac.abort() +// { +// error: { +// message: 'FetchError: The user aborted a request.', +// details: '', +// hint: '', +// code: '' +// }, +// data: null, +// body: null, +// count: null, +// status: 400, +// statusText: 'Bad Request' +// } +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/single.mdx b/apps/temp-docs/docs/reference/javascript/single.mdx new file mode 100644 index 00000000000..abcc6a619cc --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/single.mdx @@ -0,0 +1,74 @@ +--- +id: single +title: "single()" +slug: single +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Retrieves only one row from the result. Result must be one row (e.g. using +`limit`), otherwise this will result in an error. + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .limit(1) + .single() +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### With `select()` + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .limit(1) + .single() +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/storage-createbucket.mdx b/apps/temp-docs/docs/reference/javascript/storage-createbucket.mdx new file mode 100644 index 00000000000..9da8ce977ad --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/storage-createbucket.mdx @@ -0,0 +1,142 @@ +--- +id: storage-createbucket +title: "createBucket()" +slug: storage-createbucket +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Creates a new Storage bucket + + + + + +```js +const { data, error } = await supabase + .storage + .createBucket('avatars', { public: false }) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + id + + + required + + + string + +

      +
      + +A unique identifier for the bucket you are creating. + +
      + +
    • + + +
    • +

      + + options + + + required + + + object + +

      +
      + +No description provided. + +
      + +
        +
        Properties
        + +
      • +

        + + public + + + required + + + boolean + +

        +
        + +No description provided. + +
        + +
      • + +
      + +
    • + +
    + + +## Notes + +- Policy permissions required: + - `buckets` permissions: `insert` + - `objects` permissions: none + + + + + + + + + + +## Examples + +### Create bucket + + + + + + + +```js +const { data, error } = await supabase + .storage + .createBucket('avatars', { public: false }) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/storage-deletebucket.mdx b/apps/temp-docs/docs/reference/javascript/storage-deletebucket.mdx new file mode 100644 index 00000000000..b246d8b6339 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/storage-deletebucket.mdx @@ -0,0 +1,97 @@ +--- +id: storage-deletebucket +title: "deleteBucket()" +slug: storage-deletebucket +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Deletes an existing bucket. A bucket can't be deleted with existing objects inside it. +You must first `empty()` the bucket. + + + + + +```js +const { data, error } = await supabase + .storage + .deleteBucket('avatars') +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + id + + + required + + + string + +

      +
      + +The unique identifier of the bucket you would like to delete. + +
      + +
    • + +
    + + +## Notes + +- Policy permissions required: + - `buckets` permissions: `select` and `delete` + - `objects` permissions: none + + + + + + + + + + +## Examples + +### Delete bucket + + + + + + + +```js +const { data, error } = await supabase + .storage + .deleteBucket('avatars') +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/storage-emptybucket.mdx b/apps/temp-docs/docs/reference/javascript/storage-emptybucket.mdx new file mode 100644 index 00000000000..698b18d97e1 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/storage-emptybucket.mdx @@ -0,0 +1,96 @@ +--- +id: storage-emptybucket +title: "emptyBucket()" +slug: storage-emptybucket +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Removes all objects inside a single bucket. + + + + + +```js +const { data, error } = await supabase + .storage + .emptyBucket('avatars') +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + id + + + required + + + string + +

      +
      + +The unique identifier of the bucket you would like to empty. + +
      + +
    • + +
    + + +## Notes + +- Policy permissions required: + - `buckets` permissions: `select` + - `objects` permissions: `select` and `delete` + + + + + + + + + + +## Examples + +### Empty bucket + + + + + + + +```js +const { data, error } = await supabase + .storage + .emptyBucket('avatars') +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/storage-from-createsignedurl.mdx b/apps/temp-docs/docs/reference/javascript/storage-from-createsignedurl.mdx new file mode 100644 index 00000000000..0be5d2db714 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/storage-from-createsignedurl.mdx @@ -0,0 +1,119 @@ +--- +id: storage-from-createsignedurl +title: "from.createSignedUrl()" +slug: storage-from-createsignedurl +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Create signed url to download file without requiring permissions. This URL can be valid for a set number of seconds. + + + + + +```js +const { signedURL, error } = await supabase + .storage + .from('avatars') + .createSignedUrl('folder/avatar1.png', 60) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + path + + + required + + + string + +

      +
      + +The file path to be downloaded, including the current file name. For example `folder/image.png`. + +
      + +
    • + + +
    • +

      + + expiresIn + + + required + + + number + +

      +
      + +The number of seconds until the signed URL expires. For example, `60` for a URL which is valid for one minute. + +
      + +
    • + +
    + + +## Notes + +- Policy permissions required: + - `buckets` permissions: none + - `objects` permissions: `select` + + + + + + + + + + +## Examples + +### Create Signed URL + + + + + + + +```js +const { signedURL, error } = await supabase + .storage + .from('avatars') + .createSignedUrl('folder/avatar1.png', 60) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/storage-from-download.mdx b/apps/temp-docs/docs/reference/javascript/storage-from-download.mdx new file mode 100644 index 00000000000..4222d61947c --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/storage-from-download.mdx @@ -0,0 +1,98 @@ +--- +id: storage-from-download +title: "from.download()" +slug: storage-from-download +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Downloads a file. + + + + + +```js +const { data, error } = await supabase + .storage + .from('avatars') + .download('folder/avatar1.png') +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + path + + + required + + + string + +

      +
      + +The file path to be downloaded, including the path and file name. For example `folder/image.png`. + +
      + +
    • + +
    + + +## Notes + +- Policy permissions required: + - `buckets` permissions: none + - `objects` permissions: `select` + + + + + + + + + + +## Examples + +### Download file + + + + + + + +```js +const { data, error } = await supabase + .storage + .from('avatars') + .download('folder/avatar1.png') +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/storage-from-getpublicurl.mdx b/apps/temp-docs/docs/reference/javascript/storage-from-getpublicurl.mdx new file mode 100644 index 00000000000..81820c8a65a --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/storage-from-getpublicurl.mdx @@ -0,0 +1,99 @@ +--- +id: storage-from-getpublicurl +title: "from.getPublicUrl()" +slug: storage-from-getpublicurl +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Retrieve URLs for assets in public buckets + + + + + +```js +const { publicURL, error } = supabase + .storage + .from('public-bucket') + .getPublicUrl('folder/avatar1.png') +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + path + + + required + + + string + +

      +
      + +The file path to be downloaded, including the path and file name. For example `folder/image.png`. + +
      + +
    • + +
    + + +## Notes + +- The bucket needs to be set to public, either via [updateBucket()](/docs/reference/javascript/storage-updatebucket) or by going to Storage on [app.supabase.io](https://app.supabase.io), clicking the overflow menu on a bucket and choosing "Make public" +- Policy permissions required: + - `buckets` permissions: none + - `objects` permissions: none + + + + + + + + + + +## Examples + +### Returns the URL for an asset in a public bucket + + + + + + + +```js +const { publicURL, error } = supabase + .storage + .from('public-bucket') + .getPublicUrl('folder/avatar1.png') +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/storage-from-list.mdx b/apps/temp-docs/docs/reference/javascript/storage-from-list.mdx new file mode 100644 index 00000000000..bda57dd68a5 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/storage-from-list.mdx @@ -0,0 +1,148 @@ +--- +id: storage-from-list +title: "from.list()" +slug: storage-from-list +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Lists all the files within a bucket. + + + + + +```js +const { data, error } = await supabase + .storage + .from('avatars') + .list('folder', { + limit: 100, + offset: 0, + sortBy: { column: 'name', order: 'asc' }, + }) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + path + + + optional + + + undefined | string + +

      +
      + +The folder path. + +
      + +
    • + + +
    • +

      + + options + + + optional + + + SearchOptions + +

      +
      + +Search options, including `limit`, `offset`, and `sortBy`. + +
      + +
    • + + +
    • +

      + + parameters + + + optional + + + FetchParameters + +

      +
      + +Fetch parameters, currently only supports `signal`, which is an AbortController's signal + +
      + +
    • + +
    + + +## Notes + +- Policy permissions required: + - `buckets` permissions: none + - `objects` permissions: `select` + + + + + + + + + + +## Examples + +### List files in a bucket + + + + + + + +```js +const { data, error } = await supabase + .storage + .from('avatars') + .list('folder', { + limit: 100, + offset: 0, + sortBy: { column: 'name', order: 'asc' }, + }) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/storage-from-move.mdx b/apps/temp-docs/docs/reference/javascript/storage-from-move.mdx new file mode 100644 index 00000000000..8c00b50ebeb --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/storage-from-move.mdx @@ -0,0 +1,119 @@ +--- +id: storage-from-move +title: "from.move()" +slug: storage-from-move +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Moves an existing file, optionally renaming it at the same time. + + + + + +```js +const { data, error } = await supabase + .storage + .from('avatars') + .move('public/avatar1.png', 'private/avatar2.png') +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + fromPath + + + required + + + string + +

      +
      + +The original file path, including the current file name. For example `folder/image.png`. + +
      + +
    • + + +
    • +

      + + toPath + + + required + + + string + +

      +
      + +The new file path, including the new file name. For example `folder/image-copy.png`. + +
      + +
    • + +
    + + +## Notes + +- Policy permissions required: + - `buckets` permissions: none + - `objects` permissions: `update` and `select` + + + + + + + + + + +## Examples + +### Move file + + + + + + + +```js +const { data, error } = await supabase + .storage + .from('avatars') + .move('public/avatar1.png', 'private/avatar2.png') +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/storage-from-remove.mdx b/apps/temp-docs/docs/reference/javascript/storage-from-remove.mdx new file mode 100644 index 00000000000..0df1e3bd7cf --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/storage-from-remove.mdx @@ -0,0 +1,98 @@ +--- +id: storage-from-remove +title: "from.remove()" +slug: storage-from-remove +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Deletes files within the same bucket + + + + + +```js +const { data, error } = await supabase + .storage + .from('avatars') + .remove(['folder/avatar1.png']) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + paths + + + required + + + object + +

      +
      + +An array of files to be deleted, including the path and file name. For example [`folder/image.png`]. + +
      + +
    • + +
    + + +## Notes + +- Policy permissions required: + - `buckets` permissions: none + - `objects` permissions: `delete` and `select` + + + + + + + + + + +## Examples + +### Delete file + + + + + + + +```js +const { data, error } = await supabase + .storage + .from('avatars') + .remove(['folder/avatar1.png']) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/storage-from-update.mdx b/apps/temp-docs/docs/reference/javascript/storage-from-update.mdx new file mode 100644 index 00000000000..11d4fb2be31 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/storage-from-update.mdx @@ -0,0 +1,179 @@ +--- +id: storage-from-update +title: "from.update()" +slug: storage-from-update +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Replaces an existing file at the specified path with a new one. + + + + + +```js +const avatarFile = event.target.files[0] +const { data, error } = await supabase + .storage + .from('avatars') + .update('public/avatar1.png', avatarFile, { + cacheControl: '3600', + upsert: false + }) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + path + + + required + + + string + +

      +
      + +The relative file path. Should be of the format `folder/subfolder/filename.png`. The bucket must already exist before attempting to upload. + +
      + +
    • + + +
    • +

      + + fileBody + + + required + + + ArrayBuffer | ArrayBufferView | Blob | Buffer | File | FormData | ReadableStream | ReadableStream | URLSearchParams | string + +

      +
      + +The body of the file to be stored in the bucket. + +
      + +
    • + + +
    • +

      + + fileOptions + + + optional + + + FileOptions + +

      +
      + +HTTP headers. +`cacheControl`: string, the `Cache-Control: max-age=` seconds value. +`contentType`: string, the `Content-Type` header value. Should be specified if using a `fileBody` that is neither `Blob` nor `File` nor `FormData`, otherwise will default to `text/plain;charset=UTF-8`. +`upsert`: boolean, whether to perform an upsert. + +
      + +
    • + +
    + + +## Notes + +- Policy permissions required: + - `buckets` permissions: none + - `objects` permissions: `update` and `select` +- For React Native, using either `Blob`, `File` or `FormData` does not work as intended. Update file using `ArrayBuffer` from base64 file data instead, see example below. + + + + + + + + + + +## Examples + +### Update file + + + + + + + +```js +const avatarFile = event.target.files[0] +const { data, error } = await supabase + .storage + .from('avatars') + .update('public/avatar1.png', avatarFile, { + cacheControl: '3600', + upsert: false + }) +``` + + + + + + +### Update file using `ArrayBuffer` from base64 file data + + + + + + + +```js +import {decode} from 'base64-arraybuffer' + +const { data, error } = await supabase + .storage + .from('avatars') + .update('public/avatar1.png', decode('base64FileData'), { + contentType: 'image/png' + }) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/storage-from-upload.mdx b/apps/temp-docs/docs/reference/javascript/storage-from-upload.mdx new file mode 100644 index 00000000000..bc5fe41832e --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/storage-from-upload.mdx @@ -0,0 +1,179 @@ +--- +id: storage-from-upload +title: "from.upload()" +slug: storage-from-upload +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Uploads a file to an existing bucket. + + + + + +```js +const avatarFile = event.target.files[0] +const { data, error } = await supabase + .storage + .from('avatars') + .upload('public/avatar1.png', avatarFile, { + cacheControl: '3600', + upsert: false + }) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + path + + + required + + + string + +

      +
      + +The relative file path. Should be of the format `folder/subfolder/filename.png`. The bucket must already exist before attempting to upload. + +
      + +
    • + + +
    • +

      + + fileBody + + + required + + + ArrayBuffer | ArrayBufferView | Blob | Buffer | File | FormData | ReadableStream | ReadableStream | URLSearchParams | string + +

      +
      + +The body of the file to be stored in the bucket. + +
      + +
    • + + +
    • +

      + + fileOptions + + + optional + + + FileOptions + +

      +
      + +HTTP headers. +`cacheControl`: string, the `Cache-Control: max-age=` seconds value. +`contentType`: string, the `Content-Type` header value. Should be specified if using a `fileBody` that is neither `Blob` nor `File` nor `FormData`, otherwise will default to `text/plain;charset=UTF-8`. +`upsert`: boolean, whether to perform an upsert. + +
      + +
    • + +
    + + +## Notes + +- Policy permissions required: + - `buckets` permissions: none + - `objects` permissions: `insert` +- For React Native, using either `Blob`, `File` or `FormData` does not work as intended. Upload file using `ArrayBuffer` from base64 file data instead, see example below. + + + + + + + + + + +## Examples + +### Upload file + + + + + + + +```js +const avatarFile = event.target.files[0] +const { data, error } = await supabase + .storage + .from('avatars') + .upload('public/avatar1.png', avatarFile, { + cacheControl: '3600', + upsert: false + }) +``` + + + + + + +### Upload file using `ArrayBuffer` from base64 file data + + + + + + + +```js +import {decode} from 'base64-arraybuffer' + +const { data, error } = await supabase + .storage + .from('avatars') + .upload('public/avatar1.png', decode('base64FileData'), { + contentType: 'image/png' + }) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/storage-getbucket.mdx b/apps/temp-docs/docs/reference/javascript/storage-getbucket.mdx new file mode 100644 index 00000000000..96da99dac06 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/storage-getbucket.mdx @@ -0,0 +1,96 @@ +--- +id: storage-getbucket +title: "getBucket()" +slug: storage-getbucket +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Retrieves the details of an existing Storage bucket. + + + + + +```js +const { data, error } = await supabase + .storage + .getBucket('avatars') +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + id + + + required + + + string + +

      +
      + +The unique identifier of the bucket you would like to retrieve. + +
      + +
    • + +
    + + +## Notes + +- Policy permissions required: + - `buckets` permissions: `select` + - `objects` permissions: none + + + + + + + + + + +## Examples + +### Get bucket + + + + + + + +```js +const { data, error } = await supabase + .storage + .getBucket('avatars') +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/storage-listbuckets.mdx b/apps/temp-docs/docs/reference/javascript/storage-listbuckets.mdx new file mode 100644 index 00000000000..f78bb44a61e --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/storage-listbuckets.mdx @@ -0,0 +1,72 @@ +--- +id: storage-listbuckets +title: "listBuckets()" +slug: storage-listbuckets +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Retrieves the details of all Storage buckets within an existing product. + + + + + +```js +const { data, error } = await supabase + .storage + .listBuckets() +``` + + + + + + + + + + +## Notes + +- Policy permissions required: + - `buckets` permissions: `select` + - `objects` permissions: none + + + + + + + + + + +## Examples + +### List buckets + + + + + + + +```js +const { data, error } = await supabase + .storage + .listBuckets() +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/storage-updatebucket.mdx b/apps/temp-docs/docs/reference/javascript/storage-updatebucket.mdx new file mode 100644 index 00000000000..903aa7c4415 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/storage-updatebucket.mdx @@ -0,0 +1,142 @@ +--- +id: storage-updatebucket +title: "updateBucket()" +slug: storage-updatebucket +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Updates a new Storage bucket + + + + + +```js +const { data, error } = await supabase + .storage + .updateBucket('avatars', { public: false }) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + id + + + required + + + string + +

      +
      + +A unique identifier for the bucket you are creating. + +
      + +
    • + + +
    • +

      + + options + + + required + + + object + +

      +
      + +No description provided. + +
      + +
        +
        Properties
        + +
      • +

        + + public + + + required + + + boolean + +

        +
        + +No description provided. + +
        + +
      • + +
      + +
    • + +
    + + +## Notes + +- Policy permissions required: + - `buckets` permissions: `update` + - `objects` permissions: none + + + + + + + + + + +## Examples + +### Update bucket + + + + + + + +```js +const { data, error } = await supabase + .storage + .updateBucket('avatars', { public: false }) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/subscribe.mdx b/apps/temp-docs/docs/reference/javascript/subscribe.mdx new file mode 100644 index 00000000000..7d0139bae12 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/subscribe.mdx @@ -0,0 +1,281 @@ +--- +id: subscribe +title: "on().subscribe()" +slug: subscribe +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Subscribe to realtime changes in your databse. + + + + + +```js +const mySubscription = supabase + .from('*') + .on('*', payload => { + console.log('Change received!', payload) + }) + .subscribe() +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + event + + + required + + + SupabaseEventTypes + +

      +
      + +The database event which you would like to receive updates for, or you can use the special wildcard `*` to listen to all changes. + +
      + +
    • + + +
    • +

      + + callback + + + required + + + object + +

      +
      + +A callback that will handle the payload that is sent whenever your database changes. + +
      + +
    • + +
    + + +## Notes + +- Realtime is disabled by default for new Projects for better database performance and security. You can turn it on by [managing replication](/docs/guides/api#managing-realtime). +- If you want to receive the "previous" data for updates and deletes, you will need to set `REPLICA IDENTITY` to `FULL`, like this: `ALTER TABLE your_table REPLICA IDENTITY FULL;` + + + + + + + + + + +## Examples + +### Listen to all database changes + + + + + + + +```js +const mySubscription = supabase + .from('*') + .on('*', payload => { + console.log('Change received!', payload) + }) + .subscribe() +``` + + + + + + +### Listening to a specific table + + + + + + + +```js +const mySubscription = supabase + .from('countries') + .on('*', payload => { + console.log('Change received!', payload) + }) + .subscribe() +``` + + + + + + +### Listening to inserts + + + + + + + +```js +const mySubscription = supabase + .from('countries') + .on('INSERT', payload => { + console.log('Change received!', payload) + }) + .subscribe() +``` + + + + + + +### Listening to updates + +By default, Supabase will send only the updated record. If you want to receive the previous values as well you can +enable full replication for the table you are listening too: + +```sql +alter table "your_table" replica identity full; +``` + + + + + + +```js +const mySubscription = supabase + .from('countries') + .on('UPDATE', payload => { + console.log('Change received!', payload) + }) + .subscribe() +``` + + + + + + +### Listening to deletes + +By default, Supabase does not send deleted records. If you want to receive the deleted record you can +enable full replication for the table you are listening too: + +```sql +alter table "your_table" replica identity full; +``` + + + + + + +```js +const mySubscription = supabase + .from('countries') + .on('DELETE', payload => { + console.log('Change received!', payload) + }) + .subscribe() +``` + + + + + + +### Listening to multiple events + +You can chain listeners if you want to listen to multiple events for each table. + + + + + +```js +const mySubscription = supabase + .from('countries') + .on('INSERT', handleRecordInserted) + .on('DELETE', handleRecordDeleted) + .subscribe() +``` + + + + + + +### Listening to row level changes + +You can listen to individual rows using the format `{table}:{col}=eq.{val}` - where `{col}` is the column name, and `{val}` is the value which you want to match. + + + + + +```js +const mySubscription = supabase + .from('countries:id=eq.200') + .on('UPDATE', handleRecordUpdated) + .subscribe() +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/supabase-client.mdx b/apps/temp-docs/docs/reference/javascript/supabase-client.mdx new file mode 100644 index 00000000000..7701a27a439 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/supabase-client.mdx @@ -0,0 +1,109 @@ +--- +id: index +title: "Supabase Client" +slug: supabase-client +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Our approach for client libraries is modular. Each sub-library is a standalone implementation for a single external system. This is one of the ways we support existing tools. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    LanguageClientFeature-Clients (bundled in Supabase client)
    SupabasePostgRESTGoTrueRealtimeStorage
    ⚡️ Official ⚡️
    JavaScript (TypeScript)supabase-jspostgrest-jsgotrue-jsrealtime-jsstorage-js
    💚 Community 💚
    C#supabase-csharppostgrest-csharpgotrue-csharprealtime-csharp-
    Dart (Flutter)supabase-dartpostgrest-dartgotrue-langrealtime-dartstorage-dart
    Go-postgrest-go---
    Java--gotrue-java--
    Kotlin-postgrest-ktgotrue-kt--
    Pythonsupabase-pypostgrest-pygotrue-pyrealtime-py-
    Rubysupabase-rbpostgrest-rb---
    Rust-postgrest-rs---
    Swiftsupabase-swiftpostgrest-swiftgotrue-swiftrealtime-swiftstorage-swift
    \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/textsearch.mdx b/apps/temp-docs/docs/reference/javascript/textsearch.mdx new file mode 100644 index 00000000000..6354b2f39a6 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/textsearch.mdx @@ -0,0 +1,234 @@ +--- +id: textsearch +title: ".textSearch()" +slug: textsearch +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Finds all rows whose tsvector value on the stated `column` matches +to_tsquery(`query`). + + + +## Parameters + + +
      + +
    • +

      + + column + + + required + + + object + +

      +
      + +The column to filter on. + +
      + +
    • + + +
    • +

      + + query + + + required + + + string + +

      +
      + +The Postgres tsquery string to filter with. + +
      + +
    • + + +
    • +

      + + __namedParameters + + + required + + + object + +

      +
      + +No description provided. + +
      + +
        +
        Properties
        + +
      • +

        + + config + + + required + + + undefined | string + +

        +
        + +The text search configuration to use. + +
        + +
      • + +
      + +
    • + +
    + + + + + + + + + + + + + + +## Examples + +### Text search + + + + + + + +```js +const { data, error } = await supabase + .from('quotes') + .select('catchphrase') + .textSearch('catchphrase', `'fat' & 'cat'`, { + config: 'english' + }) +``` + + + + + + +### Basic normalization + +Uses PostgreSQL's `plainto_tsquery` function. + + + + + +```js +const { data, error } = await supabase + .from('quotes') + .select('catchphrase') + .textSearch('catchphrase', `'fat' & 'cat'`, { + type: 'plain', + config: 'english' + }) +``` + + + + + + +### Full normalization + +Uses PostgreSQL's `phraseto_tsquery` function. + + + + + +```js +const { data, error } = await supabase + .from('quotes') + .select('catchphrase') + .textSearch('catchphrase', `'fat' & 'cat'`, { + type: 'phrase', + config: 'english' + }) +``` + + + + + + +### Full normalization + +Uses PostgreSQL's `websearch_to_tsquery` function. +This function will never raise syntax errors, which makes it possible to use raw user-supplied input for search, and can be used +with advanced operators. + +- `unquoted text`: text not inside quote marks will be converted to terms separated by & operators, as if processed by plainto_tsquery. +- `"quoted text"`: text inside quote marks will be converted to terms separated by <-> operators, as if processed by phraseto_tsquery. +- `OR`: the word “or” will be converted to the | operator. +- `-`: a dash will be converted to the ! operator. + + + + + + +```js +const { data, error } = await supabase + .from('quotes') + .select('catchphrase') + .textSearch('catchphrase', `'fat or cat'`, { + type: 'websearch', + config: 'english' + }) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/update.mdx b/apps/temp-docs/docs/reference/javascript/update.mdx new file mode 100644 index 00000000000..dca58efa64d --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/update.mdx @@ -0,0 +1,195 @@ +--- +id: update +title: "Modify data: update()" +slug: update +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Performs an UPDATE on the table. + + + + + +```js +const { data, error } = await supabase + .from('cities') + .update({ name: 'Middle Earth' }) + .match({ name: 'Auckland' }) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + values + + + required + + + Partial + +

      +
      + +The values to update. + +
      + +
    • + + +
    • +

      + + __namedParameters + + + required + + + object + +

      +
      + +No description provided. + +
      + +
        +
        Properties
        + +
      • +

        + + returning + + + required + + + minimal | representation + +

        +
        + +By default the updated record is returned. Set this to 'minimal' if you don't need this value. + +
        + +
      • + + +
      • +

        + + count + + + required + + + null | exact | planned | estimated + +

        +
        + +Count algorithm to use to count rows in a table. + +
        + +
      • + +
      + +
    • + +
    + + +## Notes + +- `update()` should always be combined with [Filters](/docs/reference/javascript/using-filters) to target the item(s) you wish to update. + + + + + + + + + + +## Examples + +### Updating your data + + + + + + + +```js +const { data, error } = await supabase + .from('cities') + .update({ name: 'Middle Earth' }) + .match({ name: 'Auckland' }) +``` + + + + + + +### Updating JSON data + +Postgres offers a +[number of operators](https://www.postgresql.org/docs/current/functions-json.html) +for working with JSON data. Right now it is only possible to update an entire JSON document, +but we are [working on ideas](https://github.com/PostgREST/postgrest/issues/465) for updating individual keys. + + + + + + +```js +const { data, error } = await supabase + .from('users') + .update(` + address: { + street: 'Melrose Place', + postcode: 90210 + } + `) + .eq('address->postcode', 90210) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/upsert.mdx b/apps/temp-docs/docs/reference/javascript/upsert.mdx new file mode 100644 index 00000000000..a0b1edc28ae --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/upsert.mdx @@ -0,0 +1,281 @@ +--- +id: upsert +title: "Upsert data: upsert()" +slug: upsert +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Performs an UPSERT into the table. + + + + + +```js +const { data, error } = await supabase + .from('messages') + .upsert({ id: 3, message: 'foo', username: 'supabot' }) +``` + + + + + + +## Parameters + + +
      + +
    • +

      + + values + + + required + + + Partial | array + +

      +
      + +The values to insert. + +
      + +
    • + + +
    • +

      + + __namedParameters + + + required + + + object + +

      +
      + +No description provided. + +
      + +
        +
        Properties
        + +
      • +

        + + returning + + + required + + + minimal | representation + +

        +
        + +By default the new record is returned. Set this to 'minimal' if you don't need this value. + +
        + +
      • + + +
      • +

        + + onConflict + + + required + + + undefined | string + +

        +
        + +By specifying the `on_conflict` query parameter, you can make UPSERT work on a column(s) that has a UNIQUE constraint. + +
        + +
      • + + +
      • +

        + + ignoreDuplicates + + + required + + + boolean + +

        +
        + +Specifies if duplicate rows should be ignored and not inserted. + +
        + +
      • + + +
      • +

        + + count + + + required + + + null | exact | planned | estimated + +

        +
        + +Count algorithm to use to count rows in a table. + +
        + +
      • + +
      + +
    • + +
    + + +## Notes + +- Primary keys should be included in the data payload in order for an update to work correctly. +- Primary keys must be natural, not surrogate. There are however, [workarounds](https://github.com/PostgREST/postgrest/issues/1118) for surrogate primary keys. + + + + + + + + + + +## Examples + +### Upsert your data + + + + + + + +```js +const { data, error } = await supabase + .from('messages') + .upsert({ id: 3, message: 'foo', username: 'supabot' }) +``` + + + + + + +### Bulk Upsert your data + + + + + + + +```js +const { data, error } = await supabase + .from('messages') + .upsert([ + { id: 3, message: 'foo', username: 'supabot' }, + { id: 4, message: 'bar', username: 'supabot' } + ]) +``` + + + + + + +### Upserting into tables with constraints + +Running the following will cause supabase to upsert data into the `users` table. +If the username 'supabot' already exists, the `onConflict` argument tells supabase to overwrite that row +based on the column passed into `onConflict`. + + + + + + +```js +const { data, error } = await supabase + .from('users') + .upsert({ username: 'supabot' }, { onConflict: 'username' }) +``` + + + + + + +### Return the exact number of rows + + + + + + + +```js +const { data, error, count } = await supabase + .from('users') + .upsert({ + id: 3, message: 'foo', + username: 'supabot' + }, { + count: 'exact' + }) +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/using-filters.mdx b/apps/temp-docs/docs/reference/javascript/using-filters.mdx new file mode 100644 index 00000000000..b4ce9a4811e --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/using-filters.mdx @@ -0,0 +1,61 @@ +--- +id: using-filters +title: "Using Filters" +slug: using-filters +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Filters can be used on `select()`, `update()`, and `delete()` queries. + +If a Postgres function returns a table response, you can also apply filters. + +### Applying Filters + +You must apply your filters to the end of your query. For example: + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .eq('name', 'The Shire') // Correct + +const { data, error } = await supabase + .from('cities') + .eq('name', 'The Shire') // Incorrect + .select('name, country_id') +``` + +### Chaining + +Filters can be chained together to produce advanced queries. For example: + +```js +const { data, error } = await supabase + .from('cities') + .select('name, country_id') + .gte('population', 1000) + .lt('population', 10000) +``` + +### Conditional Chaining + +Filters can be built up one step at a time and then executed. For example: + +```js +const filterByName = null +const filterPopLow = 1000 +const filterPopHigh = 10000 + +let query = supabase + .from('cities') + .select('name, country_id') + +if (filterByName) { query = query.eq('name', filterByName) } +if (filterPopLow) { query = query.gte('population', filterPopLow) } +if (filterPopHigh) { query = query.lt('population', filterPopHigh) } + +const { data, error } = await query +``` \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/javascript/using-modifiers.mdx b/apps/temp-docs/docs/reference/javascript/using-modifiers.mdx new file mode 100644 index 00000000000..cad96411fd3 --- /dev/null +++ b/apps/temp-docs/docs/reference/javascript/using-modifiers.mdx @@ -0,0 +1,13 @@ +--- +id: using-modifiers +title: "Using Modifiers" +slug: using-modifiers +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Modifiers can be used on `select()` queries. + +If a Postgres function returns a table response, you can also apply modifiers to the `rpc()` function. \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/postgres/changing-timezones.mdx b/apps/temp-docs/docs/reference/postgres/changing-timezones.mdx new file mode 100644 index 00000000000..d05e32afc8b --- /dev/null +++ b/apps/temp-docs/docs/reference/postgres/changing-timezones.mdx @@ -0,0 +1,119 @@ +--- +id: changing-timezones +title: "Changing Timezones" +slug: changing-timezones +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/postgres.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Data types. + + + + + + +```sql +alter database postgres +set timezone to 'America/New_York'; +``` + + + + + + + + + + +## Notes + +- View a full list of timezones on [Wikipedia](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones). + + + + + + + + + + +## Examples + +### Change timezone + + + + + + + +```sql +alter database postgres +set timezone to 'America/New_York'; +``` + + + + + + +### Full list of timezones + +Get a full list of timezones supported by your database. This will return the following columns: + +- `name`: Time zone name +- `abbrev`: Time zone abbreviation +- `utc_offset`: Offset from UTC (positive means east of Greenwich) +- `is_dst`: True if currently observing daylight savings + + + + + + +```sql +select name, abbrev, utc_offset, is_dst +from pg_timezone_names() +order by name; +``` + + + + + + +### Search for a specific timezone + +Use `ilike` (case insensitive search) to find specific timezones. + + + + + +```sql +select * +from pg_timezone_names() +where name ilike '%york%'; +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/postgres/columns.mdx b/apps/temp-docs/docs/reference/postgres/columns.mdx new file mode 100644 index 00000000000..0ccaa830381 --- /dev/null +++ b/apps/temp-docs/docs/reference/postgres/columns.mdx @@ -0,0 +1,95 @@ +--- +id: columns +title: "Columns" +slug: columns +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/postgres.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Creating columns. + + + + + + +```sql +create table table_name ( + id integer primary key, + data jsonb, + name text +); +``` + + + + + + + + + + + + + + + + + + + + + + +## Examples + +### During table creation + + + + + + + +```sql +create table table_name ( + id integer primary key, + data jsonb, + name text +); +``` + + + + + + +### Create column + + + + + + + +```sql +alter table new_table +add new_column text; +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/postgres/connection-strings.mdx b/apps/temp-docs/docs/reference/postgres/connection-strings.mdx new file mode 100644 index 00000000000..12e4f919c9c --- /dev/null +++ b/apps/temp-docs/docs/reference/postgres/connection-strings.mdx @@ -0,0 +1,135 @@ +--- +id: connection-strings +title: "Connection Strings" +slug: connection-strings +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/postgres.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +There are various ways to connect to your database, depending on the configuration of your Postgres instance and the tool which you are connecting with. + + + + + + +```bash +postgres://postgres:postgres@localhost:5432/postgres +# or +postgresql://postgres:postgres@localhost:5432/postgres +``` + + + + + + + + + + +## Notes + +- [Official Documentation](https://www.postgresql.org/docs/current/libpq-connect.html). +- Avoid using special characters usernames and passwords. If you use special characters in a connection URL, you'll need to URL encode any special characters. + + + + + + + + + + +## Examples + +### Basic connection string + +If you're using a default setup, your postgres connection string will likely be in the format: + +`postgres://{user}:{password}@{host}:{port}/{database_name}` + + + + + + +```bash +postgres://postgres:postgres@localhost:5432/postgres +# or +postgresql://postgres:postgres@localhost:5432/postgres +``` + + + + + + +### JDBC + +See full [documentation](http://jdbc.postgresql.org/documentation/head/connect.html). + + + + + +```bash +jdbc:postgresql://{host}:{port}/{database_name} +``` + + + + + + +### ADO.NET + +See full [documentation](http://npgsql.projects.postgresql.org/docs/manual/UserManual.html). + + + + + +```bash +Server=host;Port=5432;User Id=username;Password=secret;Database=database_name; +``` + + + + + + +### PHP + +See full [documentation](http://php.net/manual/en/book.pgsql.php). + + + + + +```bash +host=hostname port=5432 dbname=databasename user=username password=secret +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/postgres/database-passwords.mdx b/apps/temp-docs/docs/reference/postgres/database-passwords.mdx new file mode 100644 index 00000000000..9f58234b1a1 --- /dev/null +++ b/apps/temp-docs/docs/reference/postgres/database-passwords.mdx @@ -0,0 +1,53 @@ +--- +id: database-passwords +title: "Database Passwords" +slug: database-passwords +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/postgres.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Manage the passwords of your database users using any super user. + + + + + + + + + + + + + + + + + + + + +## Examples + +### Password reset + + + + + + + +```sql +alter user postgres +with password 'new_password'; +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/postgres/database-users.mdx b/apps/temp-docs/docs/reference/postgres/database-users.mdx new file mode 100644 index 00000000000..8ccca2ce94a --- /dev/null +++ b/apps/temp-docs/docs/reference/postgres/database-users.mdx @@ -0,0 +1,53 @@ +--- +id: database-users +title: "Database Users" +slug: database-users +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/postgres.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Users and Roles are almost interchangeable. + + + + + + + + + + + + + + + + + + + + +## Examples + +### Create New User + + + + + + + +```sql +create user new_user +with password 'hello'; +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/postgres/index.mdx b/apps/temp-docs/docs/reference/postgres/index.mdx new file mode 100644 index 00000000000..b6641472785 --- /dev/null +++ b/apps/temp-docs/docs/reference/postgres/index.mdx @@ -0,0 +1,15 @@ +--- +id: index +title: "Getting started" +slug: getting-started +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/postgres.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + + +PostgreSQL, also known as Postgres, is a free and open-source relational +database management system emphasizing extensibility and SQL compliance. +It was originally named POSTGRES, referring to its origins as a successor +to the Ingres database developed at the University of California, Berkeley. \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/postgres/publications.mdx b/apps/temp-docs/docs/reference/postgres/publications.mdx new file mode 100644 index 00000000000..87559a38e34 --- /dev/null +++ b/apps/temp-docs/docs/reference/postgres/publications.mdx @@ -0,0 +1,210 @@ +--- +id: publications +title: "Publications" +slug: publications +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/postgres.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Publications are a way of grouping changes generated from a table or a group of tables. +These changes can then be sent to other systems (usually another Postgres database). + + + + + + + + + + + + + + + + + + + + +## Examples + +### Create a Publication + +This publication will contain all changes to all tables. + + + + + + +```sql +create publication publication_name +for all tables; +``` + + + + + + +### Create a Publication which listens to individual tables + + + + + + + +```sql +create publication publication_name +for table table_one, table_two; +``` + + + + + + +### Add tables to an existing publication + + + + + + + +```sql +alter publication publication_name +add table table_name; +``` + + + + + + +### Listens to inserts only + + + + + + + +```sql +create publication publication_name +for all tables +with (publish = 'insert'); +``` + + + + + + +### Listens to updates only + + + + + + + +```sql +create publication publication_name +for all tables +with (publish = 'update'); +``` + + + + + + +### Listens to deletions only + + + + + + + +```sql +create publication publication_name +for all tables +with (publish = 'delete'); +``` + + + + + + +### Remove a Publication + + + + + + + +```sql +drop publication if exists publication_name; +``` + + + + + + +### Recreate a Publication + +If you are planning to re-create a publication, it's best to do it in a transaction to ensure the operation succeeds. + + + + + + +```sql +begin; + -- remove the realtime publication + drop publication if exists publication_name; + + -- re-create the publication but don't enable it for any tables + create publication publication_name; +commit; +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/postgres/schemas.mdx b/apps/temp-docs/docs/reference/postgres/schemas.mdx new file mode 100644 index 00000000000..ad4fbf6d9ef --- /dev/null +++ b/apps/temp-docs/docs/reference/postgres/schemas.mdx @@ -0,0 +1,114 @@ +--- +id: schemas +title: "Schemas" +slug: schemas +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/postgres.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Schemas are like "folders". They help to keep your database organized. + +Schemas are particularly useful for security. You can set different permissions on each schema. +For example, you might want to use a `public` schema for user-facing data, and an `auth` schema for all logins and secured data. + + + + + + +```sql +create schema schema_name; +``` + + + + + + + + + + +## Notes + +- Schemas contain [tables](/docs/reference/postgres/tables), columns, triggers, functions, etc. +- Postgres comes with a `public` schema set up by default. +- It is best practice to use lowercase and underscores when naming schemas. For example: `schema_name`, not `Schema Name`. + + + + + + + + + + +## Examples + +### Creating a schema + + + + + + + +```sql +create schema schema_name; +``` + + + + + + +### Removing a schema + + + + + + + +```sql +drop schema if exists schema_name; +``` + + + + + + +### Using special characters + +Although it's not recommended, you can use uppercase and spaces when naming your schema by wrapping the name with double-quotes. +As a result, you will always need to use double-quotes when referencing your schema. + + + + + + +```sql +create schema "Schema Name"; +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/docs/reference/postgres/tables.mdx b/apps/temp-docs/docs/reference/postgres/tables.mdx new file mode 100644 index 00000000000..05df802a961 --- /dev/null +++ b/apps/temp-docs/docs/reference/postgres/tables.mdx @@ -0,0 +1,161 @@ +--- +id: tables +title: "Tables" +slug: tables +custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/postgres.yml +--- + +import Tabs from '@theme/Tabs'; +import TabsPanel from '@theme/TabsPanel'; + +Tables are similar to excel spreadsheets. They contain columns & rows of data. There are a few key differences from a spreadsheet however: + +- Every column is a strict type of data. When you set up a column, you must define what "data type" it is. +- Tables can be joined together through relationships. For example you can have a "users" table, which is joined to a "teams" table. + + + + + + +```sql +create table table_name ( + id integer primary key, + data jsonb, + name text +); + +# with schema +create table schema_name.table_name ( + id integer primary key, + data jsonb, + name text +); +``` + + + + + + + + + + +## Notes + +- Tables contain columns, rows, triggers, comments, +- It is best practice to use lowercase and underscores when naming tables. For example: `table_name`, not `Table Name`. +- Tables belong to [schemas](/docs/reference/postgres/schemas). If you don't explicitly pass the schema, Postgres will assume that you want to create the table in the `public` schema. + + + + + + + + + + +## Examples + +### Create table + + + + + + + +```sql +create table table_name ( + id integer primary key, + data jsonb, + name text +); + +# with schema +create table schema_name.table_name ( + id integer primary key, + data jsonb, + name text +); +``` + + + + + + +### Primary keys using multiple columns + + + + + + + +```sql +create table table_name ( + column_1 data_type, + column_2 data_type + -- Constraints: + primary key (column_1, column_2) +); +``` + + + + + + +### Multiple foreign keys to the same table + + + + + + + +```sql +alter table table_name + add constraint constraint_name_1 foreign key (column_1) references foreign_table(id), + add constraint constraint_name_2 foreign key (column_2) references foreign_table(id); +``` + + + + + + +### Delete a table + + + + + + + +```sql +delete table if exists table_name; +``` + + + + + \ No newline at end of file diff --git a/apps/temp-docs/lib/docs.ts b/apps/temp-docs/lib/docs.ts new file mode 100644 index 00000000000..3af7d930c39 --- /dev/null +++ b/apps/temp-docs/lib/docs.ts @@ -0,0 +1,45 @@ +import fs from 'fs' +import { join } from 'path' +import matter from 'gray-matter' + +const docsDirectory = process.cwd() + +export function getDocsBySlug(slug: string) { + const realSlug = slug.replace(/\.mdx$/, '') + let fullPath = join(docsDirectory, `${realSlug}.mdx`) + + if (!fs.existsSync(fullPath)) { + console.log(`\nfile ${fullPath} not found, redirect to 404\n`) + fullPath = join(docsDirectory, 'docs/404.mdx') + } + + const fileContents = fs.readFileSync(fullPath, 'utf8') + + const { data, content } = matter(fileContents) + + return { slug: realSlug, meta: data, content } +} + +export function getAllDocs() { + const slugs = walk('docs') + const docs = slugs.map((slug) => getDocsBySlug(slug)) + + return docs +} + +function walk(dir: string) { + let results: string[] = [] + const list = fs.readdirSync(dir) + list.forEach(function (file) { + file = dir + '/' + file + const stat = fs.statSync(file) + if (stat && stat.isDirectory()) { + /* Recurse into a subdirectory */ + results = results.concat(walk(file)) + } else { + /* Is a file */ + results.push(file) + } + }) + return results +} diff --git a/apps/temp-docs/package.json b/apps/temp-docs/package.json index a3b959bf083..2002b8360a5 100644 --- a/apps/temp-docs/package.json +++ b/apps/temp-docs/package.json @@ -9,10 +9,25 @@ "lint": "next lint" }, "dependencies": { + "@mdx-js/loader": "^1.6.22", + "@mdx-js/react": "^1.6.22", + "@next/mdx": "^12.0.4", + "@supabase/ui": "^0.36.2", + "@tailwindcss/typography": "^0.4.1", + "common": "*", + "gray-matter": "^4.0.3", + "markdown-toc": "^1.2.0", "next": "12.1.0", + "next-mdx-remote": "^3.0.8", + "next-themes": "0.0.15", "react": "17.0.2", + "react-copy-to-clipboard": "^5.0.2", "react-dom": "17.0.2", - "common": "*" + "react-syntax-highlighter": "^15.3.1", + "remark": "^14.0.2", + "remark-html": "^15.0.0", + "remark-mdx": "^2.0.0-rc.2", + "remark-prism": "^1.3.6" }, "devDependencies": { "@types/node": "^17.0.12", diff --git a/apps/temp-docs/pages/[...slug].tsx b/apps/temp-docs/pages/[...slug].tsx new file mode 100644 index 00000000000..719969cfa28 --- /dev/null +++ b/apps/temp-docs/pages/[...slug].tsx @@ -0,0 +1,83 @@ +import { ReactElement } from 'react' +import { getAllDocs, getDocsBySlug } from '../lib/docs' +import Layout from '../components/layouts/Layout' +import { serialize } from 'next-mdx-remote/serialize' +import { MDXRemote } from 'next-mdx-remote' +import { MDXProvider } from '@mdx-js/react' +import components from '../components/index' +import menuItems from '../components/nav/menu-items.json' +import { useRouter } from 'next/router' + +// table of contents extractor +const toc = require('markdown-toc') + +export default function Doc({ + meta, + content, + toc, +}: { + meta: { title: string; description: string } + content: ReactElement + toc: any +}) { + const { asPath } = useRouter() + let page + switch (asPath) { + case '/guides': + case '/guides/local-development': + case /\/guides\/[a-zA-Z]*\/[a-zA-Z\-]*/.test(asPath) && asPath: + page = 'Guides' + break + case asPath.includes('/reference') && asPath: + page = 'Reference' + break + default: + page = 'Docs' + break + } + + return ( + + + + + + ) +} + +export async function getStaticProps({ params }: { params: { slug: string[] } }) { + let slug + + if (params.slug.length > 1) { + slug = `docs/${params.slug.join('/')}` + } else { + slug = `docs/${params.slug[0]}` + } + + let doc = getDocsBySlug(slug) + + const content = await serialize(doc.content || '') + + return { + props: { + ...doc, + content, + toc: toc(doc.content, { maxdepth: 2 }), + }, + } +} + +export function getStaticPaths() { + let docs = getAllDocs() + + return { + paths: docs.map(() => { + return { + params: { + slug: docs.map((d) => d.slug), + }, + } + }), + fallback: 'blocking', + } +} diff --git a/apps/temp-docs/pages/_app.tsx b/apps/temp-docs/pages/_app.tsx new file mode 100644 index 00000000000..c320ed68e31 --- /dev/null +++ b/apps/temp-docs/pages/_app.tsx @@ -0,0 +1,14 @@ +import React from 'react' +import type { AppProps } from 'next/app' +import { ThemeProvider } from '../components/Providers' +import '../styles/tailwind.css' + +function MyApp({ Component, pageProps }: AppProps) { + return ( + + + + ) +} + +export default MyApp diff --git a/apps/temp-docs/pages/_document.tsx b/apps/temp-docs/pages/_document.tsx new file mode 100644 index 00000000000..d6c12b699ae --- /dev/null +++ b/apps/temp-docs/pages/_document.tsx @@ -0,0 +1,15 @@ +import Document, { Html, Head, Main, NextScript } from 'next/document' + +export default class MyDocument extends Document { + render() { + return ( + + + +
    + + + + ) + } +} diff --git a/apps/temp-docs/pages/index.tsx b/apps/temp-docs/pages/index.tsx new file mode 100644 index 00000000000..6fe909bff2d --- /dev/null +++ b/apps/temp-docs/pages/index.tsx @@ -0,0 +1,36 @@ +import { getDocsBySlug } from '../lib/docs' +import Layout from '../components/layouts/Layout' +import { serialize } from 'next-mdx-remote/serialize' +import { MDXRemote } from 'next-mdx-remote' +import { MDXProvider } from '@mdx-js/react' +import components from '../components' +import menuItems from '../components/nav/menu-items.json' + +export default function Home({ + meta, + content, +}: { + meta: { title: string; description: string } + content: any +}) { + return ( + + + + + + ) +} + +export async function getStaticProps() { + const doc = getDocsBySlug('docs/introduction') + + const content = await serialize(doc.content || '') + + return { + props: { + ...doc, + content, + }, + } +} diff --git a/apps/temp-docs/public/favicon.ico b/apps/temp-docs/public/favicon.ico new file mode 100644 index 00000000000..5c4d1dcc5cf Binary files /dev/null and b/apps/temp-docs/public/favicon.ico differ diff --git a/apps/temp-docs/public/favicon.png b/apps/temp-docs/public/favicon.png new file mode 100644 index 00000000000..e217fec5c6b Binary files /dev/null and b/apps/temp-docs/public/favicon.png differ diff --git a/apps/temp-docs/public/img/add-contributor.png b/apps/temp-docs/public/img/add-contributor.png new file mode 100644 index 00000000000..a366dc84411 Binary files /dev/null and b/apps/temp-docs/public/img/add-contributor.png differ diff --git a/apps/temp-docs/public/img/auth-5-1.png b/apps/temp-docs/public/img/auth-5-1.png new file mode 100644 index 00000000000..e90534de2d6 Binary files /dev/null and b/apps/temp-docs/public/img/auth-5-1.png differ diff --git a/apps/temp-docs/public/img/auth-5-2.png b/apps/temp-docs/public/img/auth-5-2.png new file mode 100644 index 00000000000..125dbb44a2c Binary files /dev/null and b/apps/temp-docs/public/img/auth-5-2.png differ diff --git a/apps/temp-docs/public/img/auth-5-3.png b/apps/temp-docs/public/img/auth-5-3.png new file mode 100644 index 00000000000..143e520df0d Binary files /dev/null and b/apps/temp-docs/public/img/auth-5-3.png differ diff --git a/apps/temp-docs/public/img/auth-5-4.png b/apps/temp-docs/public/img/auth-5-4.png new file mode 100644 index 00000000000..767dadd0c78 Binary files /dev/null and b/apps/temp-docs/public/img/auth-5-4.png differ diff --git a/apps/temp-docs/public/img/auth-5-5.png b/apps/temp-docs/public/img/auth-5-5.png new file mode 100644 index 00000000000..feb332dbe6b Binary files /dev/null and b/apps/temp-docs/public/img/auth-5-5.png differ diff --git a/apps/temp-docs/public/img/auth-5-6.png b/apps/temp-docs/public/img/auth-5-6.png new file mode 100644 index 00000000000..c90310a4c06 Binary files /dev/null and b/apps/temp-docs/public/img/auth-5-6.png differ diff --git a/apps/temp-docs/public/img/auth-5-7.png b/apps/temp-docs/public/img/auth-5-7.png new file mode 100644 index 00000000000..a3f259be06e Binary files /dev/null and b/apps/temp-docs/public/img/auth-5-7.png differ diff --git a/apps/temp-docs/public/img/auth-5-8.png b/apps/temp-docs/public/img/auth-5-8.png new file mode 100644 index 00000000000..a114192d358 Binary files /dev/null and b/apps/temp-docs/public/img/auth-5-8.png differ diff --git a/apps/temp-docs/public/img/auth-deep-dive-2-2.png b/apps/temp-docs/public/img/auth-deep-dive-2-2.png new file mode 100644 index 00000000000..0a42cd56c4f Binary files /dev/null and b/apps/temp-docs/public/img/auth-deep-dive-2-2.png differ diff --git a/apps/temp-docs/public/img/auth-deep-dive-2.png b/apps/temp-docs/public/img/auth-deep-dive-2.png new file mode 100644 index 00000000000..a874d05491e Binary files /dev/null and b/apps/temp-docs/public/img/auth-deep-dive-2.png differ diff --git a/apps/temp-docs/public/img/blog/auth-audit.png b/apps/temp-docs/public/img/blog/auth-audit.png new file mode 100644 index 00000000000..29a2f3a51ce Binary files /dev/null and b/apps/temp-docs/public/img/blog/auth-audit.png differ diff --git a/apps/temp-docs/public/img/blog/auth-azure-and-facebook.png b/apps/temp-docs/public/img/blog/auth-azure-and-facebook.png new file mode 100644 index 00000000000..560fb160a49 Binary files /dev/null and b/apps/temp-docs/public/img/blog/auth-azure-and-facebook.png differ diff --git a/apps/temp-docs/public/img/blog/auth-widget.png b/apps/temp-docs/public/img/blog/auth-widget.png new file mode 100644 index 00000000000..64ebd80d301 Binary files /dev/null and b/apps/temp-docs/public/img/blog/auth-widget.png differ diff --git a/apps/temp-docs/public/img/blog/core-web-vitals.png b/apps/temp-docs/public/img/blog/core-web-vitals.png new file mode 100644 index 00000000000..748e1d63c16 Binary files /dev/null and b/apps/temp-docs/public/img/blog/core-web-vitals.png differ diff --git a/apps/temp-docs/public/img/blog/countries.gif b/apps/temp-docs/public/img/blog/countries.gif new file mode 100644 index 00000000000..7ccbcec3d55 Binary files /dev/null and b/apps/temp-docs/public/img/blog/countries.gif differ diff --git a/apps/temp-docs/public/img/blog/dec-beta.png b/apps/temp-docs/public/img/blog/dec-beta.png new file mode 100644 index 00000000000..9afabe75f7e Binary files /dev/null and b/apps/temp-docs/public/img/blog/dec-beta.png differ diff --git a/apps/temp-docs/public/img/blog/dec-starcount.png b/apps/temp-docs/public/img/blog/dec-starcount.png new file mode 100644 index 00000000000..c1cc76efa4c Binary files /dev/null and b/apps/temp-docs/public/img/blog/dec-starcount.png differ diff --git a/apps/temp-docs/public/img/blog/feb/auth-redirect.png b/apps/temp-docs/public/img/blog/feb/auth-redirect.png new file mode 100644 index 00000000000..79fa8136503 Binary files /dev/null and b/apps/temp-docs/public/img/blog/feb/auth-redirect.png differ diff --git a/apps/temp-docs/public/img/blog/feb/autocomplete.mp4 b/apps/temp-docs/public/img/blog/feb/autocomplete.mp4 new file mode 100644 index 00000000000..73a4802dccc Binary files /dev/null and b/apps/temp-docs/public/img/blog/feb/autocomplete.mp4 differ diff --git a/apps/temp-docs/public/img/blog/feb/docs-resources.png b/apps/temp-docs/public/img/blog/feb/docs-resources.png new file mode 100644 index 00000000000..ef093486cc0 Binary files /dev/null and b/apps/temp-docs/public/img/blog/feb/docs-resources.png differ diff --git a/apps/temp-docs/public/img/blog/feb/github-stars-feb-2021.png b/apps/temp-docs/public/img/blog/feb/github-stars-feb-2021.png new file mode 100644 index 00000000000..a8b707b004d Binary files /dev/null and b/apps/temp-docs/public/img/blog/feb/github-stars-feb-2021.png differ diff --git a/apps/temp-docs/public/img/blog/feb/manage-replication.png b/apps/temp-docs/public/img/blog/feb/manage-replication.png new file mode 100644 index 00000000000..1649b0a1ce1 Binary files /dev/null and b/apps/temp-docs/public/img/blog/feb/manage-replication.png differ diff --git a/apps/temp-docs/public/img/blog/feb/new-region-south-africa.png b/apps/temp-docs/public/img/blog/feb/new-region-south-africa.png new file mode 100644 index 00000000000..03daa4e48a6 Binary files /dev/null and b/apps/temp-docs/public/img/blog/feb/new-region-south-africa.png differ diff --git a/apps/temp-docs/public/img/blog/feb/sidebar-sql.png b/apps/temp-docs/public/img/blog/feb/sidebar-sql.png new file mode 100644 index 00000000000..9bf465178d7 Binary files /dev/null and b/apps/temp-docs/public/img/blog/feb/sidebar-sql.png differ diff --git a/apps/temp-docs/public/img/blog/feb/sidebar-tables.png b/apps/temp-docs/public/img/blog/feb/sidebar-tables.png new file mode 100644 index 00000000000..d62ad7ebd61 Binary files /dev/null and b/apps/temp-docs/public/img/blog/feb/sidebar-tables.png differ diff --git a/apps/temp-docs/public/img/blog/feb/supabase-stencil.png b/apps/temp-docs/public/img/blog/feb/supabase-stencil.png new file mode 100644 index 00000000000..3358b617167 Binary files /dev/null and b/apps/temp-docs/public/img/blog/feb/supabase-stencil.png differ diff --git a/apps/temp-docs/public/img/blog/feb/supabase-storage.png b/apps/temp-docs/public/img/blog/feb/supabase-storage.png new file mode 100644 index 00000000000..52dce2f47b4 Binary files /dev/null and b/apps/temp-docs/public/img/blog/feb/supabase-storage.png differ diff --git a/apps/temp-docs/public/img/blog/jan-21-starcount.png b/apps/temp-docs/public/img/blog/jan-21-starcount.png new file mode 100644 index 00000000000..86cf0c10b2f Binary files /dev/null and b/apps/temp-docs/public/img/blog/jan-21-starcount.png differ diff --git a/apps/temp-docs/public/img/blog/nextjs-tree-analyzer.png b/apps/temp-docs/public/img/blog/nextjs-tree-analyzer.png new file mode 100644 index 00000000000..d6f95674bd5 Binary files /dev/null and b/apps/temp-docs/public/img/blog/nextjs-tree-analyzer.png differ diff --git a/apps/temp-docs/public/img/blog/npm-dependencies.png b/apps/temp-docs/public/img/blog/npm-dependencies.png new file mode 100644 index 00000000000..853b6c8ab8c Binary files /dev/null and b/apps/temp-docs/public/img/blog/npm-dependencies.png differ diff --git a/apps/temp-docs/public/img/blog/policies-email.png b/apps/temp-docs/public/img/blog/policies-email.png new file mode 100644 index 00000000000..2a6aafd6be6 Binary files /dev/null and b/apps/temp-docs/public/img/blog/policies-email.png differ diff --git a/apps/temp-docs/public/img/blog/postgres-count.png b/apps/temp-docs/public/img/blog/postgres-count.png new file mode 100644 index 00000000000..d61591f074a Binary files /dev/null and b/apps/temp-docs/public/img/blog/postgres-count.png differ diff --git a/apps/temp-docs/public/img/blog/react-server-components-supabase.png b/apps/temp-docs/public/img/blog/react-server-components-supabase.png new file mode 100644 index 00000000000..f32424fbe50 Binary files /dev/null and b/apps/temp-docs/public/img/blog/react-server-components-supabase.png differ diff --git a/apps/temp-docs/public/img/blog/regions-london-sydney.png b/apps/temp-docs/public/img/blog/regions-london-sydney.png new file mode 100644 index 00000000000..51d458e4583 Binary files /dev/null and b/apps/temp-docs/public/img/blog/regions-london-sydney.png differ diff --git a/apps/temp-docs/public/img/blog/sentry-results.png b/apps/temp-docs/public/img/blog/sentry-results.png new file mode 100644 index 00000000000..d154faf6be8 Binary files /dev/null and b/apps/temp-docs/public/img/blog/sentry-results.png differ diff --git a/apps/temp-docs/public/img/blog/supabase-auth-series.png b/apps/temp-docs/public/img/blog/supabase-auth-series.png new file mode 100644 index 00000000000..f5e34f79268 Binary files /dev/null and b/apps/temp-docs/public/img/blog/supabase-auth-series.png differ diff --git a/apps/temp-docs/public/img/blog/supabase-extensions.png b/apps/temp-docs/public/img/blog/supabase-extensions.png new file mode 100644 index 00000000000..413ea2b8f20 Binary files /dev/null and b/apps/temp-docs/public/img/blog/supabase-extensions.png differ diff --git a/apps/temp-docs/public/img/blog/supabase-postgres-cron.png b/apps/temp-docs/public/img/blog/supabase-postgres-cron.png new file mode 100644 index 00000000000..e006bf00de5 Binary files /dev/null and b/apps/temp-docs/public/img/blog/supabase-postgres-cron.png differ diff --git a/apps/temp-docs/public/img/blog/website-hook.jpeg b/apps/temp-docs/public/img/blog/website-hook.jpeg new file mode 100644 index 00000000000..0cf412b6c0a Binary files /dev/null and b/apps/temp-docs/public/img/blog/website-hook.jpeg differ diff --git a/apps/temp-docs/public/img/check.svg b/apps/temp-docs/public/img/check.svg new file mode 100644 index 00000000000..c708bd28f7a --- /dev/null +++ b/apps/temp-docs/public/img/check.svg @@ -0,0 +1,3 @@ + + + diff --git a/apps/temp-docs/public/img/community-august.png b/apps/temp-docs/public/img/community-august.png new file mode 100644 index 00000000000..ee62c54230c Binary files /dev/null and b/apps/temp-docs/public/img/community-august.png differ diff --git a/apps/temp-docs/public/img/custom-docs.png b/apps/temp-docs/public/img/custom-docs.png new file mode 100644 index 00000000000..65b688effa6 Binary files /dev/null and b/apps/temp-docs/public/img/custom-docs.png differ diff --git a/apps/temp-docs/public/img/deeplink-setting.png b/apps/temp-docs/public/img/deeplink-setting.png new file mode 100644 index 00000000000..2bd335fd5ed Binary files /dev/null and b/apps/temp-docs/public/img/deeplink-setting.png differ diff --git a/apps/temp-docs/public/img/delete-users.gif b/apps/temp-docs/public/img/delete-users.gif new file mode 100644 index 00000000000..08eb2491e76 Binary files /dev/null and b/apps/temp-docs/public/img/delete-users.gif differ diff --git a/apps/temp-docs/public/img/digital-ocean-emails-errors.png b/apps/temp-docs/public/img/digital-ocean-emails-errors.png new file mode 100644 index 00000000000..aec2f7a5d82 Binary files /dev/null and b/apps/temp-docs/public/img/digital-ocean-emails-errors.png differ diff --git a/apps/temp-docs/public/img/docker-supabase.png b/apps/temp-docs/public/img/docker-supabase.png new file mode 100644 index 00000000000..54d7be8856f Binary files /dev/null and b/apps/temp-docs/public/img/docker-supabase.png differ diff --git a/apps/temp-docs/public/img/edit-contributors.png b/apps/temp-docs/public/img/edit-contributors.png new file mode 100644 index 00000000000..7b17aab0b84 Binary files /dev/null and b/apps/temp-docs/public/img/edit-contributors.png differ diff --git a/apps/temp-docs/public/img/guides/apple-developer-portal.png b/apps/temp-docs/public/img/guides/apple-developer-portal.png new file mode 100644 index 00000000000..85309c4dc6d Binary files /dev/null and b/apps/temp-docs/public/img/guides/apple-developer-portal.png differ diff --git a/apps/temp-docs/public/img/guides/auth-messagebird/1.png b/apps/temp-docs/public/img/guides/auth-messagebird/1.png new file mode 100644 index 00000000000..0ff2ea855f2 Binary files /dev/null and b/apps/temp-docs/public/img/guides/auth-messagebird/1.png differ diff --git a/apps/temp-docs/public/img/guides/auth-messagebird/2.png b/apps/temp-docs/public/img/guides/auth-messagebird/2.png new file mode 100644 index 00000000000..de9c1459499 Binary files /dev/null and b/apps/temp-docs/public/img/guides/auth-messagebird/2.png differ diff --git a/apps/temp-docs/public/img/guides/auth-messagebird/3.png b/apps/temp-docs/public/img/guides/auth-messagebird/3.png new file mode 100644 index 00000000000..d46c759873a Binary files /dev/null and b/apps/temp-docs/public/img/guides/auth-messagebird/3.png differ diff --git a/apps/temp-docs/public/img/guides/auth-twilio/1.png b/apps/temp-docs/public/img/guides/auth-twilio/1.png new file mode 100644 index 00000000000..3ebec131556 Binary files /dev/null and b/apps/temp-docs/public/img/guides/auth-twilio/1.png differ diff --git a/apps/temp-docs/public/img/guides/auth-twilio/2.png b/apps/temp-docs/public/img/guides/auth-twilio/2.png new file mode 100644 index 00000000000..79ffac71b0f Binary files /dev/null and b/apps/temp-docs/public/img/guides/auth-twilio/2.png differ diff --git a/apps/temp-docs/public/img/guides/auth-twilio/3.png b/apps/temp-docs/public/img/guides/auth-twilio/3.png new file mode 100644 index 00000000000..9982be7802e Binary files /dev/null and b/apps/temp-docs/public/img/guides/auth-twilio/3.png differ diff --git a/apps/temp-docs/public/img/guides/auth-twilio/4.png b/apps/temp-docs/public/img/guides/auth-twilio/4.png new file mode 100644 index 00000000000..b02543e92be Binary files /dev/null and b/apps/temp-docs/public/img/guides/auth-twilio/4.png differ diff --git a/apps/temp-docs/public/img/guides/auth-twilio/5.png b/apps/temp-docs/public/img/guides/auth-twilio/5.png new file mode 100644 index 00000000000..e8eed1373a2 Binary files /dev/null and b/apps/temp-docs/public/img/guides/auth-twilio/5.png differ diff --git a/apps/temp-docs/public/img/guides/auth-twilio/6.png b/apps/temp-docs/public/img/guides/auth-twilio/6.png new file mode 100644 index 00000000000..b43126c8430 Binary files /dev/null and b/apps/temp-docs/public/img/guides/auth-twilio/6.png differ diff --git a/apps/temp-docs/public/img/guides/auth-twilio/7.png b/apps/temp-docs/public/img/guides/auth-twilio/7.png new file mode 100644 index 00000000000..16fbadafa01 Binary files /dev/null and b/apps/temp-docs/public/img/guides/auth-twilio/7.png differ diff --git a/apps/temp-docs/public/img/guides/auth-twilio/8.png b/apps/temp-docs/public/img/guides/auth-twilio/8.png new file mode 100644 index 00000000000..1c99bb7a110 Binary files /dev/null and b/apps/temp-docs/public/img/guides/auth-twilio/8.png differ diff --git a/apps/temp-docs/public/img/guides/bitbucket-portal.png b/apps/temp-docs/public/img/guides/bitbucket-portal.png new file mode 100644 index 00000000000..ebf0a58155f Binary files /dev/null and b/apps/temp-docs/public/img/guides/bitbucket-portal.png differ diff --git a/apps/temp-docs/public/img/guides/connection-pool.png b/apps/temp-docs/public/img/guides/connection-pool.png new file mode 100644 index 00000000000..c1206da9695 Binary files /dev/null and b/apps/temp-docs/public/img/guides/connection-pool.png differ diff --git a/apps/temp-docs/public/img/guides/discord-developer-portal.png b/apps/temp-docs/public/img/guides/discord-developer-portal.png new file mode 100644 index 00000000000..1ab51cd4014 Binary files /dev/null and b/apps/temp-docs/public/img/guides/discord-developer-portal.png differ diff --git a/apps/temp-docs/public/img/guides/discord-portal.png b/apps/temp-docs/public/img/guides/discord-portal.png new file mode 100644 index 00000000000..6bd35cdf308 Binary files /dev/null and b/apps/temp-docs/public/img/guides/discord-portal.png differ diff --git a/apps/temp-docs/public/img/guides/facebook-portal.png b/apps/temp-docs/public/img/guides/facebook-portal.png new file mode 100644 index 00000000000..906ea2a4349 Binary files /dev/null and b/apps/temp-docs/public/img/guides/facebook-portal.png differ diff --git a/apps/temp-docs/public/img/guides/github-portal.png b/apps/temp-docs/public/img/guides/github-portal.png new file mode 100644 index 00000000000..e987ecf54ac Binary files /dev/null and b/apps/temp-docs/public/img/guides/github-portal.png differ diff --git a/apps/temp-docs/public/img/guides/gitlab-portal.png b/apps/temp-docs/public/img/guides/gitlab-portal.png new file mode 100644 index 00000000000..90c70078a3c Binary files /dev/null and b/apps/temp-docs/public/img/guides/gitlab-portal.png differ diff --git a/apps/temp-docs/public/img/guides/google-portal.png b/apps/temp-docs/public/img/guides/google-portal.png new file mode 100644 index 00000000000..1745dbef320 Binary files /dev/null and b/apps/temp-docs/public/img/guides/google-portal.png differ diff --git a/apps/temp-docs/public/img/guides/slack-portal.png b/apps/temp-docs/public/img/guides/slack-portal.png new file mode 100644 index 00000000000..88e07529b26 Binary files /dev/null and b/apps/temp-docs/public/img/guides/slack-portal.png differ diff --git a/apps/temp-docs/public/img/guides/spotify-portal.png b/apps/temp-docs/public/img/guides/spotify-portal.png new file mode 100644 index 00000000000..9a13fa2625b Binary files /dev/null and b/apps/temp-docs/public/img/guides/spotify-portal.png differ diff --git a/apps/temp-docs/public/img/guides/twitch-applications-list.png b/apps/temp-docs/public/img/guides/twitch-applications-list.png new file mode 100644 index 00000000000..686220454ee Binary files /dev/null and b/apps/temp-docs/public/img/guides/twitch-applications-list.png differ diff --git a/apps/temp-docs/public/img/guides/twitch-console.png b/apps/temp-docs/public/img/guides/twitch-console.png new file mode 100644 index 00000000000..9687a369564 Binary files /dev/null and b/apps/temp-docs/public/img/guides/twitch-console.png differ diff --git a/apps/temp-docs/public/img/guides/twitch-developer-page.png b/apps/temp-docs/public/img/guides/twitch-developer-page.png new file mode 100644 index 00000000000..4c7ff19fb0f Binary files /dev/null and b/apps/temp-docs/public/img/guides/twitch-developer-page.png differ diff --git a/apps/temp-docs/public/img/guides/twitch-get-keys.png b/apps/temp-docs/public/img/guides/twitch-get-keys.png new file mode 100644 index 00000000000..cd34db5ac9e Binary files /dev/null and b/apps/temp-docs/public/img/guides/twitch-get-keys.png differ diff --git a/apps/temp-docs/public/img/guides/twitch-register-your-application.png b/apps/temp-docs/public/img/guides/twitch-register-your-application.png new file mode 100644 index 00000000000..da715d8d28d Binary files /dev/null and b/apps/temp-docs/public/img/guides/twitch-register-your-application.png differ diff --git a/apps/temp-docs/public/img/guides/twitter-portal.png b/apps/temp-docs/public/img/guides/twitter-portal.png new file mode 100644 index 00000000000..7c399e170c2 Binary files /dev/null and b/apps/temp-docs/public/img/guides/twitter-portal.png differ diff --git a/apps/temp-docs/public/img/hacktoberfest.png b/apps/temp-docs/public/img/hacktoberfest.png new file mode 100644 index 00000000000..1df6e4aabaa Binary files /dev/null and b/apps/temp-docs/public/img/hacktoberfest.png differ diff --git a/apps/temp-docs/public/img/hn-launch.png b/apps/temp-docs/public/img/hn-launch.png new file mode 100644 index 00000000000..33506a38075 Binary files /dev/null and b/apps/temp-docs/public/img/hn-launch.png differ diff --git a/apps/temp-docs/public/img/how-client-libs.png b/apps/temp-docs/public/img/how-client-libs.png new file mode 100644 index 00000000000..6362beeac67 Binary files /dev/null and b/apps/temp-docs/public/img/how-client-libs.png differ diff --git a/apps/temp-docs/public/img/how-replication.png b/apps/temp-docs/public/img/how-replication.png new file mode 100644 index 00000000000..97dad9afe1a Binary files /dev/null and b/apps/temp-docs/public/img/how-replication.png differ diff --git a/apps/temp-docs/public/img/how-transformation.png b/apps/temp-docs/public/img/how-transformation.png new file mode 100644 index 00000000000..d0e404d821b Binary files /dev/null and b/apps/temp-docs/public/img/how-transformation.png differ diff --git a/apps/temp-docs/public/img/invite-users.gif b/apps/temp-docs/public/img/invite-users.gif new file mode 100644 index 00000000000..bd3a20c1c1f Binary files /dev/null and b/apps/temp-docs/public/img/invite-users.gif differ diff --git a/apps/temp-docs/public/img/keyboard-shortcuts.png b/apps/temp-docs/public/img/keyboard-shortcuts.png new file mode 100644 index 00000000000..1d91c48b7bf Binary files /dev/null and b/apps/temp-docs/public/img/keyboard-shortcuts.png differ diff --git a/apps/temp-docs/public/img/libraries/angular-icon.svg b/apps/temp-docs/public/img/libraries/angular-icon.svg new file mode 100644 index 00000000000..5f8b0aaac49 --- /dev/null +++ b/apps/temp-docs/public/img/libraries/angular-icon.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/temp-docs/public/img/libraries/c-sharp-icon.svg b/apps/temp-docs/public/img/libraries/c-sharp-icon.svg new file mode 100644 index 00000000000..5f58f928629 --- /dev/null +++ b/apps/temp-docs/public/img/libraries/c-sharp-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/temp-docs/public/img/libraries/dart-icon.svg b/apps/temp-docs/public/img/libraries/dart-icon.svg new file mode 100644 index 00000000000..7fdd552a41e --- /dev/null +++ b/apps/temp-docs/public/img/libraries/dart-icon.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/temp-docs/public/img/libraries/expo-icon.svg b/apps/temp-docs/public/img/libraries/expo-icon.svg new file mode 100644 index 00000000000..e4deeadf133 --- /dev/null +++ b/apps/temp-docs/public/img/libraries/expo-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/temp-docs/public/img/libraries/javascript-icon.svg b/apps/temp-docs/public/img/libraries/javascript-icon.svg new file mode 100644 index 00000000000..1f203d35ed6 --- /dev/null +++ b/apps/temp-docs/public/img/libraries/javascript-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/temp-docs/public/img/libraries/kotlin-icon.svg b/apps/temp-docs/public/img/libraries/kotlin-icon.svg new file mode 100644 index 00000000000..93fee789273 --- /dev/null +++ b/apps/temp-docs/public/img/libraries/kotlin-icon.svg @@ -0,0 +1 @@ +icon_Kotlin \ No newline at end of file diff --git a/apps/temp-docs/public/img/libraries/nestjs-icon.svg b/apps/temp-docs/public/img/libraries/nestjs-icon.svg new file mode 100644 index 00000000000..6deb3ed54ee --- /dev/null +++ b/apps/temp-docs/public/img/libraries/nestjs-icon.svg @@ -0,0 +1,19 @@ + + + + + + diff --git a/apps/temp-docs/public/img/libraries/nextjs-icon.svg b/apps/temp-docs/public/img/libraries/nextjs-icon.svg new file mode 100644 index 00000000000..99afa3413d3 --- /dev/null +++ b/apps/temp-docs/public/img/libraries/nextjs-icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/apps/temp-docs/public/img/libraries/python-icon.svg b/apps/temp-docs/public/img/libraries/python-icon.svg new file mode 100644 index 00000000000..366f52f3393 --- /dev/null +++ b/apps/temp-docs/public/img/libraries/python-icon.svg @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/apps/temp-docs/public/img/libraries/react-icon.svg b/apps/temp-docs/public/img/libraries/react-icon.svg new file mode 100644 index 00000000000..88860de5722 --- /dev/null +++ b/apps/temp-docs/public/img/libraries/react-icon.svg @@ -0,0 +1,37 @@ + + + + + + + + + + + diff --git a/apps/temp-docs/public/img/libraries/react-native-icon.svg b/apps/temp-docs/public/img/libraries/react-native-icon.svg new file mode 100644 index 00000000000..88860de5722 --- /dev/null +++ b/apps/temp-docs/public/img/libraries/react-native-icon.svg @@ -0,0 +1,37 @@ + + + + + + + + + + + diff --git a/apps/temp-docs/public/img/libraries/rust-icon.svg b/apps/temp-docs/public/img/libraries/rust-icon.svg new file mode 100644 index 00000000000..b486919ff05 --- /dev/null +++ b/apps/temp-docs/public/img/libraries/rust-icon.svg @@ -0,0 +1,2 @@ + +Rust programming language logoimage/svg+xml diff --git a/apps/temp-docs/public/img/libraries/svelte-icon.svg b/apps/temp-docs/public/img/libraries/svelte-icon.svg new file mode 100644 index 00000000000..4bf279659a9 --- /dev/null +++ b/apps/temp-docs/public/img/libraries/svelte-icon.svg @@ -0,0 +1,20 @@ + + + + + + + diff --git a/apps/temp-docs/public/img/libraries/vuejs-icon.svg b/apps/temp-docs/public/img/libraries/vuejs-icon.svg new file mode 100644 index 00000000000..a1d285eb2a1 --- /dev/null +++ b/apps/temp-docs/public/img/libraries/vuejs-icon.svg @@ -0,0 +1,2 @@ + + diff --git a/apps/temp-docs/public/img/magic-links.png b/apps/temp-docs/public/img/magic-links.png new file mode 100644 index 00000000000..acc767b5001 Binary files /dev/null and b/apps/temp-docs/public/img/magic-links.png differ diff --git a/apps/temp-docs/public/img/monitoro-requests.png b/apps/temp-docs/public/img/monitoro-requests.png new file mode 100644 index 00000000000..623ba2edc29 Binary files /dev/null and b/apps/temp-docs/public/img/monitoro-requests.png differ diff --git a/apps/temp-docs/public/img/new-sponsor-dark.png b/apps/temp-docs/public/img/new-sponsor-dark.png new file mode 100644 index 00000000000..f9956d222d6 Binary files /dev/null and b/apps/temp-docs/public/img/new-sponsor-dark.png differ diff --git a/apps/temp-docs/public/img/omar-monitoro.png b/apps/temp-docs/public/img/omar-monitoro.png new file mode 100644 index 00000000000..5d285f2e240 Binary files /dev/null and b/apps/temp-docs/public/img/omar-monitoro.png differ diff --git a/apps/temp-docs/public/img/postgres-views.png b/apps/temp-docs/public/img/postgres-views.png new file mode 100644 index 00000000000..36a3841bbe0 Binary files /dev/null and b/apps/temp-docs/public/img/postgres-views.png differ diff --git a/apps/temp-docs/public/img/propose-changes.png b/apps/temp-docs/public/img/propose-changes.png new file mode 100644 index 00000000000..c240c42184f Binary files /dev/null and b/apps/temp-docs/public/img/propose-changes.png differ diff --git a/apps/temp-docs/public/img/release-dec-2020.jpg b/apps/temp-docs/public/img/release-dec-2020.jpg new file mode 100644 index 00000000000..dd6d2d6e76b Binary files /dev/null and b/apps/temp-docs/public/img/release-dec-2020.jpg differ diff --git a/apps/temp-docs/public/img/release-feb-2021.jpg b/apps/temp-docs/public/img/release-feb-2021.jpg new file mode 100644 index 00000000000..9348e74ad4b Binary files /dev/null and b/apps/temp-docs/public/img/release-feb-2021.jpg differ diff --git a/apps/temp-docs/public/img/release-jan-2021.jpg b/apps/temp-docs/public/img/release-jan-2021.jpg new file mode 100644 index 00000000000..7b0df47e0f1 Binary files /dev/null and b/apps/temp-docs/public/img/release-jan-2021.jpg differ diff --git a/apps/temp-docs/public/img/roboflow-gallery.png b/apps/temp-docs/public/img/roboflow-gallery.png new file mode 100644 index 00000000000..4f04b4afa94 Binary files /dev/null and b/apps/temp-docs/public/img/roboflow-gallery.png differ diff --git a/apps/temp-docs/public/img/roboflow-og.png b/apps/temp-docs/public/img/roboflow-og.png new file mode 100644 index 00000000000..4dc7c43baf9 Binary files /dev/null and b/apps/temp-docs/public/img/roboflow-og.png differ diff --git a/apps/temp-docs/public/img/roboflow-quote.png b/apps/temp-docs/public/img/roboflow-quote.png new file mode 100644 index 00000000000..d88f5c129b4 Binary files /dev/null and b/apps/temp-docs/public/img/roboflow-quote.png differ diff --git a/apps/temp-docs/public/img/roboflow-stat.png b/apps/temp-docs/public/img/roboflow-stat.png new file mode 100644 index 00000000000..b83f978e72a Binary files /dev/null and b/apps/temp-docs/public/img/roboflow-stat.png differ diff --git a/apps/temp-docs/public/img/roboflow-website.png b/apps/temp-docs/public/img/roboflow-website.png new file mode 100644 index 00000000000..8e7de1cafab Binary files /dev/null and b/apps/temp-docs/public/img/roboflow-website.png differ diff --git a/apps/temp-docs/public/img/sarup-tayfa.png b/apps/temp-docs/public/img/sarup-tayfa.png new file mode 100644 index 00000000000..5c443ca87bf Binary files /dev/null and b/apps/temp-docs/public/img/sarup-tayfa.png differ diff --git a/apps/temp-docs/public/img/showcase-logo/supabase-logo.svg b/apps/temp-docs/public/img/showcase-logo/supabase-logo.svg new file mode 100644 index 00000000000..1315b0a5ccf --- /dev/null +++ b/apps/temp-docs/public/img/showcase-logo/supabase-logo.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/temp-docs/public/img/sql-editor.png b/apps/temp-docs/public/img/sql-editor.png new file mode 100644 index 00000000000..2f84849abde Binary files /dev/null and b/apps/temp-docs/public/img/sql-editor.png differ diff --git a/apps/temp-docs/public/img/status-page.png b/apps/temp-docs/public/img/status-page.png new file mode 100644 index 00000000000..8b5460b8a41 Binary files /dev/null and b/apps/temp-docs/public/img/status-page.png differ diff --git a/apps/temp-docs/public/img/strive-supabase.png b/apps/temp-docs/public/img/strive-supabase.png new file mode 100644 index 00000000000..9656ce4b5b9 Binary files /dev/null and b/apps/temp-docs/public/img/strive-supabase.png differ diff --git a/apps/temp-docs/public/img/supabase-angular-demo.png b/apps/temp-docs/public/img/supabase-angular-demo.png new file mode 100644 index 00000000000..7fbeaa64199 Binary files /dev/null and b/apps/temp-docs/public/img/supabase-angular-demo.png differ diff --git a/apps/temp-docs/public/img/supabase-architecture.png b/apps/temp-docs/public/img/supabase-architecture.png new file mode 100644 index 00000000000..7972446c168 Binary files /dev/null and b/apps/temp-docs/public/img/supabase-architecture.png differ diff --git a/apps/temp-docs/public/img/supabase-auth-cover.png b/apps/temp-docs/public/img/supabase-auth-cover.png new file mode 100644 index 00000000000..627e77779f7 Binary files /dev/null and b/apps/temp-docs/public/img/supabase-auth-cover.png differ diff --git a/apps/temp-docs/public/img/supabase-december-2020.png b/apps/temp-docs/public/img/supabase-december-2020.png new file mode 100644 index 00000000000..9d871a77993 Binary files /dev/null and b/apps/temp-docs/public/img/supabase-december-2020.png differ diff --git a/apps/temp-docs/public/img/supabase-flutter-account-page.png b/apps/temp-docs/public/img/supabase-flutter-account-page.png new file mode 100644 index 00000000000..1f275727b7c Binary files /dev/null and b/apps/temp-docs/public/img/supabase-flutter-account-page.png differ diff --git a/apps/temp-docs/public/img/supabase-flutter-demo.png b/apps/temp-docs/public/img/supabase-flutter-demo.png new file mode 100644 index 00000000000..a9bde86c590 Binary files /dev/null and b/apps/temp-docs/public/img/supabase-flutter-demo.png differ diff --git a/apps/temp-docs/public/img/supabase-github-discussions.png b/apps/temp-docs/public/img/supabase-github-discussions.png new file mode 100644 index 00000000000..3cc3deb7e81 Binary files /dev/null and b/apps/temp-docs/public/img/supabase-github-discussions.png differ diff --git a/apps/temp-docs/public/img/supabase-github-stars-june.png b/apps/temp-docs/public/img/supabase-github-stars-june.png new file mode 100644 index 00000000000..db26c6c30fc Binary files /dev/null and b/apps/temp-docs/public/img/supabase-github-stars-june.png differ diff --git a/apps/temp-docs/public/img/supabase-hacktoberfest-board.png b/apps/temp-docs/public/img/supabase-hacktoberfest-board.png new file mode 100644 index 00000000000..de69c097bfa Binary files /dev/null and b/apps/temp-docs/public/img/supabase-hacktoberfest-board.png differ diff --git a/apps/temp-docs/public/img/supabase-hn-launch.png b/apps/temp-docs/public/img/supabase-hn-launch.png new file mode 100644 index 00000000000..3f26b60faff Binary files /dev/null and b/apps/temp-docs/public/img/supabase-hn-launch.png differ diff --git a/apps/temp-docs/public/img/supabase-january-2021.png b/apps/temp-docs/public/img/supabase-january-2021.png new file mode 100644 index 00000000000..730c79231cb Binary files /dev/null and b/apps/temp-docs/public/img/supabase-january-2021.png differ diff --git a/apps/temp-docs/public/img/supabase-js-1-0.png b/apps/temp-docs/public/img/supabase-js-1-0.png new file mode 100644 index 00000000000..dad6ec0a4dd Binary files /dev/null and b/apps/temp-docs/public/img/supabase-js-1-0.png differ diff --git a/apps/temp-docs/public/img/supabase-middleware-docker.png b/apps/temp-docs/public/img/supabase-middleware-docker.png new file mode 100644 index 00000000000..29fa1c875e2 Binary files /dev/null and b/apps/temp-docs/public/img/supabase-middleware-docker.png differ diff --git a/apps/temp-docs/public/img/supabase-monaco-editor.png b/apps/temp-docs/public/img/supabase-monaco-editor.png new file mode 100644 index 00000000000..f6091d117fd Binary files /dev/null and b/apps/temp-docs/public/img/supabase-monaco-editor.png differ diff --git a/apps/temp-docs/public/img/supabase-monitoro.png b/apps/temp-docs/public/img/supabase-monitoro.png new file mode 100644 index 00000000000..272ad8c47fe Binary files /dev/null and b/apps/temp-docs/public/img/supabase-monitoro.png differ diff --git a/apps/temp-docs/public/img/supabase-november-2020.png b/apps/temp-docs/public/img/supabase-november-2020.png new file mode 100644 index 00000000000..fcac70e83e5 Binary files /dev/null and b/apps/temp-docs/public/img/supabase-november-2020.png differ diff --git a/apps/temp-docs/public/img/supabase-oauth-logins.png b/apps/temp-docs/public/img/supabase-oauth-logins.png new file mode 100644 index 00000000000..2e2aa3db2be Binary files /dev/null and b/apps/temp-docs/public/img/supabase-oauth-logins.png differ diff --git a/apps/temp-docs/public/img/supabase-october-2020.png b/apps/temp-docs/public/img/supabase-october-2020.png new file mode 100644 index 00000000000..1abacc71a31 Binary files /dev/null and b/apps/temp-docs/public/img/supabase-october-2020.png differ diff --git a/apps/temp-docs/public/img/supabase-og-image.png b/apps/temp-docs/public/img/supabase-og-image.png new file mode 100644 index 00000000000..c2f4d0ea806 Binary files /dev/null and b/apps/temp-docs/public/img/supabase-og-image.png differ diff --git a/apps/temp-docs/public/img/supabase-react-demo.png b/apps/temp-docs/public/img/supabase-react-demo.png new file mode 100644 index 00000000000..cdeba23d472 Binary files /dev/null and b/apps/temp-docs/public/img/supabase-react-demo.png differ diff --git a/apps/temp-docs/public/img/supabase-redwoodjs-demo.png b/apps/temp-docs/public/img/supabase-redwoodjs-demo.png new file mode 100644 index 00000000000..51f20b8e959 Binary files /dev/null and b/apps/temp-docs/public/img/supabase-redwoodjs-demo.png differ diff --git a/apps/temp-docs/public/img/supabase-september-2020.png b/apps/temp-docs/public/img/supabase-september-2020.png new file mode 100644 index 00000000000..9103aae8db6 Binary files /dev/null and b/apps/temp-docs/public/img/supabase-september-2020.png differ diff --git a/apps/temp-docs/public/img/supabase-squad.png b/apps/temp-docs/public/img/supabase-squad.png new file mode 100644 index 00000000000..6f52e57826d Binary files /dev/null and b/apps/temp-docs/public/img/supabase-squad.png differ diff --git a/apps/temp-docs/public/img/supabase-strive-school.png b/apps/temp-docs/public/img/supabase-strive-school.png new file mode 100644 index 00000000000..445f48589f8 Binary files /dev/null and b/apps/temp-docs/public/img/supabase-strive-school.png differ diff --git a/apps/temp-docs/public/img/supabase-svelte-demo.png b/apps/temp-docs/public/img/supabase-svelte-demo.png new file mode 100644 index 00000000000..267a5b4cd8d Binary files /dev/null and b/apps/temp-docs/public/img/supabase-svelte-demo.png differ diff --git a/apps/temp-docs/public/img/supabase-tayfa.png b/apps/temp-docs/public/img/supabase-tayfa.png new file mode 100644 index 00000000000..215ce4677e8 Binary files /dev/null and b/apps/temp-docs/public/img/supabase-tayfa.png differ diff --git a/apps/temp-docs/public/img/supabase-traffic-may.png b/apps/temp-docs/public/img/supabase-traffic-may.png new file mode 100644 index 00000000000..e5f40eb2c1b Binary files /dev/null and b/apps/temp-docs/public/img/supabase-traffic-may.png differ diff --git a/apps/temp-docs/public/img/supabase-vue-3-demo.png b/apps/temp-docs/public/img/supabase-vue-3-demo.png new file mode 100644 index 00000000000..f3151a101b1 Binary files /dev/null and b/apps/temp-docs/public/img/supabase-vue-3-demo.png differ diff --git a/apps/temp-docs/public/img/supabase-xendit.png b/apps/temp-docs/public/img/supabase-xendit.png new file mode 100644 index 00000000000..b1dc884c608 Binary files /dev/null and b/apps/temp-docs/public/img/supabase-xendit.png differ diff --git a/apps/temp-docs/public/img/table-view.png b/apps/temp-docs/public/img/table-view.png new file mode 100644 index 00000000000..dbc9fc6ed58 Binary files /dev/null and b/apps/temp-docs/public/img/table-view.png differ diff --git a/apps/temp-docs/public/img/tanmai-tayfa.png b/apps/temp-docs/public/img/tanmai-tayfa.png new file mode 100644 index 00000000000..ed9cfe76773 Binary files /dev/null and b/apps/temp-docs/public/img/tanmai-tayfa.png differ diff --git a/apps/temp-docs/public/img/toadli-og.jpg b/apps/temp-docs/public/img/toadli-og.jpg new file mode 100644 index 00000000000..7ab8ec7d884 Binary files /dev/null and b/apps/temp-docs/public/img/toadli-og.jpg differ diff --git a/apps/temp-docs/public/img/typescript-support.gif b/apps/temp-docs/public/img/typescript-support.gif new file mode 100644 index 00000000000..615d600d864 Binary files /dev/null and b/apps/temp-docs/public/img/typescript-support.gif differ diff --git a/apps/temp-docs/public/img/user-management-demo.png b/apps/temp-docs/public/img/user-management-demo.png new file mode 100644 index 00000000000..ee61c3d52aa Binary files /dev/null and b/apps/temp-docs/public/img/user-management-demo.png differ diff --git a/apps/temp-docs/public/img/worklife-dark.png b/apps/temp-docs/public/img/worklife-dark.png new file mode 100644 index 00000000000..b1454797d14 Binary files /dev/null and b/apps/temp-docs/public/img/worklife-dark.png differ diff --git a/apps/temp-docs/public/img/yc-gray.png b/apps/temp-docs/public/img/yc-gray.png new file mode 100644 index 00000000000..f3fade0625b Binary files /dev/null and b/apps/temp-docs/public/img/yc-gray.png differ diff --git a/apps/temp-docs/public/supabase-dark.svg b/apps/temp-docs/public/supabase-dark.svg new file mode 100644 index 00000000000..d64e9d1a47a --- /dev/null +++ b/apps/temp-docs/public/supabase-dark.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/temp-docs/public/supabase-light.svg b/apps/temp-docs/public/supabase-light.svg new file mode 100644 index 00000000000..47126efbdf5 --- /dev/null +++ b/apps/temp-docs/public/supabase-light.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/temp-docs/public/videos/api/api-create-table-sm.mp4 b/apps/temp-docs/public/videos/api/api-create-table-sm.mp4 new file mode 100644 index 00000000000..c912366145a Binary files /dev/null and b/apps/temp-docs/public/videos/api/api-create-table-sm.mp4 differ diff --git a/apps/temp-docs/public/videos/api/api-create-table.mp4 b/apps/temp-docs/public/videos/api/api-create-table.mp4 new file mode 100644 index 00000000000..326cd448e5f Binary files /dev/null and b/apps/temp-docs/public/videos/api/api-create-table.mp4 differ diff --git a/apps/temp-docs/public/videos/api/api-realtime.mp4 b/apps/temp-docs/public/videos/api/api-realtime.mp4 new file mode 100644 index 00000000000..6b91ae1955d Binary files /dev/null and b/apps/temp-docs/public/videos/api/api-realtime.mp4 differ diff --git a/apps/temp-docs/public/videos/api/api-url-and-key.mp4 b/apps/temp-docs/public/videos/api/api-url-and-key.mp4 new file mode 100644 index 00000000000..7a5628f7211 Binary files /dev/null and b/apps/temp-docs/public/videos/api/api-url-and-key.mp4 differ diff --git a/apps/temp-docs/public/videos/auth-zoom2.mp4 b/apps/temp-docs/public/videos/auth-zoom2.mp4 new file mode 100644 index 00000000000..447ea8f5452 Binary files /dev/null and b/apps/temp-docs/public/videos/auth-zoom2.mp4 differ diff --git a/apps/temp-docs/public/videos/confirm-email.mp4 b/apps/temp-docs/public/videos/confirm-email.mp4 new file mode 100644 index 00000000000..60efdc590a6 Binary files /dev/null and b/apps/temp-docs/public/videos/confirm-email.mp4 differ diff --git a/apps/temp-docs/public/videos/csv-download-zoom.mp4 b/apps/temp-docs/public/videos/csv-download-zoom.mp4 new file mode 100644 index 00000000000..9292e7f3ad0 Binary files /dev/null and b/apps/temp-docs/public/videos/csv-download-zoom.mp4 differ diff --git a/apps/temp-docs/public/videos/duplicate-tables.mp4 b/apps/temp-docs/public/videos/duplicate-tables.mp4 new file mode 100644 index 00000000000..ad9e0cd99e1 Binary files /dev/null and b/apps/temp-docs/public/videos/duplicate-tables.mp4 differ diff --git a/apps/temp-docs/public/videos/favorites.mp4 b/apps/temp-docs/public/videos/favorites.mp4 new file mode 100644 index 00000000000..b643a0084ab Binary files /dev/null and b/apps/temp-docs/public/videos/favorites.mp4 differ diff --git a/apps/temp-docs/public/videos/invite-team.mp4 b/apps/temp-docs/public/videos/invite-team.mp4 new file mode 100644 index 00000000000..030c125a0e0 Binary files /dev/null and b/apps/temp-docs/public/videos/invite-team.mp4 differ diff --git a/apps/temp-docs/public/videos/lazy_loading.mov b/apps/temp-docs/public/videos/lazy_loading.mov new file mode 100644 index 00000000000..4c3be4892ef Binary files /dev/null and b/apps/temp-docs/public/videos/lazy_loading.mov differ diff --git a/apps/temp-docs/public/videos/new-tables.mp4 b/apps/temp-docs/public/videos/new-tables.mp4 new file mode 100644 index 00000000000..ac1a589e810 Binary files /dev/null and b/apps/temp-docs/public/videos/new-tables.mp4 differ diff --git a/apps/temp-docs/public/videos/pgbouncer-connection.mp4 b/apps/temp-docs/public/videos/pgbouncer-connection.mp4 new file mode 100644 index 00000000000..f05740fc633 Binary files /dev/null and b/apps/temp-docs/public/videos/pgbouncer-connection.mp4 differ diff --git a/apps/temp-docs/public/videos/policies-zoom2.mp4 b/apps/temp-docs/public/videos/policies-zoom2.mp4 new file mode 100644 index 00000000000..b912fa9ea48 Binary files /dev/null and b/apps/temp-docs/public/videos/policies-zoom2.mp4 differ diff --git a/apps/temp-docs/public/videos/postgres-connection.mp4 b/apps/temp-docs/public/videos/postgres-connection.mp4 new file mode 100644 index 00000000000..1aa7816f924 Binary files /dev/null and b/apps/temp-docs/public/videos/postgres-connection.mp4 differ diff --git a/apps/temp-docs/public/videos/realtime-updates.mp4 b/apps/temp-docs/public/videos/realtime-updates.mp4 new file mode 100644 index 00000000000..4f560c1307c Binary files /dev/null and b/apps/temp-docs/public/videos/realtime-updates.mp4 differ diff --git a/apps/temp-docs/public/videos/relational-drilldown-zoom.mp4 b/apps/temp-docs/public/videos/relational-drilldown-zoom.mp4 new file mode 100644 index 00000000000..7ecba63069b Binary files /dev/null and b/apps/temp-docs/public/videos/relational-drilldown-zoom.mp4 differ diff --git a/apps/temp-docs/public/videos/rls-zoom2.mp4 b/apps/temp-docs/public/videos/rls-zoom2.mp4 new file mode 100644 index 00000000000..07a379c5ea8 Binary files /dev/null and b/apps/temp-docs/public/videos/rls-zoom2.mp4 differ diff --git a/apps/temp-docs/public/videos/sql-user-management-starter.mp4 b/apps/temp-docs/public/videos/sql-user-management-starter.mp4 new file mode 100644 index 00000000000..023c4144bbe Binary files /dev/null and b/apps/temp-docs/public/videos/sql-user-management-starter.mp4 differ diff --git a/apps/temp-docs/public/videos/storage/create.mp4 b/apps/temp-docs/public/videos/storage/create.mp4 new file mode 100644 index 00000000000..d5addac0968 Binary files /dev/null and b/apps/temp-docs/public/videos/storage/create.mp4 differ diff --git a/apps/temp-docs/public/videos/storage/download.mp4 b/apps/temp-docs/public/videos/storage/download.mp4 new file mode 100644 index 00000000000..6da5deb13f0 Binary files /dev/null and b/apps/temp-docs/public/videos/storage/download.mp4 differ diff --git a/apps/temp-docs/public/videos/storage/policies.mp4 b/apps/temp-docs/public/videos/storage/policies.mp4 new file mode 100644 index 00000000000..66c2edabef6 Binary files /dev/null and b/apps/temp-docs/public/videos/storage/policies.mp4 differ diff --git a/apps/temp-docs/public/videos/storage/upload.mp4 b/apps/temp-docs/public/videos/storage/upload.mp4 new file mode 100644 index 00000000000..9351c578b38 Binary files /dev/null and b/apps/temp-docs/public/videos/storage/upload.mp4 differ diff --git a/apps/temp-docs/public/videos/table-pagination.mp4 b/apps/temp-docs/public/videos/table-pagination.mp4 new file mode 100644 index 00000000000..5a652d645db Binary files /dev/null and b/apps/temp-docs/public/videos/table-pagination.mp4 differ diff --git a/apps/temp-docs/public/videos/table-relationships.mp4 b/apps/temp-docs/public/videos/table-relationships.mp4 new file mode 100644 index 00000000000..5aa15cb7cc4 Binary files /dev/null and b/apps/temp-docs/public/videos/table-relationships.mp4 differ diff --git a/apps/temp-docs/public/videos/toggle-extensions.mp4 b/apps/temp-docs/public/videos/toggle-extensions.mp4 new file mode 100644 index 00000000000..42643ac9e85 Binary files /dev/null and b/apps/temp-docs/public/videos/toggle-extensions.mp4 differ diff --git a/apps/temp-docs/public/videos/update-docs.mp4 b/apps/temp-docs/public/videos/update-docs.mp4 new file mode 100644 index 00000000000..159b4f638a3 Binary files /dev/null and b/apps/temp-docs/public/videos/update-docs.mp4 differ diff --git a/apps/temp-docs/src/components/Sidebar.tsx b/apps/temp-docs/src/components/Sidebar.tsx deleted file mode 100644 index a8d7ce26a6f..00000000000 --- a/apps/temp-docs/src/components/Sidebar.tsx +++ /dev/null @@ -1,30 +0,0 @@ -const navigation = [ - { name: 'Guides', href: '#', icon: null, current: true }, - { name: 'Reference', href: '#', icon: null, current: false }, - { name: 'Examples', href: '#', icon: null, current: false }, - { name: 'API', href: '#', icon: null, current: false }, - { name: 'Forum', href: '#', icon: null, current: false }, -] - -function classNames(...classes: string[]) { - return classes.filter(Boolean).join(' ') -} - -export default function Sidebar() { - return ( - - ) -} diff --git a/apps/temp-docs/src/pages/_app.tsx b/apps/temp-docs/src/pages/_app.tsx deleted file mode 100644 index 3f1a17de101..00000000000 --- a/apps/temp-docs/src/pages/_app.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import React from 'react' -import Docs from '.' -import '../styles/tailwind.css' - -const Index = () => { - return -} - -export default Index diff --git a/apps/temp-docs/src/pages/index.tsx b/apps/temp-docs/src/pages/index.tsx deleted file mode 100644 index 23642e79837..00000000000 --- a/apps/temp-docs/src/pages/index.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import { Button, Layouts } from 'common' -import Sidebar from '../components/Sidebar' - -export default function Docs() { - return ( - }> - <> -

    Docs

    -