Documentation for the new DX (#253)

## What kind of change does this PR introduce?

Updates the docs with the new developer experience: https://deploy-preview-253--supabase.netlify.app/docs

- Documents the new Auth using `gotrue-js`
- Fixes #179 
- Fixes OAuth links https://github.com/supabase/supabase/issues/241#issuecomment-705632335 
- [x] Add docs on Policies

## Additional context

Related PR on `supabase-js` https://github.com/supabase/supabase-js/pull/50

* Updates the docs for the new Auth DX.

* docs: adds docs for subscribing to rows

* Updates all the reads

* Updates all the docs with the new format

* docs: Replaces all { error, data} with data first, because I subjectively think it looks better

* Adds some of the breaking changes to a blog post

* Adds headings

* removes the blog post since it is now in notion

* Adds the Oauth changes

* removes recharts because we no longer use it

* Adds basic structure for GoTrue ref

* Adds styles for the api reference docs

* Adds more generated docs

* Downloads the files to work locally

* Adds a supabase generator

* Moves some of the guides into the "tools" folder

* Re-shuffles some of the pages around

* Generated everythign related to the Supabase Client

* Refactors and categorieses the pages

* Changes the names to be more readable

* Migrates almost all of the filters into the API reference

* Moves most of the stored procedure filters

* Adds realtime-js to the mix

* More desciptive titles

* Moves all the generated docs to the docs folder

* Moves over some of the data manipulators

* Extracts most of the client functionality to the API ref

* Adds more detail to the guides

* Removes the reference to the emulator

* Adds the supabase 1.0 blog post

* Adds a redirects for netlify

* chore: Updates packages

* Updates broken links

* Adding docs for the server

* Adds comments to gotrue and pgapi

* Adds a twitter icon to our navbar

* Updates the auth with the new user and session return values

* Updates the sponsors

* Styles for cards

* Adds a default value to all of the Tabs
This commit is contained in:
Copple authored and GitHub committed 2020-11-02 11:08:02 +08:00
1 parent e9923e739b
commit a788003648
189 files changed
+75629 -6475

No files matched your search

+1 -4
View File
@@ -25,11 +25,8 @@ github.issues:
github.repos: \
github.repos.supabase \
github.repos.realtime \
github.repos.marketplace \
github.repos.pg-api \
github.repos.postgrest-js \
github.repos.postgres \
github.repos.doctest-js
github.repos.pg-api
github.repos.%:
curl -sS https://api.github.com/repos/supabase/$* \
+68 -124
View File
@@ -1272,32 +1272,69 @@
}
}
},
"@supabase/postgrest-js": {
"version": "0.17.0",
"resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-0.17.0.tgz",
"integrity": "sha512-7Dt7ALli+bOQK51JMolraI08sJg2UweNuGFghr8MrX4nc3WoDwL5PP6fNZwy+j/7f7nvvM6s1OUtqNTvqiW+5Q==",
"@supabase/gotrue-js": {
"version": "1.5.10",
"resolved": "https://registry.npmjs.org/@supabase/gotrue-js/-/gotrue-js-1.5.10.tgz",
"integrity": "sha512-SAoT5znv6r/nasJQp35n72dYGkBMWgKsCHc45vrCu8M/XDNpU/9vN8TzzziK4M0tWg3LGKm7MbRkNOwLEk5a8A==",
"requires": {
"superagent": "^5.2.1"
"cross-fetch": "^3.0.6"
},
"dependencies": {
"cross-fetch": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.0.6.tgz",
"integrity": "sha512-KBPUbqgFjzWlVcURG+Svp9TlhA5uliYtiNx/0r8nv0pdypeQCRJ9IaSIc3q/x3q8t3F75cHuwxVql1HFGHCNJQ==",
"requires": {
"node-fetch": "2.6.1"
}
},
"node-fetch": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
"integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw=="
}
}
},
"@supabase/postgrest-js": {
"version": "0.21.0",
"resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-0.21.0.tgz",
"integrity": "sha512-2MxPodIf1Ij+iR2RYVxziZpBv/9j6zT2d2UWSvdu2GT8yODo1hO2oXXT4cFJqvxmVX6A+z4J39wBqutt9vlttQ==",
"requires": {
"cross-fetch": "^3.0.6"
},
"dependencies": {
"cross-fetch": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.0.6.tgz",
"integrity": "sha512-KBPUbqgFjzWlVcURG+Svp9TlhA5uliYtiNx/0r8nv0pdypeQCRJ9IaSIc3q/x3q8t3F75cHuwxVql1HFGHCNJQ==",
"requires": {
"node-fetch": "2.6.1"
}
},
"node-fetch": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
"integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw=="
}
}
},
"@supabase/realtime-js": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-0.9.0.tgz",
"integrity": "sha512-aYkVsD2hNgD7QPPBV+LALJTexNf8pVhIh9qJC13NnOLYZpudtHbof+rg0dgq5+GIhYa8HzqUMdf+OwwlQVJgsw==",
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-1.0.6.tgz",
"integrity": "sha512-qzYYBzXteYsqQYlLzoYwee2OloWn3w8YzUFbDYFUPdkUwLs01OIqsm+lRCzKDivmyn2G0FJQjloWcF4BF5TyBg==",
"requires": {
"@babel/runtime": "^7.9.2",
"@types/websocket": "^1.0.1",
"query-string": "^6.12.1",
"websocket": "^1.0.31"
}
},
"@supabase/supabase-js": {
"version": "0.36.5",
"resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-0.36.5.tgz",
"integrity": "sha512-iiY5lDIrbhQjT8grRgXbUfIU5omD8CfNI4Iio3z/DHjsdrzYNf9o0/kRAzVVITPOuqlN9g0QhPt7bzRQKxLbwA==",
"version": "github:kiwicopple/supabase-js#6199fa765eee19a83befd755faff9c9dcb250a00",
"from": "github:kiwicopple/supabase-js#feature/migrate_to_typescript",
"requires": {
"@supabase/postgrest-js": "^0.17.0",
"@supabase/realtime-js": "^0.9.0",
"superagent": "^5.2.1"
"@supabase/gotrue-js": "^1.5.10",
"@supabase/postgrest-js": "^0.21.0",
"@supabase/realtime-js": "^1.0.6"
}
},
"@types/json-schema": {
@@ -1305,6 +1342,19 @@
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz",
"integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw=="
},
"@types/node": {
"version": "14.14.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.0.tgz",
"integrity": "sha512-BfbIHP9IapdupGhq/hc+jT5dyiBVZ2DdeC5WwJWQWDb0GijQlzUFAeIQn/2GtvZcd2HVUU7An8felIICFTC2qg=="
},
"@types/websocket": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@types/websocket/-/websocket-1.0.1.tgz",
"integrity": "sha512-f5WLMpezwVxCLm1xQe/kdPpQIOmL0TXYx2O15VYfYzc7hTIdxiOoOvez+McSIw3b7z/1zGovew9YSL7+h4h7/Q==",
"requires": {
"@types/node": "*"
}
},
"@webassemblyjs/ast": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz",
@@ -1707,11 +1757,6 @@
"resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz",
"integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ=="
},
"asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
},
"atob": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
@@ -2232,14 +2277,6 @@
"integrity": "sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==",
"dev": true
},
"combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"requires": {
"delayed-stream": "~1.0.0"
}
},
"commander": {
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
@@ -2297,11 +2334,6 @@
"safe-buffer": "~5.1.1"
}
},
"cookiejar": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz",
"integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA=="
},
"copy-concurrently": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz",
@@ -2638,11 +2670,6 @@
"integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=",
"dev": true
},
"delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
},
"des.js": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz",
@@ -3082,11 +3109,6 @@
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
},
"fast-safe-stringify": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz",
"integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA=="
},
"figgy-pudding": {
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz",
@@ -3158,21 +3180,6 @@
"resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
"integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA="
},
"form-data": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.0.tgz",
"integrity": "sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg==",
"requires": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
}
},
"formidable": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.2.tgz",
"integrity": "sha512-V8gLm+41I/8kguQ4/o1D3RIHRmhYFG4pnNyonvua+40rqcEmT4+V71yaZ3B457xbbgCsCfjSPi65u/W6vK1U5Q=="
},
"fragment-cache": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
@@ -3854,11 +3861,6 @@
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="
},
"methods": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
"integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
},
"micromatch": {
"version": "3.1.10",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
@@ -3895,24 +3897,6 @@
}
}
},
"mime": {
"version": "2.4.6",
"resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz",
"integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA=="
},
"mime-db": {
"version": "1.44.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz",
"integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg=="
},
"mime-types": {
"version": "2.1.27",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz",
"integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==",
"requires": {
"mime-db": "1.44.0"
}
},
"minimalistic-assert": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
@@ -5167,15 +5151,10 @@
}
}
},
"qs": {
"version": "6.9.4",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz",
"integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ=="
},
"query-string": {
"version": "6.13.5",
"resolved": "https://registry.npmjs.org/query-string/-/query-string-6.13.5.tgz",
"integrity": "sha512-svk3xg9qHR39P3JlHuD7g3nRnyay5mHbrPctEBDUxUkHRifPHXJDhBUycdCC0NBjXoDf44Gb+IsOZL1Uwn8M/Q==",
"version": "6.13.6",
"resolved": "https://registry.npmjs.org/query-string/-/query-string-6.13.6.tgz",
"integrity": "sha512-/WWZ7d9na6s2wMEGdVCVgKWE9Rt7nYyNIf7k8xmHXcesPMlEzicWo3lbYwHyA4wBktI2KrXxxZeACLbE84hvSQ==",
"requires": {
"decode-uri-component": "^0.2.0",
"split-on-first": "^1.0.0",
@@ -6018,41 +5997,6 @@
"resolved": "https://registry.npmjs.org/stylis-rule-sheet/-/stylis-rule-sheet-0.0.10.tgz",
"integrity": "sha512-nTbZoaqoBnmK+ptANthb10ZRZOGC+EmTLLUxeYIuHNkEKcmKgXX1XWKkUBT2Ac4es3NybooPe0SmvKdhKJZAuw=="
},
"superagent": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/superagent/-/superagent-5.3.1.tgz",
"integrity": "sha512-wjJ/MoTid2/RuGCOFtlacyGNxN9QLMgcpYLDQlWFIhhdJ93kNscFonGvrpAHSCVjRVj++DGCglocF7Aej1KHvQ==",
"requires": {
"component-emitter": "^1.3.0",
"cookiejar": "^2.1.2",
"debug": "^4.1.1",
"fast-safe-stringify": "^2.0.7",
"form-data": "^3.0.0",
"formidable": "^1.2.2",
"methods": "^1.1.2",
"mime": "^2.4.6",
"qs": "^6.9.4",
"readable-stream": "^3.6.0",
"semver": "^7.3.2"
},
"dependencies": {
"readable-stream": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
"requires": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
}
},
"semver": {
"version": "7.3.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
"integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ=="
}
}
},
"supports-color": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+1 -1
View File
@@ -7,7 +7,7 @@
"start": "next start"
},
"dependencies": {
"@supabase/supabase-js": "^0.36.5",
"@supabase/supabase-js": "github:kiwicopple/supabase-js#feature/migrate_to_typescript",
"next": "latest",
"react": "^16.13.1",
"react-dom": "^16.13.1"
+244
View File
@@ -0,0 +1,244 @@
/**
* Usage:
* ts-node docGen.ts -o {output_dir} {input}.yml
*/
import Example from './spec/gen/components/Example'
import Page from './spec/gen/components/Page'
import Sidebar from './spec/gen/components/Sidebar'
import SidebarCategory from './spec/gen/components/SidebarCategory'
import Tab from './spec/gen/components/Tab'
import Tabs from './spec/gen/components/Tabs'
import { slugify, tsDocCommentToMdComment, writeToDisk } from './spec/gen/lib/helpers'
import { TsDoc, OpenRef } from './spec/gen/definitions'
const yaml = require('js-yaml')
const fs = require('fs')
const main = (fileNames, options) => {
try {
const outputDir = options.o || options.output || ''
fileNames.forEach((inputFileName) => {
gen(inputFileName, outputDir)
})
return
} catch (e) {
console.log(e)
}
}
async function gen(inputFileName, outputDir) {
const docSpec = yaml.safeLoad(fs.readFileSync(inputFileName, 'utf8'))
const defRef = fs.readFileSync(docSpec.info.definition, 'utf8')
if (!defRef) return
const definition = JSON.parse(defRef)
const allLanguages = docSpec.info.libraries
const pages = Object.entries(docSpec.pages).map(([name, x]: [string, OpenRef.Page]) => ({
...x,
pageName: name,
}))
// Sidebar
const inputFileNameToSnakeCase = inputFileName.replace('/', '_').replace('.yml', '')
const sidebarFileName = `sidebar_${inputFileNameToSnakeCase}.js`
const sidebar = generateSidebar(docSpec)
await writeToDisk(sidebarFileName, sidebar)
console.log('Sidebar created: ', sidebarFileName)
// Index Page
const indexFilename = outputDir + `/index.mdx`
const index = generateDocsIndexPage(docSpec)
await writeToDisk(indexFilename, index)
console.log('The index was saved: ', indexFilename)
// Generate Pages
pages.forEach(async (pageSpec: OpenRef.Page) => {
try {
const slug = slugify(pageSpec.pageName)
const hasTsRef = pageSpec['$ref'] || null
const tsDefinition = hasTsRef && extractTsDocNode(hasTsRef, definition)
if (hasTsRef && !tsDefinition) throw new Error('Definition not found: ' + hasTsRef)
const description =
pageSpec.description || tsDocCommentToMdComment(getDescriptionFromDefintion(tsDefinition))
// Create page
const content = Page({
slug,
id: slug,
title: pageSpec.title || pageSpec.pageName,
description,
parameters: hasTsRef ? generateParameters(tsDefinition) : '',
spotlight: generateSpotlight(pageSpec['examples'] || [], allLanguages),
examples: generateExamples(pageSpec['examples'] || [], allLanguages),
notes: pageSpec.notes,
})
// Write to disk
const dest = outputDir + `/${slug}.mdx`
await writeToDisk(dest, content)
console.log('Saved: ', dest)
} catch (error) {
console.error(error)
}
})
}
function generateParameters(tsDefinition: any) {
let functionDeclaration = null
if (tsDefinition.kindString == 'Method') {
functionDeclaration = tsDefinition
} else if (tsDefinition.kindString == 'Constructor') {
functionDeclaration = tsDefinition
} else functionDeclaration = tsDefinition?.type?.declaration
if (!functionDeclaration) return ''
const paramDefinitions: TsDoc.TypeDefinition[] = functionDeclaration.signatures[0].parameters // PMC: seems flaky.. why the [0]?
if (!paramDefinitions) return ''
// const paramsComments: TsDoc.CommentTag = tsDefinition.comment?.tags?.filter(x => x.tag == 'param')
let parameters = paramDefinitions.map((x) => recurseThroughParams(x)).join(`\n`)
return methodListGroup(parameters)
}
function getDescriptionFromDefintion(tsDefinition) {
if (!tsDefinition) return null
if (['Method', 'Constructor', 'Constructor signature'].includes(tsDefinition.kindString))
return tsDefinition?.signatures[0].comment
else return tsDefinition?.comment || ''
}
function recurseThroughParams(paramDefinition: TsDoc.TypeDefinition) {
let children = paramDefinition.type?.declaration?.children
const labelParams = {
name: paramDefinition.name,
isOptional: !!paramDefinition.flags.isOptional,
type: extractParamTypeAsString(paramDefinition),
description: paramDefinition.comment ? tsDocCommentToMdComment(paramDefinition.comment) : null,
}
let subContent = ''
if (!!children) {
let properties = children
.sort((a, b) => (a.flags?.isOptional ? 1 : -1)) // required params first
.map((x) => recurseThroughParams(x))
let heading = `<h5 class="method-list-title method-list-title-isChild expanded">Properties</h5>`
subContent = methodListGroup([heading].concat(properties).join('\n'))
}
return methodListItemLabel(labelParams, subContent)
}
const methodListGroup = (items) => `
<ul className="method-list-group">
${items}
</ul>
`
const methodListItemLabel = ({ name, isOptional, type, description }, subContent) => `
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
${name}
</span>
<span className="method-list-item-label-badge ${!isOptional && 'required'}">
${isOptional ? 'optional' : 'required'}
</span>
<span className="method-list-item-validation">
${type}
</span>
</h4>
<div class="method-list-item-description">
${description ? description : 'No description provided. '}
</div>
${subContent}
</li>
`
function generateExamples(specExamples: any, allLanguages: any) {
return specExamples.map((example) => {
let allTabs = Tabs(allLanguages, generateTabs(allLanguages, example))
return Example({ name: example.name, description: example.description, tabs: allTabs })
})
}
/**
* A spotlight is an example which appears at the top of the page.
*/
function generateSpotlight(specExamples: any, allLanguages: any) {
const spotlight = specExamples.find((x) => x.isSpotlight) || null
const spotlightContent = !spotlight
? ''
: Tabs(allLanguages, generateTabs(allLanguages, spotlight))
return spotlightContent
}
function generateTabs(allLanguages: any, example: any) {
return allLanguages
.map((library) => {
let content = example[library.id] || notImplemented
return Tab(library.id, content)
})
.join('\n')
}
const notImplemented = `
\`\`\`
Not yet implemented
\`\`\`
`
function extractParamTypeAsString(paramDefinition) {
if (paramDefinition.type?.name) {
return paramDefinition.type.name
}
if (paramDefinition.type?.type == 'union') {
return paramDefinition.type.types.map((x) => x.value).join(' | ')
} else {
return 'object'
}
}
/**
* Iterates through the definition to find the correct definition.
* You can pass it a deeply nested node using dot notation. eg: 'LoggedInUser.data.email'
*/
function extractTsDocNode(nodeToFind: string, definition: any) {
const nodePath = nodeToFind.split('.')
let i = 0
let currentNode = definition
while (i < nodePath.length) {
currentNode = currentNode.children.find((x) => x.name == nodePath[i]) || null
if (currentNode == null) break
i++
}
return currentNode
}
function generateSidebar(docSpec: any) {
let path = docSpec.info.docs.path || ''
let categories = docSpec.info.docs.sidebar.map((x) => {
const items = x.items.map((item) => {
let slug = slugify(item)
return `'${path}${slug}'`
})
return SidebarCategory(x.name, items)
})
return Sidebar(categories)
}
function generateDocsIndexPage(docSpec: any) {
return Page({
slug: slugify(docSpec.info.title),
id: 'index',
title: docSpec.info.title,
description: docSpec.info.description,
})
}
// Run everything
const argv = require('minimist')(process.argv.slice(2))
main(argv['_'], argv)
+1 -1
View File
@@ -14,7 +14,7 @@ Whenever you create a new database in Postgres, you are actually [basing it off
<!--truncate-->
This database, `template1`, and another, called `template0`, are standard system databases that exist in every newly created database cluster. Don't believe me? Why not quickly [spin up a database](/docs/postgres/postgres-intro) and see it for yourself with this query:
This database, `template1`, and another, called `template0`, are standard system databases that exist in every newly created database cluster. Don't believe me? Why not quickly [spin up a database](/docs/postgres/server/about) and see it for yourself with this query:
```sql
SELECT * FROM pg_database;
```
+1 -1
View File
@@ -35,7 +35,7 @@ Supabase Auth provides all the backend services you need to authenticate and aut
### User management
Supabase makes it simple to onboard your users with our new `supabase.auth.signup()` and `supabase.auth.login()` [functions](/docs/library/user-management).
Supabase makes it simple to onboard your users with our new `supabase.auth.signup()` and `supabase.auth.login()` [functions](/docs/guides/auth).
<video width="99%" autoPlay="autoplay" loop muted playsInline controls="true">
<source src="/videos/auth-zoom2.mp4" type="video/mp4" loop muted playsInline />
+122
View File
@@ -0,0 +1,122 @@
---
title: Supabase.js 1.0.0
description: We're releasing a new version of our Supabase client with some awesome new improvements.
author: Paul Copplestone
author_title: Supabase
author_url: https://github.com/kiwicopple
author_image_url: https://avatars2.githubusercontent.com/u/10214025?s=400&u=c6775be2ae667e2acae3ccd347fed62bb3f5b3e7&v=4
authorURL: https://github.com/kiwicopple
# image: /img/supabase-september-2020.png
tags:
- supabase
---
Today we're releasing [supabase-js](https://github.com/supabase/supabase-js) version 1.0.0, and it comes with some major Developer Experience improvements.
<!--truncate-->
### New Docs
Before digging into the improvements, we're excited to point out our new [developer docs](http://localhost:3005/docs/client/supabase-client). While they're still a work in progress, here are some things we think you'll like:
- The [Reference Docs](/docs/client/supabase-client) are auto-generated from our Typescript definitions and then enriched with examples. This forces us to document our code and makes it easier to keep everything in sync.
- We added placeholders for the other languages that the community is developing. They have already started with Python, C#, Dart, Rust, and Swift. Expect to see the docs filling up soon!
- We've added sections for all of the open source tools we use, including [Postgres](/docs/postgres/server/about), [PostgREST](/docs/postgrest/server/about), [GoTrue](/docs/gotrue/server/about), and [Realtime](/docs/realtime/server/about). We'll be filling these with lots of valuable information including self-hosting, benchmarks, and simple guides.
### Errors are returned, not thrown
We attribute this improvement to community feedback. This has significantly improved the developer experience. Previously we would throw errors:
```js
try {
const { body } = supabase.from('todos').select('*')
}
catch (error) {
console.log(error)
}
```
And now we simply return them:
```js
const { data, error } = supabase.from('todos').select('*')
if (error) console.log(error)
// else, carry on ..
```
After testing this for a while we're very happy with this pattern. Errors are handled next to the offending function. Of course you can always rethrow the error if that's your preference.
### We created `gotrue-js`
Our goal for `supabase-js` is to tie together many sub-libaries. Each sub-library is a standalone implementation for a single external system. This is one of the ways we support existing open source tools.
To maintain this philosophy, we created [`gotrue-js`](https://github.com/supabase/goture-js), a library for Netlify's GoTrue auth server. This libary includes a number of new additions, including third-party logins.
Previously:
```js
const {
body: { user },
} = await supabase.auth.signup(
'someone@email.com',
'password'
)
```
Now:
```js
const { user, error } = await supabase.auth.signUp({
email: 'someone@email.com',
password: 'password'
})
```
### Enhancements and fixes
- Native Typescript. All of our libraries are now natively built with Typescript: [`supabase-js`](https://github.com/supabase/supabase-js), [`postgrest-js`](https://github.com/supabase/postgrest-js), [`gotrue-js`](https://github.com/supabase/gotrue-js), and [`realtime-js`](https://github.com/supabase/realtime-js).
- Better realtime scalability: we only generate one socket connection per Supabase client. Previously we would create a connection for every subscription.
- We've added support for OAuth providers.
- 60% of minor bugs outstanding for `supabase-js` have been [solved](https://github.com/supabase/supabase-js/pull/50).
- You can use `select()` instead of `select(*)`
### Breaking changes
We've bumped the major version because there are a number of breaking changes. We've detailed these in the [release notes](https://github.com/supabase/supabase-js/releases/tag/v1.0.0), but here are a few to be aware of:
- `signup()` is now `signUp()` and `email` / `password` is passed as an object
- `logout()` is now `signOut()`
- `login()` is now `signIn()`
- `ova()` and `ovr()` are now just `ov()`
- `body` is now `data`
Previously:
```js
const { body } = supabase.from('todos').select('*')
```
Now:
```js
const { data } = supabase.from('todos').select()
```
### Upgrading
There will be a number of tasks that you want to do when you upgrade:
1. Install the new version: `npm install @supabase/supabase-js@latest`
2. Update all your `body` constants to `data`
3. Update all your `supabase.auth` functions with the new [Auth interface](/docs/client/auth-signup)
### Get started
- Start using Supabase today: [app.supabase.io](https://app.supabase.io/)
- Make sure to [star us on GitHub](https://github.com/supabase/supabase)
- Follow us [on Twitter](https://twitter.com/supabase_io)
- Become a [sponsor](https://github.com/sponsors/supabase)
+225
View File
@@ -0,0 +1,225 @@
---
id: adj
title: ".adj()"
slug: adj
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Finds all rows whose range value on the stated `column` is adjacent to
the specified `range`.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('countries')
.select('name, id, population_range_millions')
.adj('population_range_millions', [70, 185])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
column
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
The column to filter on.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
range
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
string
</span>
</h4>
<div class="method-list-item-description">
The range to filter with.
</div>
</li>
</ul>
## Examples
### With `select()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('countries')
.select('name, id, population_range_millions')
.adj('population_range_millions', [70, 185])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `update()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('countries')
.update({ name: 'Mordor' })
.adj('population_range_millions', [70, 185])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `delete()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('countries')
.delete()
.adj('population_range_millions', [70, 185])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `rpc()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
// Only valid if the Stored Procedure returns a table type.
const { data, error } = await supabase
.rpc('echo_all_countries')
.adj('population_range_millions', [70, 185])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+39
View File
@@ -0,0 +1,39 @@
---
id: auth-forgotpassword
title: "auth.forgotPassword()"
slug: auth-forgotpassword
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Sends a reset request to an email address.
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
email
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
string
</span>
</h4>
<div class="method-list-item-description">
The email address of the user.
</div>
</li>
</ul>
+108
View File
@@ -0,0 +1,108 @@
---
id: auth-onauthstatechange
title: "auth.onAuthStateChange()"
slug: auth-onauthstatechange
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Receive a notification every time an auth event happens.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
supabase.auth.onAuthStateChange((event, session) => {
console.log(event, session)
})
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
callback
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
No description provided.
</div>
</li>
</ul>
## Examples
### Listen to auth changes
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
supabase.auth.onAuthStateChange((event, session) => {
console.log(event, session)
})
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+39
View File
@@ -0,0 +1,39 @@
---
id: auth-password-reset
title: "auth.password-reset"
slug: auth-password-reset
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Sends a reset request to an email address.
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
email
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
string
</span>
</h4>
<div class="method-list-item-description">
The email address of the user.
</div>
</li>
</ul>
+80
View File
@@ -0,0 +1,80 @@
---
id: auth-session
title: "auth.session()"
slug: auth-session
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Returns the session data, if there is an active session.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const session = supabase.auth.session()
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Examples
### Get the session data
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const session = supabase.auth.session()
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+211
View File
@@ -0,0 +1,211 @@
---
id: auth-signin
title: "auth.signIn()"
slug: auth-signin
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Log in an existing user, or login via a third-party provider.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { error, data } = await supabase.auth.signIn({
email: 'example@email.com',
password: 'example-password',
})
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
credentials
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
The user login details.
</div>
<ul className="method-list-group">
<h5 class="method-list-title method-list-title-isChild expanded">Properties</h5>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
provider
</span>
<span className="method-list-item-label-badge false">
optional
</span>
<span className="method-list-item-validation">
Provider
</span>
</h4>
<div class="method-list-item-description">
One of the providers supported by GoTrue.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
password
</span>
<span className="method-list-item-label-badge false">
optional
</span>
<span className="method-list-item-validation">
|
</span>
</h4>
<div class="method-list-item-description">
The user's password.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
email
</span>
<span className="method-list-item-label-badge false">
optional
</span>
<span className="method-list-item-validation">
|
</span>
</h4>
<div class="method-list-item-description">
The user's email address.
</div>
</li>
</ul>
</li>
</ul>
## 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.
- Specifying a `provider` will open the browser to the relevant login page.
## Examples
### Sign in
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { error, data } = await supabase.auth.signIn({
email: 'example@email.com',
password: 'example-password',
})
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### Sign in using third-party providers.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { user, error } = await supabase.auth.signIn({
// provider can be 'github', 'google', 'gitlab', or 'bitbucket'
provider: 'github'
})
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+80
View File
@@ -0,0 +1,80 @@
---
id: auth-signout
title: "auth.signOut()"
slug: auth-signout
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Signs out the current user, if there is a logged in user.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { error, data } = supabase.signOut()
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Examples
### Sign out
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { error, data } = supabase.signOut()
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+156
View File
@@ -0,0 +1,156 @@
---
id: auth-signup
title: "auth.signUp()"
slug: auth-signup
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Creates a new user.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { error, data } = await supabase.auth.signUp({
email: 'example@email.com',
password: 'example-password',
})
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
credentials
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
The user login details.
</div>
<ul className="method-list-group">
<h5 class="method-list-title method-list-title-isChild expanded">Properties</h5>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
email
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
string
</span>
</h4>
<div class="method-list-item-description">
The user's email address.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
password
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
string
</span>
</h4>
<div class="method-list-item-description">
The user's password.
</div>
</li>
</ul>
</li>
</ul>
## Examples
### Sign up
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { error, data } = await supabase.auth.signUp({
email: 'example@email.com',
password: 'example-password',
})
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+110
View File
@@ -0,0 +1,110 @@
---
id: auth-update
title: "auth.update()"
slug: auth-update
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Updates user data, if there is a logged in user.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { user, error } = await supabase.auth.update({
data: { hello: 'world' }
})
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
attributes
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
UserAttributes
</span>
</h4>
<div class="method-list-item-description">
No description provided.
</div>
</li>
</ul>
## 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.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { user, error } = await supabase.auth.update({
data: { hello: 'world' }
})
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+80
View File
@@ -0,0 +1,80 @@
---
id: auth-user
title: "auth.user()"
slug: auth-user
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Returns the user data, if there is a logged in user.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const user = supabase.auth.user()
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Examples
### Get the logged in user
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const user = supabase.auth.user()
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+225
View File
@@ -0,0 +1,225 @@
---
id: cd
title: ".cd()"
slug: cd
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Finds all rows whose json, array, or range value on the stated `column` is
contained by the specified `value`.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('countries')
.select('name, id, main_exports')
.cd('main_exports', ['cars', 'food', 'machine'])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
column
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
The column to filter on.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
value
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
| |
</span>
</h4>
<div class="method-list-item-description">
The value to filter with.
</div>
</li>
</ul>
## Examples
### With `select()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('countries')
.select('name, id, main_exports')
.cd('main_exports', ['cars', 'food', 'machine'])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `update()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('countries')
.update({ name: 'Mordor' })
.cd('main_exports', ['orks', 'surveillance', 'evil'])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `delete()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('countries')
.delete()
.cd('main_exports', ['cars', 'food', 'machine'])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `rpc()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
// Only valid if the Stored Procedure returns a table type.
const { data, error } = await supabase
.rpc('echo_all_countries')
.cd('main_exports', ['cars', 'food', 'machine'])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+225
View File
@@ -0,0 +1,225 @@
---
id: cs
title: ".cs()"
slug: cs
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Finds all rows whose json, array, or range value on the stated `column`
contains the values specified in `value`.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('countries')
.select('name, id, main_exports')
.cs('main_exports', ['oil'])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
column
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
The column to filter on.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
value
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
| |
</span>
</h4>
<div class="method-list-item-description">
The value to filter with.
</div>
</li>
</ul>
## Examples
### With `select()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('countries')
.select('name, id, main_exports')
.cs('main_exports', ['oil'])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `update()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('countries')
.update({ name: 'Mordor' })
.cs('main_exports', ['oil'])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `delete()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('countries')
.delete()
.cs('main_exports', ['oil'])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `rpc()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
// Only valid if the Stored Procedure returns a table type.
const { data, error } = await supabase
.rpc('echo_all_countries')
.cs('main_exports', ['oil'])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+87
View File
@@ -0,0 +1,87 @@
---
id: delete
title: "Delete data: delete()"
slug: delete
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Performs a DELETE on the table.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.delete()
.match({ id: 666 })
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Notes
- `delete()` should always be combined with [Filters](/docs/client/using-filters) to target the item(s) you wish to delete.
## Examples
### Delete records
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.delete()
.match({ id: 666 })
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+225
View File
@@ -0,0 +1,225 @@
---
id: eq
title: ".eq()"
slug: eq
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Finds all rows whose value on the stated `column` exactly matches the
specified `value`.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.select('name, country_id')
.eq('name', 'The shire')
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
column
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
The column to filter on.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
value
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
The value to filter with.
</div>
</li>
</ul>
## Examples
### With `select()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.select('name, country_id')
.eq('name', 'The shire')
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `update()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.update({ name: 'Mordor' })
.eq('name', 'San Francisco')
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `delete()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.delete()
.eq('name', 'Mordor')
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `rpc()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
// Only valid if the Stored Procedure returns a table type.
const { data, error } = await supabase
.rpc('echo_all_cities')
.eq('name', 'San Francisco')
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+278
View File
@@ -0,0 +1,278 @@
---
id: filter
title: ".filter()"
slug: filter
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Finds all rows whose `column` satisfies the filter.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.select('name, country_id')
.filter('name', 'eq', 'Paris')
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
column
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
The column to filter on.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
operator
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
FilterOperator
</span>
</h4>
<div class="method-list-item-description">
The operator to filter with.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
value
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
any
</span>
</h4>
<div class="method-list-item-description">
The value to filter with.
</div>
</li>
</ul>
## Examples
### With `select()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.select('name, country_id')
.filter('name', 'eq', 'Paris')
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `update()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.update({ name: 'Mordor' })
.filter('name', 'eq', 'Paris')
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `delete()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.delete()
.filter({'name', 'eq', 'Paris'})
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `rpc()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
// Only valid if the Stored Procedure returns a table type.
const { data, error } = await supabase
.rpc('echo_all_cities')
.filter({'name', 'eq', 'Paris'})
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### Filter embedded resources
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
export const getFilterJsEmbedded = `
const { data, error } = await supabase
.from('cities')
.select('name, countries ( name )')
.filter('countries.name', 'eq', 'France')
`.trim()
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+107
View File
@@ -0,0 +1,107 @@
---
id: fts
title: ".fts()"
slug: fts
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Finds all rows whose tsvector value on the stated `column` matches
to_tsquery(`query`).
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
column
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
The column to filter on.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
query
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
string
</span>
</h4>
<div class="method-list-item-description">
The Postgres tsquery string to filter with.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
__namedParameters
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
No description provided.
</div>
<ul className="method-list-group">
<h5 class="method-list-title method-list-title-isChild expanded">Properties</h5>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
config
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
|
</span>
</h4>
<div class="method-list-item-description">
The text search configuration to use.
</div>
</li>
</ul>
</li>
</ul>
+8 -54
View File
@@ -1,33 +1,17 @@
---
id: getting-started
title: Getting Started
description: 'How to install Supabase and start interacting with your database'
id: generating-types
title: "Generating Types"
slug: generating-types
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
## Installing
```bash
npm install --save @supabase/supabase-js
# OR
yarn add @supabase/supabase-js
```
## Initializing
```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");
```
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 autocomplete and documentation in your editor.
`supabase-js` ships with type definitions for usage with TypeScript and for convenient IntelliSense autocomplete 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 autocompletion support down the chain.
If you don't provide a type for the row you need to explicitly pass `from<any>('tableName')`.
@@ -93,34 +77,4 @@ export default async (req: NextApiRequest, res: NextApiResponse) => {
.eq("status", "ONLINE");
res.status(200).json(allOnlineUsers);
};
```
## Reference
### `createClient()`
```js
createClient('supabaseURL', 'supabaseKey', OPTIONS)
```
#### `supabaseURL: string`
The unique Supabase URL which is supplied when you create a new project in [your project dashboard](https://app.supabase.io).
#### `supabaseKey: string`
The unique Supabase Key which is supplied when you create a new project in [your project dashboard](https://app.supabase.io).
#### `OPTIONS: object?`
```js
/**
* @param {string} [schema='public']
* You can switch in between schemas.
* The schema however would need to be on the list of exposed schemas.
* Defaults to the 'public' schema.
* If there is the need to use more than one schema,
* another instance of .createClient() would need to be instantiated.
*/
const options = {
schema: 'public'
}
```
```
+80
View File
@@ -0,0 +1,80 @@
---
id: getsubscriptions
title: "getSubscriptions()"
slug: getsubscriptions
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Returns an array of all your subscriptions.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const subscriptions = supabase.getSubscriptions()
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Examples
### Remove a subscription
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const subscriptions = supabase.getSubscriptions()
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+225
View File
@@ -0,0 +1,225 @@
---
id: gt
title: ".gt()"
slug: gt
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Finds all rows whose value on the stated `column` is greater than the
specified `value`.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.select('name, country_id')
.gt('country_id', 250)
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
column
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
The column to filter on.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
value
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
The value to filter with.
</div>
</li>
</ul>
## Examples
### With `select()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.select('name, country_id')
.gt('country_id', 250)
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `update()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.update({ name: 'Mordor' })
.gt('country_id', 250)
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `delete()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.delete()
.gt('country_id', 250)
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `rpc()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
// Only valid if the Stored Procedure returns a table type.
const { data, error } = await supabase
.rpc('echo_all_cities')
.gt('country_id', 250)
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+225
View File
@@ -0,0 +1,225 @@
---
id: gte
title: ".gte()"
slug: gte
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Finds all rows whose value on the stated `column` is greater than or
equal to the specified `value`.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.select('name, country_id')
.gte('country_id', 250)
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
column
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
The column to filter on.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
value
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
The value to filter with.
</div>
</li>
</ul>
## Examples
### With `select()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.select('name, country_id')
.gte('country_id', 250)
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `update()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.update({ name: 'Mordor' })
.gte('country_id', 250)
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `delete()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.delete()
.gte('country_id', 250)
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `rpc()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
// Only valid if the Stored Procedure returns a table type.
const { data, error } = await supabase
.rpc('echo_all_cities')
.gte('country_id', 250)
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+225
View File
@@ -0,0 +1,225 @@
---
id: ilike
title: ".ilike()"
slug: ilike
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Finds all rows whose value in the stated `column` matches the supplied
`pattern` (case insensitive).
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.select('name, country_id')
.ilike('name', '%la%')
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
column
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
The column to filter on.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
pattern
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
string
</span>
</h4>
<div class="method-list-item-description">
The pattern to filter with.
</div>
</li>
</ul>
## Examples
### With `select()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.select('name, country_id')
.ilike('name', '%la%')
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `update()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.update({ name: 'Mordor' })
.ilike('name', '%la%')
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `delete()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.delete()
.ilike('name', '%la%')
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `rpc()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
// Only valid if the Stored Procedure returns a table type.
const { data, error } = await supabase
.rpc('echo_all_cities')
.ilike('name', '%la%')
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+225
View File
@@ -0,0 +1,225 @@
---
id: in
title: ".in()"
slug: in
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Finds all rows whose value on the stated `column` is found on the
specified `values`.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.select('name, country_id')
.in('name', ['Rio de Janeiro', 'San Francisco'])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
column
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
The column to filter on.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
values
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
The values to filter with.
</div>
</li>
</ul>
## Examples
### With `select()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.select('name, country_id')
.in('name', ['Rio de Janeiro', 'San Francisco'])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `update()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.update({ name: 'Mordor' })
.in('name', ['Rio de Janeiro', 'San Francisco'])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `delete()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.delete()
.in('name', ['Rio de Janeiro', 'San Francisco'])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `rpc()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
// Only valid if the Stored Procedure returns a table type.
const { data, error } = await supabase
.rpc('echo_all_cities')
.in('name', ['Rio de Janeiro', 'San Francisco'])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+19
View File
@@ -0,0 +1,19 @@
---
id: index
title: "Supabase Client"
slug: supabase-client
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Our client library is modular. Each sub-library is a standalone implementation for a single external system. This is one of the ways we support existing tools.
| Repo | Official | Community |
|-----------------------|--------------------------------------------------|------------------|
| **`supabase-{lang}`** <br /> Combines libraries and adds enrichments. | [`JavaScript`](https://github.com/supabase/supabase-js) | [`C#`](https://github.com/supabase/supabase-csharp), [`Python`](https://github.com/supabase/supabase-py), `Rust` |
| `postgrest-{lang}` <br /> Client library to work with [PostgREST](https://github.com/postgrest/postgrest) | [`JavaScript`](https://github.com/supabase/postgrest-js) | [`C#`](https://github.com/supabase/postgrest-csharp), [`Python`](https://github.com/supabase/postgrest-py), [`Rust`](https://github.com/supabase/postgrest-rs) |
| `realtime-{lang}` <br /> Client library to work with [Realtime](https://github.com/supabase/realtime) | [`JavaScript`](https://github.com/supabase/realtime-js) | `C#`, `Python`, `Rust` |
| `gotrue-{lang}` <br /> Client library to work with [GoTrue](https://github.com/netlify/gotrue) | [`JavaScript`](https://github.com/supabase/gotrue-js) | `C#`, `Python`, `Rust` |
+159
View File
@@ -0,0 +1,159 @@
---
id: initializing
title: "Initializing"
slug: initializing
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
You can initialize a new Supabase client using the `createClient()` method.
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
supabaseUrl
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
string
</span>
</h4>
<div class="method-list-item-description">
The unique Supabase URL which is supplied when you create a new project in your project dashboard.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
supabaseKey
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
string
</span>
</h4>
<div class="method-list-item-description">
The unique Supabase Key which is supplied when you create a new project in your project dashboard.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
options
</span>
<span className="method-list-item-label-badge false">
optional
</span>
<span className="method-list-item-validation">
SupabaseClientOptions
</span>
</h4>
<div class="method-list-item-description">
No description provided.
</div>
</li>
</ul>
## Examples
### createClient()
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```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")
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With additional parameters
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
import { createClient } from '@supabase/supabase-js'
const options = { }
const supabase = createClient("https://xyzcompany.supabase.co", "public-anon-key", options)
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+253
View File
@@ -0,0 +1,253 @@
---
id: insert
title: "Create data: insert()"
slug: insert
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Performs an INSERT into the table.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.insert([
{ name: 'The Shire', country_id: 554 }
])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
values
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
|
</span>
</h4>
<div class="method-list-item-description">
The values to insert.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
__namedParameters
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
No description provided.
</div>
<ul className="method-list-group">
<h5 class="method-list-title method-list-title-isChild expanded">Properties</h5>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
onConflict
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
|
</span>
</h4>
<div class="method-list-item-description">
By specifying the `on_conflict` query parameter, you can make UPSERT work on a column(s) that has a UNIQUE constraint.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
upsert
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
boolean
</span>
</h4>
<div class="method-list-item-description">
If `true`, performs an UPSERT.
</div>
</li>
</ul>
</li>
</ul>
## Examples
### Create a record
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.insert([
{ name: 'The Shire', country_id: 554 }
])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### Bulk create
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.insert([
{ name: 'The Shire', country_id: 554 },
{ name: 'Rohan', country_id: 555 },
])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### 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.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```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 })
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+25
View File
@@ -0,0 +1,25 @@
---
id: installing
title: "Installing"
slug: installing
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
All JavaScript libraries are built directly by the Supabase team.
Other languages are built by the community and supported by Supabase.
## Javascript
```bash
npm install @supabase/postgrest-js
```
Find the source code on [GitHub](https://github.com/supabase/postgrest-js).
## Python
```bash
# Not yet implemented
+225
View File
@@ -0,0 +1,225 @@
---
id: is
title: ".is()"
slug: is
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
A check for exact equality (null, true, false), finds all rows whose
value on the stated `column` exactly match the specified `value`.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.select('name, country_id')
.is('name', null)
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
column
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
The column to filter on.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
value
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
|
</span>
</h4>
<div class="method-list-item-description">
The value to filter with.
</div>
</li>
</ul>
## Examples
### With `select()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.select('name, country_id')
.is('name', null)
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `update()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.update({ name: 'Mordor' })
.is('name', null)
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `delete()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.delete()
.is('name', null)
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `rpc()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
// Only valid if the Stored Procedure returns a table type.
const { data, error } = await supabase
.rpc('echo_all_cities')
.is('name', null)
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+225
View File
@@ -0,0 +1,225 @@
---
id: like
title: ".like()"
slug: like
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Finds all rows whose value in the stated `column` matches the supplied
`pattern` (case sensitive).
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.select('name, country_id')
.like('name', '%la%')
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
column
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
The column to filter on.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
pattern
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
string
</span>
</h4>
<div class="method-list-item-description">
The pattern to filter with.
</div>
</li>
</ul>
## Examples
### With `select()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.select('name, country_id')
.like('name', '%la%')
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `update()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.update({ name: 'Mordor' })
.like('name', '%la%')
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `delete()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.delete()
.like('name', '%la%')
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `rpc()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
// Only valid if the Stored Procedure returns a table type.
const { data, error } = await supabase
.rpc('echo_all_cities')
.like('name', '%la%')
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+188
View File
@@ -0,0 +1,188 @@
---
id: limit
title: "limit()"
slug: limit
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Limits the result with the specified `count`.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.select('name, country_id')
.limit(1)
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
count
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
number
</span>
</h4>
<div class="method-list-item-description">
The maximum no. of rows to limit to.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
__namedParameters
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
No description provided.
</div>
<ul className="method-list-group">
<h5 class="method-list-title method-list-title-isChild expanded">Properties</h5>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
foreignTable
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
|
</span>
</h4>
<div class="method-list-item-description">
The foreign table to use (for foreign columns).
</div>
</li>
</ul>
</li>
</ul>
## Examples
### With `select()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.select('name, country_id')
.limit(1)
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With embedded resources
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.select('name, cities(name)')
.eq('name', 'United States')
.limit(1, 'cities')
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+225
View File
@@ -0,0 +1,225 @@
---
id: lt
title: ".lt()"
slug: lt
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Finds all rows whose value on the stated `column` is less than the
specified `value`.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.select('name, country_id')
.lt('country_id', 250)
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
column
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
The column to filter on.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
value
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
The value to filter with.
</div>
</li>
</ul>
## Examples
### With `select()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.select('name, country_id')
.lt('country_id', 250)
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `update()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.update({ name: 'Mordor' })
.lt('country_id', 250)
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `delete()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.delete()
.lt('country_id', 250)
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `rpc()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
// Only valid if the Stored Procedure returns a table type.
const { data, error } = await supabase
.rpc('echo_all_cities')
.lt('country_id', 250)
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+225
View File
@@ -0,0 +1,225 @@
---
id: lte
title: ".lte()"
slug: lte
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Finds all rows whose value on the stated `column` is less than or equal
to the specified `value`.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.select('name, country_id')
.lte('country_id', 250)
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
column
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
The column to filter on.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
value
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
The value to filter with.
</div>
</li>
</ul>
## Examples
### With `select()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.select('name, country_id')
.lte('country_id', 250)
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `update()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.update({ name: 'Mordor' })
.lte('country_id', 250)
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `delete()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.delete()
.lte('country_id', 250)
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `rpc()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
// Only valid if the Stored Procedure returns a table type.
const { data, error } = await supabase
.rpc('echo_all_cities')
.lte('country_id', 250)
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+204
View File
@@ -0,0 +1,204 @@
---
id: match
title: ".match()"
slug: match
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Finds all rows whose columns match the specified `query` object.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.select('name, country_id')
.match({name: 'Beijing', country_id: 156})
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
query
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
The object to filter with, with column names as keys mapped
to their filter values.
</div>
</li>
</ul>
## Examples
### With `select()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.select('name, country_id')
.match({name: 'Beijing', country_id: 156})
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `update()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.update({ name: 'Mordor' })
.match({name: 'Beijing', country_id: 156})
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `delete()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.delete()
.match({name: 'Beijing', country_id: 156})
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `rpc()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
// Only valid if the Stored Procedure returns a table type.
const { data, error } = await supabase
.rpc('echo_all_cities')
.match({name: 'Beijing', country_id: 156})
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+225
View File
@@ -0,0 +1,225 @@
---
id: neq
title: ".neq()"
slug: neq
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Finds all rows whose value on the stated `column` doesn't match the
specified `value`.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.select('name, country_id')
.neq('name', 'The shire')
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
column
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
The column to filter on.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
value
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
The value to filter with.
</div>
</li>
</ul>
## Examples
### With `select()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.select('name, country_id')
.neq('name', 'The shire')
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `update()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.update({ name: 'Mordor' })
.neq('name', 'San Francisco')
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `delete()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.delete()
.neq('name', 'Mordor')
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `rpc()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
// Only valid if the Stored Procedure returns a table type.
const { data, error } = await supabase
.rpc('echo_all_cities')
.neq('name', 'Lagos')
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+245
View File
@@ -0,0 +1,245 @@
---
id: not
title: ".not()"
slug: not
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Finds all rows which doesn't satisfy the filter.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.select('name, country_id')
.not('name', 'eq', 'Paris')
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
column
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
The column to filter on.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
operator
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
FilterOperator
</span>
</h4>
<div class="method-list-item-description">
The operator to filter with.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
value
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
any
</span>
</h4>
<div class="method-list-item-description">
The value to filter with.
</div>
</li>
</ul>
## Examples
### With `select()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.select('name, country_id')
.not('name', 'eq', 'Paris')
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `update()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.update({ name: 'Mordor' })
.not('name', 'eq', 'Paris')
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `delete()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.delete()
.not('name', 'eq', 'Paris')
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `rpc()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
// Only valid if the Stored Procedure returns a table type.
const { data, error } = await supabase
.rpc('echo_all_cities)
.not('name', 'eq', 'Paris')
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+225
View File
@@ -0,0 +1,225 @@
---
id: nxl
title: ".nxl()"
slug: nxl
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Finds all rows whose range value on the stated `column` does not extend
to the left of the specified `range`.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('countries')
.select('name, id, population_range_millions')
.nxl('population_range_millions', [150, 250])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
column
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
The column to filter on.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
range
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
string
</span>
</h4>
<div class="method-list-item-description">
The range to filter with.
</div>
</li>
</ul>
## Examples
### With `select()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('countries')
.select('name, id, population_range_millions')
.nxl('population_range_millions', [150, 250])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `update()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('countries')
.update({ name: 'Mordor' })
.nxl('population_range_millions', [150, 250])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `delete()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('countries')
.delete()
.nxl('population_range_millions', [150, 250])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `rpc()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
// Only valid if the Stored Procedure returns a table type.
const { data, error } = await supabase
.rpc('echo_all_countries')
.nxl('population_range_millions', [150, 250])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+225
View File
@@ -0,0 +1,225 @@
---
id: nxr
title: ".nxr()"
slug: nxr
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Finds all rows whose range value on the stated `column` does not extend
to the right of the specified `range`.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('countries')
.select('name, id, population_range_millions')
.nxr('population_range_millions', [150, 250])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
column
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
The column to filter on.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
range
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
string
</span>
</h4>
<div class="method-list-item-description">
The range to filter with.
</div>
</li>
</ul>
## Examples
### With `select()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('countries')
.select('name, id, population_range_millions')
.nxr('population_range_millions', [150, 250])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `update()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('countries')
.update({ name: 'Mordor' })
.nxr('population_range_millions', [150, 250])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `delete()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('countries')
.delete()
.nxr('population_range_millions', [150, 250])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `rpc()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
// Only valid if the Stored Procedure returns a table type.
const { data, error } = await supabase
.rpc('echo_all_countries')
.nxr('population_range_millions', [150, 250])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+293
View File
@@ -0,0 +1,293 @@
---
id: on
title: "Subscribing: on()"
slug: on
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Subscribe to realtime changes in your databse.
<Tabs
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const mySubscription = supabase
.from('*')
.on('*', payload => {
console.log('Change received!', payload)
})
.subscribe()
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
event
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
INSERT | UPDATE | DELETE | *
</span>
</h4>
<div class="method-list-item-description">
The database event which you would like to receive updates for, or you can use the special wildcard `*` to listen to all changes.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
callback
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
A callback that will handle the payload that is sent whenever your database changes.
</div>
</li>
</ul>
## Notes
- 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
<Tabs
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const mySubscription = supabase
.from('*')
.on('*', payload => {
console.log('Change received!', payload)
})
.subscribe()
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### Listening to a specific table
<Tabs
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const mySubscription = supabase
.from('countries')
.on('*', payload => {
console.log('Change received!', payload)
})
.subscribe()
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### Listening to inserts
<Tabs
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const mySubscription = supabase
.from('countries')
.on('INSERT', payload => {
console.log('Change received!', payload)
})
.subscribe()
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### Listening to updates
<Tabs
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const mySubscription = supabase
.from('countries')
.on('UPDATE', payload => {
console.log('Change received!', payload)
})
.subscribe()
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### Listening to deletes
<Tabs
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const mySubscription = supabase
.from('countries')
.on('DELETE', payload => {
console.log('Change received!', payload)
})
.subscribe()
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### Listening to multiple events
You can chain listeners if you want to listen to multiple events for each table.
<Tabs
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const mySubscription = supabase
.from('countries')
.on('INSERT', handleRecordInserted)
.on('DELETE', handleRecordDeleted)
.subscribe()
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+141
View File
@@ -0,0 +1,141 @@
---
id: or
title: ".or()"
slug: or
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Finds all rows satisfying at least one of the filters.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.select('name, country_id')
.or('id.eq.20,id.eq.30')
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
filters
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
string
</span>
</h4>
<div class="method-list-item-description">
The filters to use, separated by commas.
</div>
</li>
</ul>
## Examples
### With `select()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.select('name, country_id')
.or('id.eq.20,id.eq.30')
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### User `or` with `and`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.select('name, country_id')
.or('id.gt.20,and(name.eq.New Zealand,name.eq.France)')
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+230
View File
@@ -0,0 +1,230 @@
---
id: order
title: "order()"
slug: order
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Orders the result with the specified `column`.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.select('name', 'country_id')
.order('id')
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
column
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
The column to order on.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
__namedParameters
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
No description provided.
</div>
<ul className="method-list-group">
<h5 class="method-list-title method-list-title-isChild expanded">Properties</h5>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
ascending
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
boolean
</span>
</h4>
<div class="method-list-item-description">
If `true`, the result will be in ascending order.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
foreignTable
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
|
</span>
</h4>
<div class="method-list-item-description">
The foreign table to use (if `column` is a foreign column).
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
nullsFirst
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
boolean
</span>
</h4>
<div class="method-list-item-description">
If `true`, `null`s appear first.
</div>
</li>
</ul>
</li>
</ul>
## Examples
### With `select()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.select('name', 'country_id')
.order('id')
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With embedded resources
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('countries')
.select('name, cities(name)')
.eq('name', 'United States')
.order('cities.name')
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+225
View File
@@ -0,0 +1,225 @@
---
id: ov
title: ".ov()"
slug: ov
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Finds all rows whose array or range value on the stated `column` is
contained by the specified `value`.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('countries')
.select('name, id, main_exports')
.ova('main_exports', ['computers', 'minerals'])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
column
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
The column to filter on.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
value
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
|
</span>
</h4>
<div class="method-list-item-description">
The value to filter with.
</div>
</li>
</ul>
## Examples
### With `select()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('countries')
.select('name, id, main_exports')
.ova('main_exports', ['computers', 'minerals'])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `update()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
let countries = await supabase
.from('countries')
.update({ name: 'Mordor' })
.ova('main_exports', ['computers', 'minerals'])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `delete()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('countries')
.delete()
.ova('main_exports', ['computers', 'minerals'])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `rpc()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
// Only valid if the Stored Procedure returns a table type.
const { data, error } = await supabase
.rpc('echo_all_countries')
.ova('main_exports', ['computers', 'minerals'])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+107
View File
@@ -0,0 +1,107 @@
---
id: phfts
title: ".phfts()"
slug: phfts
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Finds all rows whose tsvector value on the stated `column` matches
phraseto_tsquery(`query`).
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
column
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
The column to filter on.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
query
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
string
</span>
</h4>
<div class="method-list-item-description">
The Postgres tsquery string to filter with.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
__namedParameters
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
No description provided.
</div>
<ul className="method-list-group">
<h5 class="method-list-title method-list-title-isChild expanded">Properties</h5>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
config
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
|
</span>
</h4>
<div class="method-list-item-description">
The text search configuration to use.
</div>
</li>
</ul>
</li>
</ul>
+107
View File
@@ -0,0 +1,107 @@
---
id: plfts
title: ".plfts()"
slug: plfts
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Finds all rows whose tsvector value on the stated `column` matches
plainto_tsquery(`query`).
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
column
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
The column to filter on.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
query
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
string
</span>
</h4>
<div class="method-list-item-description">
The Postgres tsquery string to filter with.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
__namedParameters
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
No description provided.
</div>
<ul className="method-list-group">
<h5 class="method-list-title method-list-title-isChild expanded">Properties</h5>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
config
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
|
</span>
</h4>
<div class="method-list-item-description">
The text search configuration to use.
</div>
</li>
</ul>
</li>
</ul>
+177
View File
@@ -0,0 +1,177 @@
---
id: range
title: "range()"
slug: range
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Limits the result to rows within the specified range, inclusive.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.select('name, country_id')
.range(0,3)
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
from
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
number
</span>
</h4>
<div class="method-list-item-description">
The starting index from which to limit the result, inclusive.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
to
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
number
</span>
</h4>
<div class="method-list-item-description">
The last index to which to limit the result, inclusive.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
__namedParameters
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
No description provided.
</div>
<ul className="method-list-group">
<h5 class="method-list-title method-list-title-isChild expanded">Properties</h5>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
foreignTable
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
|
</span>
</h4>
<div class="method-list-item-description">
The foreign table to use (for foreign columns).
</div>
</li>
</ul>
</li>
</ul>
## Examples
### With `select()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.select('name, country_id')
.range(0,3)
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+104
View File
@@ -0,0 +1,104 @@
---
id: removesubscription
title: "removeSubscription()"
slug: removesubscription
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Removes an active subscription and returns the number of open connections.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
supabase.removeSubscription(mySubscription)
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
subscription
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
RealtimeSubscription
</span>
</h4>
<div class="method-list-item-description">
The subscription you want to remove.
</div>
</li>
</ul>
## Examples
### Remove a subscription
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
supabase.removeSubscription(mySubscription)
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+104
View File
@@ -0,0 +1,104 @@
---
id: reset-password-email
title: "Reset Password (Email)"
slug: reset-password-email
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Sends a reset request to an email address.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = supabase.auth.api.resetPasswordForEmail('user@email.com')
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
email
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
string
</span>
</h4>
<div class="method-list-item-description">
The email address of the user.
</div>
</li>
</ul>
## Examples
### Reset password
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = supabase.auth.api.resetPasswordForEmail('user@email.com')
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+229
View File
@@ -0,0 +1,229 @@
---
id: rpc
title: "Stored Procedures: rpc()"
slug: rpc
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
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.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.rpc('hello_world')
}
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
fn
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
string
</span>
</h4>
<div class="method-list-item-description">
The function name to call.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
params
</span>
<span className="method-list-item-label-badge false">
optional
</span>
<span className="method-list-item-validation">
|
</span>
</h4>
<div class="method-list-item-description">
The parameters to pass to the function call.
</div>
</li>
</ul>
## Examples
### Call a stored procedure
This is an example invoking a stored procedure.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.rpc('hello_world')
}
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With Parameters
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.rpc('echo_city', { name: 'The Shire' })
}
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### Bulk call
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.rpc('echo_city', [
{ name: 'The Shire' },
{ name: 'Mordor' }
])
}
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With filters.
Stored procedures that return tables can also be combined with
[Modifiers](/docs/client/using-modifiers) and
[Filters](/docs/client/using-filters).
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.rpc('echo_all_cities')
.eq('name', 'The Shire')
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+254
View File
@@ -0,0 +1,254 @@
---
id: select
title: "Fetch data: select()"
slug: select
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Performs horizontal filtering with SELECT.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.select()
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
columns
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
string
</span>
</h4>
<div class="method-list-item-description">
The columns to retrieve, separated by commas.
</div>
</li>
</ul>
## Notes
- `select()` can be combined with [Modifiers](/docs/client/using-modifiers)
- `select()` can be combined with [Filters](/docs/client/using-filters)
## Examples
### Getting your data
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.select()
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### Selecting specific columns
You can select specific fields from your tables.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.select('name')
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### Query foreign tables
If your database has relationships, you can query related tables too.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('countries')
.select(`
name,
cities (
name
)
`)
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### 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:
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('products')
.select(`
id,
supplier:supplier_id ( name ),
purchaser:purchaser_id ( name )
`)
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### Quering 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/9.5/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.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('products')
.select(`
id,
supplier:supplier_id ( name ),
purchaser:purchaser_id ( name )
`)
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+87
View File
@@ -0,0 +1,87 @@
---
id: single
title: "single()"
slug: single
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Retrieves only one row from the result. Result must be one row (e.g. using
`limit`), otherwise this will result in an error.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.select('name, country_id')
.single()
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Examples
### With `select()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.select('name, country_id')
.single()
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+225
View File
@@ -0,0 +1,225 @@
---
id: sl
title: ".sl()"
slug: sl
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Finds all rows whose range value on the stated `column` is strictly to the
left of the specified `range`.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('countries')
.select('name, id, population_range_millions')
.sl('population_range_millions', [150, 250])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
column
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
The column to filter on.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
range
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
string
</span>
</h4>
<div class="method-list-item-description">
The range to filter with.
</div>
</li>
</ul>
## Examples
### With `select()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('countries')
.select('name, id, population_range_millions')
.sl('population_range_millions', [150, 250])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `update()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('countries')
.update({ name: 'Mordor' })
.sl('population_range_millions', [150, 250])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `delete()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('countries')
.delete()
.sl('population_range_millions', [150, 250])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `rpc()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
// Only valid if the Stored Procedure returns a table type.
const { data, error } = await supabase
.rpc('echo_all_countries')
.sl('population_range_millions', [150, 250])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+225
View File
@@ -0,0 +1,225 @@
---
id: sr
title: ".sr()"
slug: sr
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Finds all rows whose range value on the stated `column` is strictly to
the right of the specified `range`.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('countries')
.select('name, id, population_range_millions')
.sr('population_range_millions', [150, 250])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
column
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
The column to filter on.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
range
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
string
</span>
</h4>
<div class="method-list-item-description">
The range to filter with.
</div>
</li>
</ul>
## Examples
### With `select()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('countries')
.select('name, id, population_range_millions')
.sr('population_range_millions', [150, 250])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `update()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('countries')
.update({ name: 'Mordor' })
.sr('population_range_millions', [150, 250])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `delete()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('countries')
.delete()
.sr('population_range_millions', [150, 250])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### With `rpc()`
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
// Only valid if the Stored Procedure returns a table type.
const { data, error } = await supabase
.rpc('echo_all_countries')
.sr('population_range_millions', [150, 250])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+331
View File
@@ -0,0 +1,331 @@
---
id: subscribe
title: "on().subscribe()"
slug: subscribe
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Subscribe to realtime changes in your databse.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const mySubscription = supabase
.from('*')
.on('*', payload => {
console.log('Change received!', payload)
})
.subscribe()
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
event
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
INSERT | UPDATE | DELETE | *
</span>
</h4>
<div class="method-list-item-description">
The database event which you would like to receive updates for, or you can use the special wildcard `*` to listen to all changes.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
callback
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
A callback that will handle the payload that is sent whenever your database changes.
</div>
</li>
</ul>
## Notes
- 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
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const mySubscription = supabase
.from('*')
.on('*', payload => {
console.log('Change received!', payload)
})
.subscribe()
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### Listening to a specific table
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const mySubscription = supabase
.from('countries')
.on('*', payload => {
console.log('Change received!', payload)
})
.subscribe()
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### Listening to inserts
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const mySubscription = supabase
.from('countries')
.on('INSERT', payload => {
console.log('Change received!', payload)
})
.subscribe()
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### Listening to updates
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const mySubscription = supabase
.from('countries')
.on('UPDATE', payload => {
console.log('Change received!', payload)
})
.subscribe()
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### Listening to deletes
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const mySubscription = supabase
.from('countries')
.on('DELETE', payload => {
console.log('Change received!', payload)
})
.subscribe()
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### Listening to multiple events
You can chain listeners if you want to listen to multiple events for each table.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const mySubscription = supabase
.from('countries')
.on('INSERT', handleRecordInserted)
.on('DELETE', handleRecordDeleted)
.subscribe()
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
### 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.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const mySubscription = supabase
.from('countries:id.eq.200')
.on('UPDATE', handleRecordUpdated)
.subscribe()
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+111
View File
@@ -0,0 +1,111 @@
---
id: update
title: "Modify data: update()"
slug: update
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Performs an UPDATE on the table.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.update({ name: 'Middle Earth' })
.match({ name: 'Auckland' })
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
values
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
Partial
</span>
</h4>
<div class="method-list-item-description">
The values to update.
</div>
</li>
</ul>
## Notes
- `update()` should always be combined with [Filters](/docs/client/using-filters) to target the item(s) you wish to update.
## Examples
### Updating your data
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.update({ name: 'Middle Earth' })
.match({ name: 'Auckland' })
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+12
View File
@@ -0,0 +1,12 @@
---
id: using-filters
title: "Using Filters"
slug: using-filters
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Filters can be used on `select()`, `update()`, and `delete()` queries.
If a Stored Procedure returns a table response, you can also apply filters.
+12
View File
@@ -0,0 +1,12 @@
---
id: using-modifiers
title: "Using Modifiers"
slug: using-modifiers
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Modifiers can be used on `select()` queries.
If a Stored Procedure returns a table response, you can also apply modifiers to the `rpc()` function.
+107
View File
@@ -0,0 +1,107 @@
---
id: wfts
title: ".wfts()"
slug: wfts
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Finds all rows whose tsvector value on the stated `column` matches
websearch_to_tsquery(`query`).
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
column
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
The column to filter on.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
query
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
string
</span>
</h4>
<div class="method-list-item-description">
The Postgres tsquery string to filter with.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
__namedParameters
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
No description provided.
</div>
<ul className="method-list-group">
<h5 class="method-list-title method-list-title-isChild expanded">Properties</h5>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
config
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
|
</span>
</h4>
<div class="method-list-item-description">
The text search configuration to use.
</div>
</li>
</ul>
</li>
</ul>
-39
View File
@@ -1,39 +0,0 @@
import Collapsable from '../../src/components/Collapsable'
<Collapsable title="Toggle Example Tables">
We will be fictional "world" database in all of our examples.
<div className="DummyData">
<div className="">
<strong>Countries</strong>
| id | name | iso2 | population_range_millions | main_exports |
| --- | ------------- | :--: | ------------------------- | --------------------- |
| 76 | Brazil | BR | ( 205, 215 ) | [ beans, minerals ] |
| 156 | China | CN | ( 1380, 1390 ) | [ computers, phones ] |
| 250 | France | FR | ( 60, 70 ) | [ cars, machines ] |
| 554 | New Zealand | NZ | ( 4, 6 ) | [ food, machines ] |
| 556 | Nigeria | NG | ( 185, 195 ) | [ oil, beans ] |
| 840 | United States | US | ( 320, 330 ) | [ oil, cars, food ] |
</div>
<div className="">
<strong>Cities</strong>
| name | country_id |
| -------------- | :--------: |
| Rio de Janeiro | 76 |
| Beijing | 156 |
| Paris | 250 |
| Auckland | 554 |
| Lagos | 556 |
| Los Angeles | 840 |
| San Francisco | 840 |
</div>
</div>
</Collapsable>
+39
View File
@@ -0,0 +1,39 @@
---
id: api-getuser
title: "api.getUser"
slug: api-getuser
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Gets the user details.
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
jwt
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
string
</span>
</h4>
<div class="method-list-item-description">
A valid, logged-in JWT.
</div>
</li>
</ul>
@@ -0,0 +1,39 @@
---
id: api-refreshaccesstoken
title: "api.refreshAccessToken"
slug: api-refreshaccesstoken
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Generates a new JWT.
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
refreshToken
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
string
</span>
</h4>
<div class="method-list-item-description">
A valid refresh token that was returned on login.
</div>
</li>
</ul>
@@ -0,0 +1,39 @@
---
id: api-resetpasswordforemail
title: "api.resetPasswordForEmail"
slug: api-resetpasswordforemail
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Sends a reset request to an email address.
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
email
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
string
</span>
</h4>
<div class="method-list-item-description">
The email address of the user.
</div>
</li>
</ul>
@@ -0,0 +1,60 @@
---
id: api-signinwithemail
title: "api.signInWithEmail"
slug: api-signinwithemail
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Logs in an existing using their email address.
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
email
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
string
</span>
</h4>
<div class="method-list-item-description">
The email address of the user.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
password
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
string
</span>
</h4>
<div class="method-list-item-description">
The password of the user.
</div>
</li>
</ul>
+39
View File
@@ -0,0 +1,39 @@
---
id: api-signout
title: "api.signOut"
slug: api-signout
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Removes a logged-in session.
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
jwt
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
string
</span>
</h4>
<div class="method-list-item-description">
A valid, logged-in JWT.
</div>
</li>
</ul>
@@ -0,0 +1,105 @@
---
id: api-signupwithemail
title: "api.signUpWithEmail"
slug: api-signupwithemail
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Creates a new user using their email address.
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
email
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
string
</span>
</h4>
<div class="method-list-item-description">
The email address of the user.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
password
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
string
</span>
</h4>
<div class="method-list-item-description">
The password of the user.
</div>
</li>
</ul>
## Examples
### Sign up a new user with email
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { error, data } = await api
.signUpWithEmail('example@email.com', 'example-password')
```
</TabItem>
<TabItem value="py">
```
Not yet implemented
```
</TabItem>
</Tabs>
+60
View File
@@ -0,0 +1,60 @@
---
id: api-updateuser
title: "api.updateUser"
slug: api-updateuser
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Updates the user data.
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
jwt
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
string
</span>
</h4>
<div class="method-list-item-description">
A valid, logged-in JWT.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
attributes
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
UserAttributes
</span>
</h4>
<div class="method-list-item-description">
The data you want to update.
</div>
</li>
</ul>
+12
View File
@@ -0,0 +1,12 @@
---
id: index
title: "GoTrue Client"
slug: gotrue-client
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
GoTrue is an authentication server.
Supabase provides client libraries to interact with the server
+169
View File
@@ -0,0 +1,169 @@
---
id: initializing
title: "Initializing"
slug: initializing
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Create a new client for use in the browser.
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
options
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
No description provided.
</div>
<ul className="method-list-group">
<h5 class="method-list-title method-list-title-isChild expanded">Properties</h5>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
url
</span>
<span className="method-list-item-label-badge false">
optional
</span>
<span className="method-list-item-validation">
|
</span>
</h4>
<div class="method-list-item-description">
The URL of the GoTrue server.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
persistSession
</span>
<span className="method-list-item-label-badge false">
optional
</span>
<span className="method-list-item-validation">
| |
</span>
</h4>
<div class="method-list-item-description">
Set to "true" if you want to automatically save the user session into local storage.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
localStorage
</span>
<span className="method-list-item-label-badge false">
optional
</span>
<span className="method-list-item-validation">
Storage
</span>
</h4>
<div class="method-list-item-description">
No description provided.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
headers
</span>
<span className="method-list-item-label-badge false">
optional
</span>
<span className="method-list-item-validation">
|
</span>
</h4>
<div class="method-list-item-description">
Any additional headers to send to the GoTrue server.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
detectSessionInUrl
</span>
<span className="method-list-item-label-badge false">
optional
</span>
<span className="method-list-item-validation">
| |
</span>
</h4>
<div class="method-list-item-description">
Set to "true" if you want to automatically detects OAuth grants in the URL and signs in the user.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
autoRefreshToken
</span>
<span className="method-list-item-label-badge false">
optional
</span>
<span className="method-list-item-validation">
| |
</span>
</h4>
<div class="method-list-item-description">
Set to "true" if you want to automatically refresh the token before expiring.
</div>
</li>
</ul>
</li>
</ul>
+24
View File
@@ -0,0 +1,24 @@
---
id: installing
title: "Installing"
slug: installing
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
All JavaScript libraries are built directly by the Supabase team.
Other languages are built by the community and supported by Supabase.
## Javascript
```bash
npm install @supabase/gotrue-js
```
## Python
```bash
# Not yet implemented
```
@@ -0,0 +1,8 @@
---
id: onauthstatechange
title: "onAuthStateChange"
slug: onauthstatechange
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
+59
View File
@@ -0,0 +1,59 @@
---
id: session
title: "session"
slug: session
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Returns the session data, if there is an active session.
## Examples
### Get user
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const user = auth.session()
```
</TabItem>
<TabItem value="py">
```
Not yet implemented
```
</TabItem>
</Tabs>
+177
View File
@@ -0,0 +1,177 @@
---
id: signin
title: "signIn"
slug: signin
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Log in an existing user, or login via a third-party provider.
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { error, data } = await auth.signIn({
email: 'example@email.com',
password: 'example-password',
})
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
credentials
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
The user login details.
</div>
<ul className="method-list-group">
<h5 class="method-list-title method-list-title-isChild expanded">Properties</h5>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
provider
</span>
<span className="method-list-item-label-badge false">
optional
</span>
<span className="method-list-item-validation">
Provider
</span>
</h4>
<div class="method-list-item-description">
One of the providers supported by GoTrue.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
password
</span>
<span className="method-list-item-label-badge false">
optional
</span>
<span className="method-list-item-validation">
|
</span>
</h4>
<div class="method-list-item-description">
The user's password.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
email
</span>
<span className="method-list-item-label-badge false">
optional
</span>
<span className="method-list-item-validation">
|
</span>
</h4>
<div class="method-list-item-description">
The user's email address.
</div>
</li>
</ul>
</li>
</ul>
## Examples
### Sign in
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { error, data } = await auth.signIn({
email: 'example@email.com',
password: 'example-password',
})
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+59
View File
@@ -0,0 +1,59 @@
---
id: signout
title: "signOut"
slug: signout
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Signs out the current user, if there is a logged in user.
## Examples
### Sign out
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { error, data } = await auth.signOut()
```
</TabItem>
<TabItem value="py">
```
Not yet implemented
```
</TabItem>
</Tabs>
+134
View File
@@ -0,0 +1,134 @@
---
id: signup
title: "signUp"
slug: signup
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Creates a new user.
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
credentials
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
object
</span>
</h4>
<div class="method-list-item-description">
The user login details.
</div>
<ul className="method-list-group">
<h5 class="method-list-title method-list-title-isChild expanded">Properties</h5>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
email
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
string
</span>
</h4>
<div class="method-list-item-description">
The user's email address.
</div>
</li>
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
password
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
string
</span>
</h4>
<div class="method-list-item-description">
The user's password.
</div>
</li>
</ul>
</li>
</ul>
## Notes
- A user can sign up either via email or OAuth.
- If you provide `email`, `password` is also required
- If you provide `access_token`, `password` is also required
## Examples
### Sign up
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { error, data } = await auth.signUp({
email: 'example@email.com',
password: 'example-password',
})
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
+39
View File
@@ -0,0 +1,39 @@
---
id: update
title: "update"
slug: update
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Updates user data, if there is a logged in user.
## Parameters
<ul className="method-list-group">
<li className="method-list-item">
<h4 className="method-list-item-label">
<span className="method-list-item-label-name">
attributes
</span>
<span className="method-list-item-label-badge required">
required
</span>
<span className="method-list-item-validation">
UserAttributes
</span>
</h4>
<div class="method-list-item-description">
No description provided.
</div>
</li>
</ul>
+59
View File
@@ -0,0 +1,59 @@
---
id: user
title: "user"
slug: user
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Returns the user data, if there is a logged in user.
## Examples
### Get user
<Tabs
defaultValue="js"
groupId="libraries"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const user = auth.user()
```
</TabItem>
<TabItem value="py">
```
Not yet implemented
```
</TabItem>
</Tabs>
+545
View File
@@ -0,0 +1,545 @@
---
id: about
title: GoTrue
description: An SWT based API for managing users and issuing SWT tokens
---
GoTrue is a small open-source API written in golang, that can act as a self-standing
API service for handling user registration and authentication for JAM projects.
It's based on OAuth2 and JWT and will handle user signup, authentication and custom
user data.
## Configuration
You may configure GoTrue using either a configuration file named `.env`,
environment variables, or a combination of both. Environment variables are prefixed with `GOTRUE_`, and will always have precedence over values provided via file.
### Top-Level
```
GOTRUE_SITE_URL=https://example.netlify.com/
```
`SITE_URL` - `string` **required**
The base URL your site is located at. Currently used in combination with other settings to construct URLs used in emails.
`OPERATOR_TOKEN` - `string` _Multi-instance mode only_
The shared secret with an operator (usually Netlify) for this microservice. Used to verify requests have been proxied through the operator and
the payload values can be trusted.
`DISABLE_SIGNUP` - `bool`
When signup is disabled the only way to create new users is through invites. Defaults to `false`, all signups enabled.
`GOTRUE_RATE_LIMIT_HEADER` - `string`
Header on which to rate limit the `/token` endpoint.
### API
```
GOTRUE_API_HOST=localhost
PORT=9999
```
`API_HOST` - `string`
Hostname to listen on.
`PORT` (no prefix) / `API_PORT` - `number`
Port number to listen on. Defaults to `8081`.
`API_ENDPOINT` - `string` _Multi-instance mode only_
Controls what endpoint Netlify can access this API on.
`REQUEST_ID_HEADER` - `string`
If you wish to inherit a request ID from the incoming request, specify the name in this value.
### Database
```
GOTRUE_DB_DRIVER=mysql
DATABASE_URL=root@localhost/gotrue
```
`DB_DRIVER` - `string` **required**
Chooses what dialect of database you want. Must be `mysql`.
`DATABASE_URL` (no prefix) / `DB_DATABASE_URL` - `string` **required**
Connection string for the database.
`DB_NAMESPACE` - `string`
Adds a prefix to all table names.
**Migrations Note**
Migrations are not applied automatically, so you will need to run them after
you've built gotrue.
* If built locally: `./gotrue migrate`
* Using Docker: `docker run --rm gotrue gotrue migrate`
### Logging
```
LOG_LEVEL=debug # available without GOTRUE prefix (exception)
GOTRUE_LOG_FILE=/var/log/go/gotrue.log
```
`LOG_LEVEL` - `string`
Controls what log levels are output. Choose from `panic`, `fatal`, `error`, `warn`, `info`, or `debug`. Defaults to `info`.
`LOG_FILE` - `string`
If you wish logs to be written to a file, set `log_file` to a valid file path.
### JSON Web Tokens (JWT)
```
GOTRUE_JWT_SECRET=supersecretvalue
GOTRUE_JWT_EXP=3600
GOTRUE_JWT_AUD=netlify
```
`JWT_SECRET` - `string` **required**
The secret used to sign JWT tokens with.
`JWT_EXP` - `number`
How long tokens are valid for, in seconds. Defaults to 3600 (1 hour).
`JWT_AUD` - `string`
The default JWT audience. Use audiences to group users.
`JWT_ADMIN_GROUP_NAME` - `string`
The name of the admin group (if enabled). Defaults to `admin`.
`JWT_DEFAULT_GROUP_NAME` - `string`
The default group to assign all new users to.
### External Authentication Providers
We support `bitbucket`, `github`, `gitlab`, and `google` for external authentication.
Use the names as the keys underneath `external` to configure each separately.
```
GOTRUE_EXTERNAL_GITHUB_CLIENT_ID=myappclientid
GOTRUE_EXTERNAL_GITHUB_SECRET=clientsecretvaluessssh
```
No external providers are required, but you must provide the required values if you choose to enable any.
`EXTERNAL_X_ENABLED` - `bool`
Whether this external provider is enabled or not
`EXTERNAL_X_CLIENT_ID` - `string` **required**
The OAuth2 Client ID registered with the external provider.
`EXTERNAL_X_SECRET` - `string` **required**
The OAuth2 Client Secret provided by the external provider when you registered.
`EXTERNAL_X_REDIRECT_URI` - `string` **required for gitlab**
The URI a OAuth2 provider will redirect to with the `code` and `state` values.
`EXTERNAL_X_URL` - `string`
The base URL used for constructing the URLs to request authorization and access tokens. Used by `gitlab` only. Defaults to `https://gitlab.com`.
### E-Mail
Sending email is not required, but highly recommended for password recovery.
If enabled, you must provide the required values below.
```
GOTRUE_SMTP_HOST=smtp.mandrillapp.com
GOTRUE_SMTP_PORT=587
GOTRUE_SMTP_USER=smtp-delivery@example.com
GOTRUE_SMTP_PASS=correcthorsebatterystaple
GOTRUE_SMTP_ADMIN_EMAIL=support@example.com
GOTRUE_MAILER_SUBJECTS_CONFIRMATION="Please confirm"
```
`SMTP_ADMIN_EMAIL` - `string` **required**
The `From` email address for all emails sent.
`SMTP_HOST` - `string` **required**
The mail server hostname to send emails through.
`SMTP_PORT` - `number` **required**
The port number to connect to the mail server on.
`SMTP_USER` - `string`
If the mail server requires authentication, the username to use.
`SMTP_PASS` - `string`
If the mail server requires authentication, the password to use.
`SMTP_MAX_FREQUENCY` - `number`
Controls the minimum amount of time that must pass before sending another signup confirmation or password reset email. The value is the number of seconds. Defaults to 900 (15 minutes).
`MAILER_AUTOCONFIRM` - `bool`
If you do not require email confirmation, you may set this to `true`. Defaults to `false`.
`MAILER_URLPATHS_INVITE` - `string`
URL path to use in the user invite email. Defaults to `/`.
`MAILER_URLPATHS_CONFIRMATION` - `string`
URL path to use in the signup confirmation email. Defaults to `/`.
`MAILER_URLPATHS_RECOVERY` - `string`
URL path to use in the password reset email. Defaults to `/`.
`MAILER_URLPATHS_EMAIL_CHANGE` - `string`
URL path to use in the email change confirmation email. Defaults to `/`.
`MAILER_SUBJECTS_INVITE` - `string`
Email subject to use for user invite. Defaults to `You have been invited`.
`MAILER_SUBJECTS_CONFIRMATION` - `string`
Email subject to use for signup confirmation. Defaults to `Confirm Your Signup`.
`MAILER_SUBJECTS_RECOVERY` - `string`
Email subject to use for password reset. Defaults to `Reset Your Password`.
`MAILER_SUBJECTS_EMAIL_CHANGE` - `string`
Email subject to use for email change confirmation. Defaults to `Confirm Email Change`.
`MAILER_TEMPLATES_INVITE` - `string`
URL path to an email template to use when inviting a user.
`SiteURL`, `Email`, and `ConfirmationURL` variables are available.
Default Content (if template is unavailable):
```html
<h2>You have been invited</h2>
<p>You have been invited to create a user on {{ .SiteURL }}. Follow this link to accept the invite:</p>
<p><a href="{{ .ConfirmationURL }}">Accept the invite</a></p>
```
`MAILER_TEMPLATES_CONFIRMATION` - `string`
URL path to an email template to use when confirming a signup.
`SiteURL`, `Email`, and `ConfirmationURL` variables are available.
Default Content (if template is unavailable):
```html
<h2>Confirm your signup</h2>
<p>Follow this link to confirm your user:</p>
<p><a href="{{ .ConfirmationURL }}">Confirm your mail</a></p>
```
`MAILER_TEMPLATES_RECOVERY` - `string`
URL path to an email template to use when resetting a password.
`SiteURL`, `Email`, and `ConfirmationURL` variables are available.
Default Content (if template is unavailable):
```html
<h2>Reset Password</h2>
<p>Follow this link to reset the password for your user:</p>
<p><a href="{{ .ConfirmationURL }}">Reset Password</a></p>
```
`MAILER_TEMPLATES_EMAIL_CHANGE` - `string`
URL path to an email template to use when confirming the change of an email address.
`SiteURL`, `Email`, `NewEmail`, and `ConfirmationURL` variables are available.
Default Content (if template is unavailable):
```html
<h2>Confirm Change of Email</h2>
<p>Follow this link to confirm the update of your email from {{ .Email }} to {{ .NewEmail }}:</p>
<p><a href="{{ .ConfirmationURL }}">Change Email</a></p>
```
## Endpoints
GoTrue exposes the following endpoints:
* **GET /settings**
Returns the publicly available settings for this gotrue instance.
```json
{
"external": {
"bitbucket": true,
"github": true,
"gitlab": true,
"google": true
},
"disable_signup": false,
"autoconfirm": false
}
```
* **POST /signup**
Register a new user with an email and password.
```json
{
"email": "email@example.com",
"password": "secret"
}
```
Returns:
```json
{
"id": "11111111-2222-3333-4444-5555555555555",
"email": "email@example.com",
"confirmation_sent_at": "2016-05-15T20:49:40.882805774-07:00",
"created_at": "2016-05-15T19:53:12.368652374-07:00",
"updated_at": "2016-05-15T19:53:12.368652374-07:00"
}
```
* **POST /invite**
Invites a new user with an email.
```json
{
"email": "email@example.com"
}
```
Returns:
```json
{
"id": "11111111-2222-3333-4444-5555555555555",
"email": "email@example.com",
"confirmation_sent_at": "2016-05-15T20:49:40.882805774-07:00",
"created_at": "2016-05-15T19:53:12.368652374-07:00",
"updated_at": "2016-05-15T19:53:12.368652374-07:00",
"invited_at": "2016-05-15T19:53:12.368652374-07:00"
}
```
* **POST /verify**
Verify a registration or a password recovery. Type can be `signup` or `recovery`
and the `token` is a token returned from either `/signup` or `/recover`.
```json
{
"type": "signup",
"token": "confirmation-code-delivered-in-email",
"password": "12345abcdef" // only required if responding to an 'invite'
}
```
`password` is required for signup verification if no existing password exists.
Returns:
```json
{
"access_token": "jwt-token-representing-the-user",
"token_type": "bearer",
"expires_in": 3600,
"refresh_token": "a-refresh-token"
}
```
* **GET /verify**
Verify a registration or a password recovery. Type can be `signup` or `recovery`
and the `token` is a token returned from either `/signup` or `/recover`.
```json
{
"type": "signup",
"token": "confirmation-code-delivered-in-email",
}
```
`password` is required for signup verification if no existing password exists.
User will be logged in and redirected to:
```json
SITE_URL/#access_token=jwt-token-representing-the-user&token_type=bearer&expires_in=3600&refresh_token=a-refresh-token
```
* **POST /recover**
Password recovery. Will deliver a password recovery mail to the user based on
email address.
```json
{
"email": "email@example.com"
}
```
Returns:
```json
{}
```
* **POST /token**
This is an OAuth2 endpoint that currently implements
the password and refresh_token grant types
query params:
```
?grant_type=password
```
body:
```json
{
"email": "name@domain.com",
"password": "somepassword",
}
```
or
query params:
```
grant_type=refresh_token
```
body:
```json
{
"refresh_token": "a-refresh-token"
}
```
Once you have an access token, you can access the methods requiring authentication
by settings the `Authorization: Bearer YOUR_ACCESS_TOKEN_HERE` header.
Returns:
```json
{
"access_token": "jwt-token-representing-the-user",
"token_type": "bearer",
"expires_in": 3600,
"refresh_token": "a-refresh-token"
}
```
* **GET /user**
Get the JSON object for the logged in user (requires authentication)
Returns:
```json
{
"id": "11111111-2222-3333-4444-5555555555555",
"email": "email@example.com",
"confirmation_sent_at": "2016-05-15T20:49:40.882805774-07:00",
"created_at": "2016-05-15T19:53:12.368652374-07:00",
"updated_at": "2016-05-15T19:53:12.368652374-07:00"
}
```
* **PUT /user**
Update a user (Requires authentication). Apart from changing email/password, this
method can be used to set custom user data.
```json
{
"email": "new-email@example.com",
"password": "new-password",
"data": {
"key": "value",
"number": 10,
"admin": false
}
}
```
Returns:
```json
{
"id": "11111111-2222-3333-4444-5555555555555",
"email": "email@example.com",
"confirmation_sent_at": "2016-05-15T20:49:40.882805774-07:00",
"created_at": "2016-05-15T19:53:12.368652374-07:00",
"updated_at": "2016-05-15T19:53:12.368652374-07:00"
}
```
* **POST /logout**
Logout a user (Requires authentication).
This will revoke all refresh tokens for the user. Remember that the JWT tokens
will still be valid for stateless auth until they expires.
* **GET /authorize**
Get access_token from external oauth provider
query params:
```
provider=google | bitbucket | github | gitlab
```
Redirects to provider and then to `/callback`
* **GET /callback**
External provider should redirect to here
Redirects to `<GOTRUE_SITE_URL>#access_token=<access_token>&refresh_token=<refresh_token>&expires_in=3600&provider=<provider_name>`
## Pre-built
- [Docker](https://hub.docker.com/repository/docker/supabase/gotrue)
+122
View File
@@ -0,0 +1,122 @@
---
id: auth
title: Auth
description: Use Supabase to Authenticate and Authorize your users.
---
### User Management
Supabase makes it simple to manage your users.
<video width="99%" muted playsInline controls="true">
<source src="/videos/auth-zoom2.mp4" type="video/mp4" muted playsInline />
</video>
When a user signs 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 the user using a `user_id` field.
Supabase provides the routes to [sign up](/docs/client/auth-signup), [login](/docs/client/auth-signin), [log out](/docs/client/auth-signout), and manage users in your apps and websites.
### Third Party Logins
We currently support the following OAuth providers:
- Google
- Github
- Gitlab
- Bitbucket
![OAuth Logins.](/img/supabase-oauth-logins.png)
You can enable providers by navigating to Authentication > Settings > External OAuth Providers and inputting your `Client ID` and `Secret` for each.
To fetch these you need to:
1. Generate `Client ID` and `Secret` ([google](https://console.developers.google.com/apis/credentials), [github](https://github.com/settings/applications/new), [gitlab](https://gitlab.com/oauth/applications), [bitbucket](https://support.atlassian.com/bitbucket-cloud/docs/use-oauth-on-bitbucket-cloud/))
2. Enter Authorized Redirect URI: `http://<your-project>.supabase.co/auth/v1/callback` on provider dashboard
### Row Level Security
Authentication only gets you so far. When you need granular authorization rules, nothing beats PostgreSQL's [Row Level Security](https://www.postgresql.org/docs/current/ddl-rowsecurity.html). Supabase makes it simple to turn RLS on and off.
<video width="99%" muted playsInline controls="true">
<source src="/videos/rls-zoom2.mp4" type="video/mp4" muted playsInline />
</video>
### 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.
<video width="99%" muted playsInline controls="true">
<source src="/videos/policies-zoom2.mp4" type="video/mp4" muted playsInline />
</video>
With policies, your database becomes the rules engine. Instead of repetitively filtering your queries, like this ...
```js
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:
```js
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
### Never use a service key on the client.
Supabase provides special "Service" keys, which can be used to bypass all Row Level Security.
These should never be used in the browser or exposed to customers, but they are usefull for administrative tasks.
### Create a `public.users` table.
Even though Supabase provides an `auth.users` table, it is helpful to also create a users table in the `public` schema, which uses the same UUID Primary Key as the `auth.users`.
For security purposes, the `auth` schema is not exposed on the auto-generated API. Created a `public.users` table allows you to interact via the Supabase client -
especially useful for cross-table queries.
### Policies are like where clauses.
Policies are easy to understand once you get the hang of them. You can just think of the as adding a `WHERE` clause to every query. For example if you had a policy like this:
```sql
create policy "Individuals can view their own todos." on todos for
select using (auth.uid() = user_id);
```
It 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.
```
## Next steps
- Read more about [Row Level Security](https://www.postgresql.org/docs/current/ddl-rowsecurity.html)
- Sign in: [app.supabase.io](https://app.supabase.io)
+310
View File
@@ -0,0 +1,310 @@
---
id: client-libraries
title: Client Libraries
description: 'Supabase provides client libraries in several languages.'
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
The [Supabase Client](/docs/client/supabase-client) makes it simple for developers to build secure and scalable products.
## Auth
Create new users using [`signUp()`](/docs/client/auth-signup).
<Tabs
groupId="libraries"
defaultValue="js"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { error, data } = await supabase.auth.signUp({
email: 'example@email.com',
password: 'example-password',
})
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
Existing users can log in using [`signIn()`](/docs/client/auth-signin).
<Tabs
groupId="libraries"
defaultValue="js"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { error, data } = await supabase.auth.signIn({
email: 'example@email.com',
password: 'example-password',
})
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
If there is an email, but no password passed to [`signIn()`](/docs/client/auth-signin), the user will receive a magic link.
<Tabs
groupId="libraries"
defaultValue="js"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { error, data } = await supabase.auth.signIn({
email: 'example@email.com'
})
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
Third party logins are also handled through [`signIn()`](/docs/client/auth-signin).
<Tabs
groupId="libraries"
defaultValue="js"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { user, error } = await supabase.auth.signIn({
// provider can be 'github', 'google', 'gitlab', or 'bitbucket'
provider: 'github'
})
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## 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/client/select).
<Tabs
groupId="libraries"
defaultValue="js"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('countries')
.select(`
name,
cities (
name
)
`)
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
You can do advanced [filtering](/docs/client/using-filters) to extract only the data that you need.
<Tabs
groupId="libraries"
defaultValue="js"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.select('name, country_id')
.lt('country_id', 100)
.limit(10)
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
You can create data easiely using [`insert()`](/docs/client/insert).
<Tabs
groupId="libraries"
defaultValue="js"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const { data, error } = await supabase
.from('cities')
.insert([
{ name: 'The Shire', country_id: 554 },
{ name: 'Rohan', country_id: 555 },
])
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Realtime Changes
The Supabase client makes it simple to listen to realtime database changes, using [`subscribe()`](/docs/client/subscribe).
<Tabs
groupId="libraries"
defaultValue="js"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const mySubscription = supabase
.from('countries')
.on('*', payload => {
console.log('Change received!', payload)
})
.subscribe()
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
You can even [listen to Row Level changes](/docs/client/subscribe#listening-to-row-level-changes).
<Tabs
groupId="libraries"
defaultValue="js"
values={[{ label: 'JavaScript', value: 'js' },{ label: 'Python', value: 'py' }]}>
<TabItem value="js">
```js
const mySubscription = supabase
.from('countries:id.eq.200')
.on('UPDATE', handleRecordUpdated)
.subscribe()
```
</TabItem>
<TabItem value="py">
```py
# Not yet implemented
```
</TabItem>
</Tabs>
## Next steps
- View the [Client Docs](/docs/client/supabase-client)
- Sign in: [app.supabase.io](https://app.supabase.io)
+65
View File
@@ -0,0 +1,65 @@
---
id: database
title: Database
description: Use Supabase to manage your data.
---
Supabase is built on top of [Postgres](/docs/postgres/server/about), 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.](/img/table-view.png)
### Relationships
Dig into the relationships within your data.
<video width="99%" loop="" muted="" playsInline="" controls="true">
<source src="/videos/relational-drilldown-zoom.mp4" type="video/mp4" />
</video>
### Clone tables
You can duplicate your tables, just like you would inside a spreadsheet.
<video width="99%" muted playsInline controls={true}>
<source src="/videos/duplicate-tables.mp4" type="video/mp4" muted playsInline />
</video>
### Enable and disable extensions
Extensions are one of the best things about Postgres. You can enable Postgres extensions with the click of a button.
<video width="99%" muted playsInline controls={true}>
<source src="/videos/toggle-extensions.mp4" type="video/mp4" muted playsInline />
</video>
### The SQL Editor
Supabase comes with a SQL Editor. You can also save your favorite queries to run later!
<video width="99%" muted playsInline controls={true}>
<source src="/videos/favourites.mp4" type="video/mp4" muted playsInline />
</video>
### Additional features
- Supabase extends Postgres with realtime functionality using our [Realtime Server](/docs/realtime/server/about).
- Every project is a full Postgres database, with `postgres` level access.
- Managed backups - Supabase handles all your database backups.
- Data imports - import directly from a CSV or excel spreadsheet.
## Next steps
- Read more about [Postgres](/docs/postgres/server/about)
- Sign in: [app.supabase.io](https://app.supabase.io)
+42
View File
@@ -0,0 +1,42 @@
---
id: platform
title: Getting started
sidebar_label: Introduction
description: Getting started with the Supabase Platform.
---
Supabase is a hosted platform which makes it very simple to get started.
Just visit [app.supabase.io](https://app.supabase.io) and sign in to start creating projects.
### Organizations and Project
After you have signed in, you can create Organizations and Projects. Each project contains a full Postgres database, as well as auto-generated APIs and Auth functionality.
### Managing team members
You can invite your team members into your organizations so that you can collaborate on projects.
<video width="99%" muted playsInline controls="true">
<source src="/videos/invite-team.mp4" type="video/mp4" muted playsInline />
</video>
## Self Hosting
Supabase is an amalgamation of various open source tools. If you've started with Supabase and you want to migrate away,
all you need to do is a backup/dump of your database and take it anywhere you want.
You can find instructions for installing each of the components of Supabase in the "Tools" section.
We choose tools which are permissively licensed (usually MIT or Apache 2) whenever we build new features.
This prevents lock-in and, more importantly, it is our way of supporting open source development.
We support the tools that we use in a number of ways - donating directly, building client libraries,
and employing contributors to work full-time on the tools (in the case of PostgREST).
## Next steps
- Sign in to [app.supabase.io](https://app.supabase.io)
-476
View File
@@ -1,476 +0,0 @@
---
id: delete
title: 'Deleting'
description: 'How to delete records from your database with Supabase'
---
import DummyData from '../common/_DummyData.mdx'
import Collapsable from '../../src/components/Collapsable'
import CommonResponses from '../common/_CommonResponses.mdx'
import CommonFilters from '../common/CommonFilters'
import FromFunction from '../common/_FromFunction.mdx'
import CustomCodeBlock from '../../src/components/CustomCodeBlock'
import {
deleteRecordJs,
deleteFilterJs,
deleteNotJs,
deleteMatchJs,
deleteEqJs,
deleteNeqJs,
deleteGtJs,
deleteLtJs,
deleteGteJs,
deleteLteJs,
deleteLikeJs,
deleteIlikeJs,
deleteIsJs,
deleteInJs,
deleteCsJs,
deleteCdJs,
deleteOvaJs,
deleteOvrJs,
deleteSlJs,
deleteSrJs,
deleteNxlJs,
deleteNxrJs,
deleteAdjJs,
} from './examples/delete'
<DummyData />
### Delete records
<CustomCodeBlock
header="Deletes city."
js={deleteRecordJs}
jsHighlight="{7-10}"
response={`{
"body": null,
"status": 204,
"statusCode": 204,
"statusText": "No Content"
}`}
/>
## Reference
### `from()`
<FromFunction verb="delete" />
### `delete()`
```js {3}
supabase
.from(tableName)
.delete()
```
It is to note that it is required to apply filters when using `.delete()`. Not using filters would result in an error.
---
## Filtering
### `filter()`
<CustomCodeBlock
header="Shows how to use filter( ) with delete( )"
js={deleteFilterJs}
jsHighlight="{10}"
response={`{
"body": null,
"status": 204,
"statusCode": 204,
"statusText": "No Content"
}`}
/>
<br />
<CommonFilters filter="filter" />
### `not()`
<CustomCodeBlock
header="Shows how to use not( ) with delete( )"
js={deleteNotJs}
jsHighlight="{10}"
response={`{
"body": null,
"status": 204,
"statusCode": 204,
"statusText": "No Content"
}`}
/>
<br />
<CommonFilters filter="not" />
### `match()`
<CustomCodeBlock
header="Shows how to use match( ) with delete( )"
js={deleteMatchJs}
jsHighlight="{10}"
response={`{
"body": null,
"status": 204,
"statusCode": 204,
"statusText": "No Content"
}`}
/>
<br />
<CommonFilters filter="match" />
### `eq()`
<CustomCodeBlock
header="Shows how to use eq( ) with delete( )"
js={deleteEqJs}
jsHighlight="{10}"
response={`{
"body": null,
"status": 204,
"statusCode": 204,
"statusText": "No Content"
}`}
/>
<br />
<CommonFilters filter="eq" />
### `neq()`
<CustomCodeBlock
header="Shows how to use neq( ) with delete( )"
js={deleteNeqJs}
jsHighlight="{10}"
response={`{
"body": null,
"status": 204,
"statusCode": 204,
"statusText": "No Content"
}`}
/>
<br />
<CommonFilters filter="neq" />
### `gt()`
<CustomCodeBlock
header="Shows how to use gt( ) with delete( )"
js={deleteGtJs}
jsHighlight="{10}"
response={`{
"body": null,
"status": 204,
"statusCode": 204,
"statusText": "No Content"
}`}
/>
<br />
<CommonFilters filter="gt" />
### `lt()`
<CustomCodeBlock
header="Shows how to use lt( ) with delete( )"
js={deleteLtJs}
jsHighlight="{10}"
response={`{
"body": null,
"status": 204,
"statusCode": 204,
"statusText": "No Content"
}`}
/>
<br />
<CommonFilters filter="lt" />
### `gte()`
<CustomCodeBlock
header="Shows how to use gte( ) with delete( )"
js={deleteGteJs}
jsHighlight="{10}"
response={`{
"body": null,
"status": 204,
"statusCode": 204,
"statusText": "No Content"
}`}
/>
<br />
<CommonFilters filter="gte" />
### `lte()`
<CustomCodeBlock
header="Shows how to use lte( ) with delete( )"
js={deleteLteJs}
jsHighlight="{10}"
response={`{
"body": null,
"status": 204,
"statusCode": 204,
"statusText": "No Content"
}`}
/>
<br />
<CommonFilters filter="lte" />
### `like()`
<CustomCodeBlock
header="Shows how to use like( ) with delete( )"
js={deleteLikeJs}
jsHighlight="{10}"
response={`{
"body": null,
"status": 204,
"statusCode": 204,
"statusText": "No Content"
}`}
/>
<br />
<CommonFilters filter="like" />
### `ilike()`
<CustomCodeBlock
header="Shows how to use ilike( ) with delete( )"
js={deleteIlikeJs}
jsHighlight="{10}"
response={`{
"body": null,
"status": 204,
"statusCode": 204,
"statusText": "No Content"
}`}
/>
<br />
<CommonFilters filter="ilike" />
### `is()`
<CustomCodeBlock
header="Shows how to use is( ) with delete( )"
js={deleteIsJs}
jsHighlight="{10}"
response={`{
"body": null,
"status": 204,
"statusCode": 204,
"statusText": "No Content"
}`}
/>
<br />
<CommonFilters filter="is" />
### `in()`
<CustomCodeBlock
header="Shows how to use in( ) with delete( )"
js={deleteInJs}
jsHighlight="{10}"
response={`{
"body": null,
"status": 204,
"statusCode": 204,
"statusText": "No Content"
}`}
/>
<br />
<CommonFilters filter="in" />
### `cs()`
<CustomCodeBlock
header="Shows how to use cs( ) with delete( )"
js={deleteCsJs}
jsHighlight="{10}"
response={`{
"body": null,
"status": 204,
"statusCode": 204,
"statusText": "No Content"
}`}
/>
<br />
<CommonFilters filter="cs" />
### `cd()`
<CustomCodeBlock
header="Shows how to use cd( ) with delete( )"
js={deleteCdJs}
jsHighlight="{10}"
response={`{
"body": null,
"status": 204,
"statusCode": 204,
"statusText": "No Content"
}`}
/>
<br />
<CommonFilters filter="cd" />
### `ova()`
<CustomCodeBlock
header="Shows how to use ova( ) with delete( )"
js={deleteOvaJs}
jsHighlight="{10}"
response={`{
"body": null,
"status": 204,
"statusCode": 204,
"statusText": "No Content"
}`}
/>
<br />
<CommonFilters filter="ova" />
### `ovr()`
<CustomCodeBlock
header="Shows how to use ovr( ) with delete( )"
js={deleteOvrJs}
jsHighlight="{10}"
response={`{
"body": null,
"status": 204,
"statusCode": 204,
"statusText": "No Content"
}`}
/>
<br />
<CommonFilters filter="ovr" />
### `sl()`
<CustomCodeBlock
header="Shows how to use sl( ) with delete( )"
js={deleteSlJs}
jsHighlight="{10}"
response={`{
"body": null,
"status": 204,
"statusCode": 204,
"statusText": "No Content"
}`}
/>
<br />
<CommonFilters filter="sl" />
### `sr()`
<CustomCodeBlock
header="Shows how to use sr( ) with delete( )"
js={deleteSrJs}
jsHighlight="{10}"
response={`{
"body": null,
"status": 204,
"statusCode": 204,
"statusText": "No Content"
}`}
/>
<br />
<CommonFilters filter="sr" />
### `nxl()`
<CustomCodeBlock
header="Shows how to use nxl( ) with delete( )"
js={deleteNxlJs}
jsHighlight="{10}"
response={`{
"body": null,
"status": 204,
"statusCode": 204,
"statusText": "No Content"
}`}
/>
<br />
<CommonFilters filter="nxl" />
### `nxr()`
<CustomCodeBlock
header="Shows how to use nxr( ) with delete( )"
js={deleteNxrJs}
jsHighlight="{10}"
response={`{
"body": null,
"status": 204,
"statusCode": 204,
"statusText": "No Content"
}`}
/>
<br />
<CommonFilters filter="nxr" />
### `adj()`
<CustomCodeBlock
header="Shows how to use adj( ) with delete( )"
js={deleteAdjJs}
jsHighlight="{10}"
response={`{
"body": null,
"status": 204,
"statusCode": 204,
"statusText": "No Content"
}`}
/>
<br />
<CommonFilters filter="adj" />
## Responses
#### 200 OK
Successful request
<CommonResponses />
-281
View File
@@ -1,281 +0,0 @@
import {importJs, errorJs} from './common'
/**
* delete.mdx examples
*/
export const deleteRecordJs = `
${importJs}
const deleteCity = async () => {
try {
let values = await supabase
.from('cities')
.delete()
.match({ id: 666 })
return values
${errorJs}
`.trim()
export const deleteFilterJs = `
${importJs}
const deleteCity = async () => {
try {
let cities = await supabase
.from('cities')
.delete()
.filter({'name', 'eq', 'Paris'})
return cities
${errorJs}
`.trim()
export const deleteNotJs = `
${importJs}
const getCities = async () => {
try {
let cities = await supabase
.from('cities')
.delete()
.not('name', 'eq', 'Paris')
return cities
${errorJs}
`.trim()
export const deleteMatchJs = `
${importJs}
const deleteCity = async () => {
try {
let cities = await supabase
.from('cities')
.delete()
.match({name: 'Beijing', country_id: 156})
return cities
${errorJs}
`.trim()
export const deleteEqJs = `
${importJs}
const deleteCity = async () => {
try {
let cities = await supabase
.from('cities')
.delete()
.eq('name', 'San Francisco')
return cities
${errorJs}
`.trim()
export const deleteNeqJs = `
${importJs}
const deleteCity = async () => {
try {
let cities = await supabase
.from('cities')
.delete()
.neq('name', 'Lagos')
return cities
${errorJs}
`.trim()
export const deleteGtJs = `
${importJs}
const deleteCity = async () => {
try {
let cities = await supabase
.from('cities')
.delete()
.gt('country_id', 250)
return cities
${errorJs}
`.trim()
export const deleteLtJs = `
${importJs}
const deleteCity = async () => {
try {
let cities = await supabase
.from('cities')
.delete()
.lt('country_id', 250)
return cities
${errorJs}
`.trim()
export const deleteGteJs = `
${importJs}
const deleteCity = async () => {
try {
let cities = await supabase
.from('cities')
.delete()
.gte('country_id', 250)
return cities
${errorJs}
`.trim()
export const deleteLteJs = `
${importJs}
const deleteCity = async () => {
try {
let cities = await supabase
.from('cities')
.delete()
.lte('country_id', 250)
return cities
${errorJs}
`.trim()
export const deleteLikeJs = `
${importJs}
const deleteCity = async () => {
try {
let cities = await supabase
.from('cities')
.delete()
.like('name', '%la%')
return cities
${errorJs}
`.trim()
export const deleteIlikeJs = `
${importJs}
const deleteCity = async () => {
try {
let cities = await supabase
.from('cities')
.delete()
.ilike('name', '%la%')
return cities
${errorJs}
`.trim()
export const deleteIsJs = `
${importJs}
const deleteCity = async () => {
try {
let cities = await supabase
.from('cities')
.delete()
.is('name', null)
return cities
${errorJs}
`.trim()
export const deleteInJs = `
${importJs}
const deleteCity = async () => {
try {
let cities = await supabase
.from('cities')
.delete()
.in('name', ['Rio de Janeiro', 'San Francisco'])
return cities
${errorJs}
`.trim()
export const deleteCsJs = `
${importJs}
const deleteCountry = async () => {
try {
let countries = await supabase
.from('countries')
.delete()
.cs('main_exports', ['oil'])
return countries
${errorJs}
`.trim()
export const deleteCdJs = `
${importJs}
const deleteCountry = async () => {
try {
let countries = await supabase
.from('countries')
.delete()
.cd('main_exports', ['cars', 'food', 'machine'])
return countries
${errorJs}
`.trim()
export const deleteOvaJs = `
${importJs}
const deleteCountry = async () => {
try {
let countries = await supabase
.from('countries')
.delete()
.ova('main_exports', ['computers', 'minerals'])
return countries
${errorJs}
`.trim()
export const deleteOvrJs = `
${importJs}
const deleteCountry = async () => {
try {
let countries = await supabase
.from('countries')
.delete()
.ovr('population_range_millions', [150, 250])
return countries
${errorJs}
`.trim()
export const deleteSlJs = `
${importJs}
const deleteCountry = async () => {
try {
let countries = await supabase
.from('countries')
.delete()
.sl('population_range_millions', [150, 250])
return countries
${errorJs}
`.trim()
export const deleteSrJs = `
${importJs}
const deleteCountry = async () => {
try {
let countries = await supabase
.from('countries')
.delete()
.sr('population_range_millions', [150, 250])
return countries
${errorJs}
`.trim()
export const deleteNxlJs = `
${importJs}
const deleteCountry = async () => {
try {
let countries = await supabase
.from('countries')
.delete()
.nxl('population_range_millions', [150, 250])
return countries
${errorJs}
`.trim()
export const deleteNxrJs = `
${importJs}
const deleteCountry = async () => {
try {
let countries = await supabase
.from('countries')
.delete()
.nxr('population_range_millions', [150, 250])
return countries
${errorJs}
`.trim()
export const deleteAdjJs = `
${importJs}
const deleteCountry = async () => {
try {
let countries = await supabase
.from('countries')
.delete()
.adj('population_range_millions', [70, 185])
return countries
${errorJs}
`.trim()
-459
View File
@@ -1,459 +0,0 @@
import {importJs, errorJs} from './common'
/**
* get.mdx examples
*/
export const getSimpleJs = `
${importJs}
const getCities = async () => {
try {
let cities = await supabase
.from('cities')
.select('name, country_id')
return cities
${errorJs}
`.trim()
export const getColumnsJs = `
${importJs}
const getCities = async () => {
try {
let cities = await supabase
.from('cities')
.select('name')
return cities
${errorJs}
`.trim()
export const getForeignJs = `
${importJs}
const getCountries = async () => {
try {
let countries = await supabase
.from('countries')
.select(\`
name,
cities (
name
)
\`)
return countries
${errorJs}
`.trim()
export const getForeignMultipleJs = `
${importJs}
const getProducts = async () => {
try {
let products = await supabase
.from('products')
.select(\`
id,
supplier:supplier_id ( name ),
purchaser:purchaser_id ( name )
\`)
return products
${errorJs}
`.trim()
export const getOrderJs = `
${importJs}
const getCities = async () => {
try {
let cities = await supabase
.from('cities')
.select('name', 'country_id')
.order('id')
return cities
${errorJs}
`.trim()
export const getEmbeddedOrderJs = `
${importJs}
const getCountries = async () => {
try {
let countries = await supabase
.from('countries')
.select('name, cities(name)')
.eq('name', 'United States')
.order('cities.name')
return countries
${errorJs}
`.trim()
export const getLimitJs = `
${importJs}
const getCities = async () => {
try {
let cities = await supabase
.from('cities')
.select('name, country_id')
.limit(1)
return cities
${errorJs}
`.trim()
export const getEmbeddedLimitJs = `
${importJs}
const getCountries = async () => {
try {
let countries = await supabase
.from('cities')
.select('name, cities(name)')
.eq('name', 'United States')
.limit(1, 'cities')
return countries
${errorJs}
`.trim()
export const getOffsetJs = `
${importJs}
const getCities = async () => {
try {
let cities = await supabase
.from('cities')
.select('name, country_id')
.offset(1)
return cities
${errorJs}
`.trim()
export const getEmbeddedOffsetJs = `
${importJs}
const getCountries = async () => {
try {
let countries = await supabase
.from('cities')
.select('name, cities(name)')
.eq('name', 'United States')
.offset(1, 'cities')
return countries
${errorJs}
`.trim()
export const getRangeJs = `
${importJs}
const getCities = async () => {
try {
let cities = await supabase
.from('cities')
.select('name, country_id')
.range(0,3)
return cities
${errorJs}
`.trim()
export const getSingleJs = `
${importJs}
const getCities = async () => {
try {
let cities = await supabase
.from('cities')
.select('name, country_id')
.single()
return cities
${errorJs}
`.trim()
export const getFilterJs = `
${importJs}
const getCities = async () => {
try {
let cities = await supabase
.from('cities')
.select('name, country_id')
.filter('name', 'eq', 'Paris')
return cities
${errorJs}
`.trim()
export const getFilterJsEmbedded = `
${importJs}
const getCities = async () => {
try {
let cities = await supabase
.from('cities')
.select('name, countries ( name )')
.filter('countries.name', 'eq', 'France')
return cities
${errorJs}
`.trim()
export const getNotJs = `
${importJs}
const getCities = async () => {
try {
let cities = await supabase
.from('cities')
.select('name, country_id')
.not('name', 'eq', 'Paris')
return cities
${errorJs}
`.trim()
export const getOrJs = `
${importJs}
const getCities = async () => {
try {
let cities = await supabase
.from('cities')
.select('name, country_id')
.or('id.gt.20,and(name.eq.New Zealand,name.eq.France)')
return cities
${errorJs}
`.trim()
export const getMatchJs = `
${importJs}
const getCities = async () => {
try {
let cities = await supabase
.from('cities')
.select('name, country_id')
.match({name: 'Beijing', country_id: 156})
return cities
${errorJs}
`.trim()
export const getEqJs = `
${importJs}
const getCities = async () => {
try {
let cities = await supabase
.from('cities')
.select('name, country_id')
.eq('name', 'San Francisco')
return cities
${errorJs}
`.trim()
export const getNeqJs = `
${importJs}
const getCities = async () => {
try {
let cities = await supabase
.from('cities')
.select('name, country_id')
.neq('name', 'Lagos')
return cities
${errorJs}
`.trim()
export const getGtJs = `
${importJs}
const getCities = async () => {
try {
let cities = await supabase
.from('cities')
.select('name, country_id')
.gt('country_id', 250)
return cities
${errorJs}
`.trim()
export const getLtJs = `
${importJs}
const getCities = async () => {
try {
let cities = await supabase
.from('cities')
.select('name, country_id')
.lt('country_id', 250)
return cities
${errorJs}
`.trim()
export const getGteJs = `
${importJs}
const getCities = async () => {
try {
let cities = await supabase
.from('cities')
.select('name, country_id')
.gte('country_id', 250)
return cities
${errorJs}
`.trim()
export const getLteJs = `
${importJs}
const getCities = async () => {
try {
let cities = await supabase
.from('cities')
.select('name, country_id')
.lte('country_id', 250)
return cities
${errorJs}
`.trim()
export const getLikeJs = `
${importJs}
const getCities = async () => {
try {
let cities = await supabase
.from('cities')
.select('name, country_id')
.like('name', '%la%')
return cities
${errorJs}
`.trim()
export const getIlikeJs = `
${importJs}
const getCities = async () => {
try {
let cities = await supabase
.from('cities')
.select('name, country_id')
.ilike('name', '%la%')
return cities
${errorJs}
`.trim()
export const getIsJs = `
${importJs}
const getCities = async () => {
try {
let cities = await supabase
.from('cities')
.select('name, country_id')
.is('name', null)
return cities
${errorJs}
`.trim()
export const getInJs = `
${importJs}
const getCities = async () => {
try {
let cities = await supabase
.from('cities')
.select('name, country_id')
.in('name', ['Rio de Janeiro', 'San Francisco'])
return cities
${errorJs}
`.trim()
export const getCsJs = `
${importJs}
const getCountries = async () => {
try {
let countries = await supabase
.from('countries')
.select('name, id, main_exports')
.cs('main_exports', ['oil'])
return countries
${errorJs}
`.trim()
export const getCdJs = `
${importJs}
const getCountries = async () => {
try {
let countries = await supabase
.from('countries')
.select('name, id, main_exports')
.cd('main_exports', ['cars', 'food', 'machine'])
return countries
${errorJs}
`.trim()
export const getOvaJs = `
${importJs}
const getCountries = async () => {
try {
let countries = await supabase
.from('countries')
.select('name, id, main_exports')
.ova('main_exports', ['computers', 'minerals'])
return countries
${errorJs}
`.trim()
export const getOvrJs = `
${importJs}
const getCountries = async () => {
try {
let countries = await supabase
.from('countries')
.select('name, id, population_range_millions')
.ovr('population_range_millions', [150, 250])
return countries
${errorJs}
`.trim()
export const getSlJs = `
${importJs}
const getCountries = async () => {
try {
let countries = await supabase
.from('countries')
.select('name, id, population_range_millions')
.sl('population_range_millions', [150, 250])
return countries
${errorJs}
`.trim()
export const getSrJs = `
${importJs}
const getCountries = async () => {
try {
let countries = await supabase
.from('countries')
.select('name, id, population_range_millions')
.sr('population_range_millions', [150, 250])
return countries
${errorJs}
`.trim()
export const getNxlJs = `
${importJs}
const getCountries = async () => {
try {
let countries = await supabase
.from('countries')
.select('name, id, population_range_millions')
.nxl('population_range_millions', [150, 250])
return countries
${errorJs}
`.trim()
export const getNxrJs = `
${importJs}
const getCountries = async () => {
try {
let countries = await supabase
.from('countries')
.select('name, id, population_range_millions')
.nxr('population_range_millions', [150, 250])
return countries
${errorJs}
`.trim()
export const getAdjJs = `
${importJs}
const getCountries = async () => {
try {
let countries = await supabase
.from('countries')
.select('name, id, population_range_millions')
.adj('population_range_millions', [70, 185])
return countries
${errorJs}
`.trim()
export const getJsonData = `
${importJs}
const getCountries = async () => {
try {
let countries = await supabase
.from('countries')
.select(\`
json_column_name->>population,
json_column_name->weather->>temperature
\`)
return countries
${errorJs}
`.trim()
-282
View File
@@ -1,282 +0,0 @@
import {importJs, errorJs} from './common'
/**
* patch.mdx examples
*/
export const patchRecordJs = `
${importJs}
const updateCityName = async () => {
try {
let updates = await supabase
.from('cities')
.update({ name: 'Middle Earth' })
.match({ name: 'Auckland' })
return updates
${errorJs}
`.trim()
export const patchFilterJs = `
${importJs}
const updateCityName = async () => {
try {
let cities = await supabase
.from('cities')
.update({ name: 'Mordor' })
.filter('name', 'eq', 'Paris')
return cities
${errorJs}
`.trim()
export const patchNotJs = `
${importJs}
const updateCities = async () => {
try {
let cities = await supabase
.from('cities')
.update({ name: 'Mordor' })
.not('name', 'eq', 'Paris')
return cities
${errorJs}
`.trim()
export const patchMatchJs = `
${importJs}
const updateCityName = async () => {
try {
let cities = await supabase
.from('cities')
.update({ name: 'Mordor' })
.match({name: 'Beijing', country_id: 156})
return cities
${errorJs}
`.trim()
export const patchEqJs = `
${importJs}
const updateCityName = async () => {
try {
let cities = await supabase
.from('cities')
.update({ name: 'Mordor' })
.eq('name', 'San Francisco')
return cities
${errorJs}
`.trim()
export const patchNeqJs = `
${importJs}
const updateCityName = async () => {
try {
let cities = await supabase
.from('cities')
.update({ name: 'Mordor' })
.neq('name', 'Lagos')
return cities
${errorJs}
`.trim()
export const patchGtJs = `
${importJs}
const updateCityName = async () => {
try {
let cities = await supabase
.from('cities')
.update({ name: 'Mordor' })
.gt('country_id', 250)
return cities
${errorJs}
`.trim()
export const patchLtJs = `
${importJs}
const updateCityName = async () => {
try {
let cities = await supabase
.from('cities')
.update({ name: 'Mordor' })
.lt('country_id', 250)
return cities
${errorJs}
`.trim()
export const patchGteJs = `
${importJs}
const updateCityName = async () => {
try {
let cities = await supabase
.from('cities')
.update({ name: 'Mordor' })
.gte('country_id', 250)
return cities
${errorJs}
`.trim()
export const patchLteJs = `
${importJs}
const updateCityName = async () => {
try {
let cities = await supabase
.from('cities')
.update({ name: 'Mordor' })
.lte('country_id', 250)
return cities
${errorJs}
`.trim()
export const patchLikeJs = `
${importJs}
const updateCityName = async () => {
try {
let cities = await supabase
.from('cities')
.update({ name: 'Mordor' })
.like('name', '%la%')
return cities
${errorJs}
}
`.trim()
export const patchIlikeJs = `
${importJs}
const updateCityName = async () => {
try {
let cities = await supabase
.from('cities')
.update({ name: 'Mordor' })
.ilike('name', '%la%')
return cities
${errorJs}
`.trim()
export const patchIsJs = `
${importJs}
const updateCityName = async () => {
try {
let cities = await supabase
.from('cities')
.update({ name: 'Mordor' })
.is('name', null)
return cities
${errorJs}
`.trim()
export const patchInJs = `
${importJs}
const updateCityName = async () => {
try {
let cities = await supabase
.from('cities')
.update({ name: 'Mordor' })
.in('name', ['Rio de Janeiro', 'San Francisco'])
return cities
${errorJs}
`.trim()
export const patchCsJs = `
${importJs}
const updateCountryName = async () => {
try {
let countries = await supabase
.from('countries')
.update({ name: 'Mordor' })
.cs('main_exports', ['oil'])
return countries
${errorJs}
`.trim()
export const patchCdJs = `
${importJs}
const updateCountryName = async () => {
try {
let countries = await supabase
.from('countries')
.update({ name: 'Mordor' })
.cd('main_exports', ['cars', 'food', 'machine'])
return countries
${errorJs}
`.trim()
export const patchOvaJs = `
${importJs}
const updateCountryName = async () => {
try {
let countries = await supabase
.from('countries')
.update({ name: 'Mordor' })
.ova('main_exports', ['computers', 'minerals'])
return countries
${errorJs}
`.trim()
export const patchOvrJs = `
${importJs}
const updateCountryName = async () => {
try {
let countries = await supabase
.from('countries')
.update({ name: 'Mordor' })
.ovr('population_range_millions', [150, 250])
return countries
${errorJs}
`.trim()
export const patchSlJs = `
${importJs}
const updateCountryName = async () => {
try {
let countries = await supabase
.from('countries')
.update({ name: 'Mordor' })
.sl('population_range_millions', [150, 250])
return countries
${errorJs}
`.trim()
export const patchSrJs = `
${importJs}
const updateCountryName = async () => {
try {
let countries = await supabase
.from('countries')
.update({ name: 'Mordor' })
.sr('population_range_millions', [150, 250])
return countries
${errorJs}
`.trim()
export const patchNxlJs = `
${importJs}
const updateCountryName = async () => {
try {
let countries = await supabase
.from('countries')
.update({ name: 'Mordor' })
.nxl('population_range_millions', [150, 250])
return countries
${errorJs}
`.trim()
export const patchNxrJs = `
${importJs}
const updateCountryName = async () => {
try {
let countries = await supabase
.from('countries')
.update({ name: 'Mordor' })
.nxr('population_range_millions', [150, 250])
return countries
${errorJs}
`.trim()
export const patchAdjJs = `
${importJs}
const updateCountryName = async () => {
try {
let countries = await supabase
.from('countries')
.update({ name: 'Mordor' })
.adj('population_range_millions', [70, 185])
return countries
${errorJs}
`.trim()
-65
View File
@@ -1,65 +0,0 @@
/**
* post.mdx examples
*/
export const postSingleJs = `
import { createClient } from '@supabase/supabase-js'
const supabase = createClient('https://world.supabase.co', '1a2b-3c4d-5e6f-7g8h')
const createCities = async () => {
try {
let cities = await supabase
.from('cities')
.insert([
{ name: 'The Shire', country_id: 554 }
])
return cities
} catch (error) {
console.log('Error: ', error)
}
}
`.trim()
export const postBulkJs = `
import { createClient } from '@supabase/supabase-js'
const supabase = createClient('https://world.supabase.co', '1a2b-3c4d-5e6f-7g8h')
const createCities = async () => {
try {
let cities = await supabase
.from('cities')
.insert([
{ name: 'The Shire', country_id: 554 },
{ name: 'Rohan', country_id: 555 },
])
return cities
} catch (error) {
console.log('Error: ', error)
}
}
`.trim()
export const postUpsertJs = `
import { createClient } from '@supabase/supabase-js'
const supabase = createClient('https://world.supabase.co', '1a2b-3c4d-5e6f-7g8h')
const createCities = async () => {
try {
let cities = 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 })
return cities
} catch (error) {
console.log('Error: ', error)
}
}
`.trim()
-282
View File
@@ -1,282 +0,0 @@
import {importJs, errorJs} from './common'
/**
* stored-procedures.mdx examples
*/
export const storedSingleJs = `
${importJs}
const echoCity = async () => {
try{
let city = await supabase
.rpc('echo_city', { name: 'The Shire' })
return cities
${errorJs}
}
`.trim()
export const storedBulkJs = `
${importJs}
const echoCities = async () => {
try{
let cities = await supabase
.rpc('echo_city', [
{ name: 'The Shire' },
{ name: 'Mordor' }
])
return cities
${errorJs}
}
`.trim()
export const storedReadingJs = `
${importJs}
const echoCities = async () => {
try{
let cities = await supabase
.rpc('echo_all_cities')
return cities
${errorJs}
`.trim()
export const storedFilterJs = `
${importJs}
const echoCities = async () => {
try {
let cities = await supabase
.rpc('echo_all_cities')
.filter({'name', 'eq', 'Paris'})
return cities
${errorJs}
`.trim()
export const storedNotJs = `
${importJs}
const echoCities = async () => {
try {
let cities = await supabase
.rpc('echo_all_cities)
.not('name', 'eq', 'Paris')
return cities
${errorJs}
`.trim()
export const storedMatchJs = `
${importJs}
const echoCities = async () => {
try {
let cities = await supabase
.rpc('echo_all_cities')
.match({name: 'Beijing', country_id: 156})
return cities
${errorJs}
`.trim()
export const storedEqJs = `
${importJs}
const echoCities = async () => {
try {
let cities = await supabase
.rpc('echo_all_cities')
.eq('name', 'San Francisco')
return cities
${errorJs}
`.trim()
export const storedNeqJs = `
${importJs}
const echoCities = async () => {
try {
let cities = await supabase
.rpc('echo_all_cities')
.neq('name', 'Lagos')
return cities
${errorJs}
`.trim()
export const storedGtJs = `
${importJs}
const echoCities = async () => {
try {
let cities = await supabase
.rpc('echo_all_cities')
.gt('country_id', 250)
return cities
${errorJs}
`.trim()
export const storedLtJs = `
${importJs}
const echoCities = async () => {
try {
let cities = await supabase
.rpc('echo_all_cities')
.lt('country_id', 250)
return cities
${errorJs}
`.trim()
export const storedGteJs = `
${importJs}
const echoCities = async () => {
try {
let cities = await supabase
.rpc('echo_all_cities')
.gte('country_id', 250)
return cities
${errorJs}
`.trim()
export const storedLteJs = `
${importJs}
const echoCities = async () => {
try {
let cities = await supabase
.rpc('echo_all_cities')
.lte('country_id', 250)
return cities
${errorJs}
`.trim()
export const storedLikeJs = `
${importJs}
const echoCities = async () => {
try {
let cities = await supabase
.rpc('echo_all_cities')
.like('name', '%la%')
return cities
${errorJs}
`.trim()
export const storedIlikeJs = `
${importJs}
const echoCities = async () => {
try {
let cities = await supabase
.rpc('echo_all_cities')
.ilike('name', '%la%')
return cities
${errorJs}
`.trim()
export const storedIsJs = `
${importJs}
const echoCities = async () => {
try {
let cities = await supabase
.rpc('echo_all_cities')
.is('name', null)
return cities
${errorJs}
`.trim()
export const storedInJs = `
${importJs}
const echoCities = async () => {
try {
let cities = await supabase
.rpc('echo_all_cities')
.in('name', ['Rio de Janeiro', 'San Francisco'])
return cities
${errorJs}
`.trim()
export const storedCsJs = `
${importJs}
const echoCountries = async () => {
try {
let countries = await supabase
.rpc('echo_all_countries')
.cs('main_exports', ['oil'])
return countries
${errorJs}
`.trim()
export const storedCdJs = `
${importJs}
const echoCountries = async () => {
try {
let countries = await supabase
.rpc('echo_all_countries')
.cd('main_exports', ['cars', 'food', 'machine'])
return countries
${errorJs}
`.trim()
export const storedOvaJs = `
${importJs}
const echoCountries = async () => {
try {
let countries = await supabase
.rpc('echo_all_countries')
.ova('main_exports', ['computers', 'minerals'])
return countries
${errorJs}
`.trim()
export const storedOvrJs = `
${importJs}
const echoCountries = async () => {
try {
let countries = await supabase
.rpc('echo_all_countries')
.ovr('population_range_millions', [150, 250])
return countries
${errorJs}
`.trim()
export const storedSlJs = `
${importJs}
const echoCountries = async () => {
try {
let countries = await supabase
.rpc('echo_all_countries')
.sl('population_range_millions', [150, 250])
return countries
${errorJs}
`.trim()
export const storedSrJs = `
${importJs}
const echoCountries = async () => {
try {
let countries = await supabase
.rpc('echo_all_countries')
.sr('population_range_millions', [150, 250])
return countries
${errorJs}
`.trim()
export const storedNxlJs = `
${importJs}
const echoCountries = async () => {
try {
let countries = await supabase
.rpc('echo_all_countries')
.nxl('population_range_millions', [150, 250])
return countries
${errorJs}
`.trim()
export const storedNxrJs = `
${importJs}
const echoCountries = async () => {
try {
let countries = await supabase
.rpc('echo_all_countries')
.nxr('population_range_millions', [150, 250])
return countries
${errorJs}
`.trim()
export const storedAdjJs = `
${importJs}
const echoCountries = async () => {
try {
let countries = await supabase
.rpc('echo_all_countries')
.adj('population_range_millions', [70, 185])
return countries
${errorJs}
`.trim()
-128
View File
@@ -1,128 +0,0 @@
/**
* subscribe.mdx examples
*/
export const subscribeAllJs = `
import { createClient } from '@supabase/supabase-js'
// Create a single supabase client for interacting with your database
const supabase = createClient('https://world.supabase.co', '1a2b-3c4d-5e6f-7g8h')
// Listen to changes
const mySubscription = supabase
.from('*')
.on('*', payload => {
console.log('Change received!', payload)
})
.subscribe()
`.trim()
export const subscribeTableJs = `
import { createClient } from '@supabase/supabase-js'
// Create a single supabase client for interacting with your database
const supabase = createClient('https://world.supabase.co', '1a2b-3c4d-5e6f-7g8h')
// Listen to changes
const mySubscription = supabase
.from('countries')
.on('*', payload => {
console.log('Change received!', payload)
})
.subscribe()
`.trim()
export const subscribeInsertsJs = `
import { createClient } from '@supabase/supabase-js'
// Create a single supabase client for interacting with your database
const supabase = createClient('https://world.supabase.co', '1a2b-3c4d-5e6f-7g8h')
// Listen to changes
const mySubscription = supabase
.from('countries')
.on('INSERT', payload => {
console.log('Change received!', payload)
})
.subscribe()
`.trim()
export const subscribeUpdatesJs = `
import { createClient } from '@supabase/supabase-js'
// Create a single supabase client for interacting with your database
const supabase = createClient('https://world.supabase.co', '1a2b-3c4d-5e6f-7g8h')
// Listen to changes
const mySubscription = supabase
.from('countries')
.on('UPDATE', payload => {
console.log('Change received!', payload)
})
.subscribe()
`.trim()
export const subscribeDeletesJs = `
import { createClient } from '@supabase/supabase-js'
// Create a single supabase client for interacting with your database
const supabase = createClient('https://world.supabase.co', '1a2b-3c4d-5e6f-7g8h')
// Listen to changes
const mySubscription = supabase
.from('countries')
.on('DELETE', payload => {
console.log('Change received!', payload)
})
.subscribe()
`.trim()
export const subscribeMultipleJs = `
import { createClient } from '@supabase/supabase-js'
// Create a single supabase client for interacting with your database
const supabase = createClient('https://world.supabase.co', '1a2b-3c4d-5e6f-7g8h')
// Listen to changes
const mySubscription = supabase
.from('countries')
.on('INSERT', handleRecordInserted)
.on('DELETE', handleRecordDeleted)
.subscribe()
`.trim()
export const subscribeUnsubscribeJs = `
import { createClient } from '@supabase/supabase-js'
// Create a single supabase client for interacting with your database
const supabase = createClient('https://world.supabase.co', '1a2b-3c4d-5e6f-7g8h')
// Listen to changes
const mySubscription = supabase
.from('countries')
.on('*', payload => {
console.log('Change received!', payload)
})
.subscribe()
// Unsubscribe from changes
mySubscription.unsubscribe()
`.trim()
export const subscribeRemoveJs = `
import { createClient } from '@supabase/supabase-js'
// Create a single supabase client for interacting with your database
const supabase = createClient('https://world.supabase.co', '1a2b-3c4d-5e6f-7g8h')
// Listen to changes
const mySubscription = supabase
.from('countries')
.on('*', payload => {
console.log('Change received!', payload)
})
.subscribe()
// Disconnect mySubscription
supabase.removeSubscription(mySubscription)
`.trim()
-56
View File
@@ -1,56 +0,0 @@
export const signup = `
const {
body: { user },
} = await supabase.auth.signup(
'someone@email.com',
'password'
)
`.trim()
export const login = `
const {
body: { user },
} = await supabase.auth.login(
'someone@email.com',
'password'
)
`.trim()
export const userData = `
const user = await supabase.auth.user()
`.trim()
export const logout = `
await supabase.auth.logout()
`.trim()
export const errorHandling = `
try {
const res = await supabase
.auth
.login('someone@email.com', 'password')
} catch (error) {
if (error.response === undefined) {
// No response from server
} else {
const server_response = error.response
// Here you can further process the response ..
}
if (error.status === undefined) {
// No HTTP status code
} else {
const http_code = error.status
// Further processing ..
}
}
`.trim()
export const setAccessToken = `
supabase.auth.saveSession(
access_token, // from callback URL
refresh_token, // from callback URL
Math.round(Date.now() / 1000) + expires_in, // current time + seconds from callback URL
null // currentUser not present yet
)
`.trim()
File diff suppressed because it is too large. Load diff
-649
View File
@@ -1,649 +0,0 @@
---
id: patch
title: 'Updating'
description: 'How to update records in your database with Supabase'
---
import DummyData from '../common/_DummyData.mdx'
import Collapsable from '../../src/components/Collapsable'
import CommonResponses from '../common/_CommonResponses.mdx'
import CommonFilters from '../common/CommonFilters'
import FromFunction from '../common/_FromFunction.mdx'
import CustomCodeBlock from '../../src/components/CustomCodeBlock'
import {
patchRecordJs,
patchFilterJs,
patchNotJs,
patchMatchJs,
patchEqJs,
patchNeqJs,
patchGtJs,
patchLtJs,
patchGteJs,
patchLteJs,
patchLikeJs,
patchIlikeJs,
patchIsJs,
patchInJs,
patchCsJs,
patchCdJs,
patchOvaJs,
patchOvrJs,
patchSlJs,
patchSrJs,
patchNxlJs,
patchNxrJs,
patchAdjJs,
} from './examples/patch'
<DummyData />
### Update record
<CustomCodeBlock
header="Updates information about a city."
js={patchRecordJs}
jsHighlight="{7-10}"
response={`{
"body": [
{ "name": "Middle Earth", "country_id": 554 },
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}`}
/>
## Reference
### `from()`
<FromFunction verb="patch" />
### `update()`
```js {3}
supabase
.from(tableName)
.update(data)
```
It is to note that it is required to apply filters when using `.update()`. Not using filters would result in an error.
#### `data: object`
New record values.
---
## Filtering
### `filter()`
<CustomCodeBlock
header="Shows how to use filter( ) with update( )"
js={patchFilterJs}
jsHighlight="{10}"
response={`{
"body": [
{ "name": "Mordor", "country_id": 250 },
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}`}
/>
<br />
<CommonFilters filter="filter" />
### `not()`
<CustomCodeBlock
header="Shows how to use not( ) with update( )"
js={patchNotJs}
jsHighlight="{10}"
response={`{
"body": [
{ "name": "Mordor", "country_id": 76 },
{ "name": "Mordor", "country_id": 156 },
{ "name": "Mordor", "country_id": 554 },
{ "name": "Mordor", "country_id": 556 },
{ "name": "Mordor", "country_id": 840 }
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}`}
/>
<br />
<CommonFilters filter="not" />
### `match()`
<CustomCodeBlock
header="Shows how to use match( ) with update( )"
js={patchMatchJs}
jsHighlight="{10}"
response={`{
"body": [
{ "name": "Mordor", "country_id": 156 },
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}`}
/>
<br />
<CommonFilters filter="match" />
### `eq()`
<CustomCodeBlock
header="Shows how to use eq( ) with update( )"
js={patchEqJs}
jsHighlight="{10}"
response={`{
"body": [
{ "name": "Mordor", "country_id": 840 },
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}`}
/>
<br />
<CommonFilters filter="eq" />
### `neq()`
<CustomCodeBlock
header="Shows how to use neq( ) with update( )"
js={patchNeqJs}
jsHighlight="{10}"
response={`{
"body": [
{ "name": "Mordor", "country_id": 76 },
{ "name": "Mordor", "country_id": 156 },
{ "name": "Mordor", "country_id": 250 },
{ "name": "Mordor", "country_id": 554 },
{ "name": "Mordor", "country_id": 556 },
{ "name": "Mordor", "country_id": 840 },
{ "name": "Mordor", "country_id": 840 }
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}`}
/>
<br />
<CommonFilters filter="neq" />
### `gt()`
<CustomCodeBlock
header="Shows how to use gt( ) with update( )"
js={patchGtJs}
jsHighlight="{10}"
response={`{
"body": [
{ "name": "Mordor", "country_id": 554 },
{ "name": "Mordor", "country_id": 556 },
{ "name": "Mordor", "country_id": 840 },
{ "name": "Mordor", "country_id": 840 }
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}`}
/>
<br />
<CommonFilters filter="gt" />
### `lt()`
<CustomCodeBlock
header="Shows how to use lt( ) with update( )"
js={patchLtJs}
jsHighlight="{10}"
response={`{
"body": [
{ "name": "Mordor", "country_id": 76 },
{ "name": "Mordor", "country_id": 156 }
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}`}
/>
<br />
<CommonFilters filter="lt" />
### `gte()`
<CustomCodeBlock
header="Shows how to use gte( ) with update( )"
js={patchGteJs}
jsHighlight="{10}"
response={`{
"body": [
{ "name": "Mordor", "country_id": 250 },
{ "name": "Mordor", "country_id": 554 },
{ "name": "Mordor", "country_id": 556 },
{ "name": "Mordor", "country_id": 840 },
{ "name": "Mordor", "country_id": 840 }
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}`}
/>
<br />
<CommonFilters filter="gte" />
### `lte()`
<CustomCodeBlock
header="Shows how to use lte( ) with update( )"
js={patchLteJs}
jsHighlight="{10}"
response={`{
"body": [
{ "name": "Mordor", "country_id": 76 },
{ "name": "Mordor", "country_id": 156 },
{ "name": "Mordor", "country_id": 250 }
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}`}
/>
<br />
<CommonFilters filter="lte" />
### `like()`
<CustomCodeBlock
header="Shows how to use like( ) with update( )"
js={patchLikeJs}
jsHighlight="{10}"
response={`{
"body": [
{ "name": "Mordor", "country_id": 554 },
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}`}
/>
<br />
<CommonFilters filter="like" />
### `ilike()`
<CustomCodeBlock
header="Shows how to use ilike( ) with update( )"
js={patchIlikeJs}
jsHighlight="{10}"
response={`{
"body": [
{ "name": "Mordor", "country_id": 554 },
{ "name": "Mordor", "country_id": 556 },
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}`}
/>
<br />
<CommonFilters filter="ilike" />
### `is()`
<CustomCodeBlock
header="Shows how to use is( ) with update( )"
js={patchIsJs}
jsHighlight="{10}"
response={`{
"body": [
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}`}
/>
<br />
<CommonFilters filter="is" />
### `in()`
<CustomCodeBlock
header="Shows how to use in( ) with update( )"
js={patchInJs}
jsHighlight="{10}"
response={`{
"body": [
{ "name": "Mordor", "country_id": 76 },
{ "name": "Mordor", "country_id": 840 }
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}`}
/>
<br />
<CommonFilters filter="in" />
### `cs()`
<CustomCodeBlock
header="Shows how to use cs( ) with update( )"
js={patchCsJs}
jsHighlight="{10}"
response={`{
"body": [
{ "id": 556,
"name": "Mordor",
"population_range_millions": [185, 195]
"main_exports": ["oil", "beans"],
},
{ "id": 840,
"name": "Mordor",
"population_range_millions": [320, 330]
"main_exports": ["oil", "cars", "food"],
}
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}`}
/>
<br />
<CommonFilters filter="cs" />
### `cd()`
<CustomCodeBlock
header="Shows how to use cd( ) with update( )"
js={patchCdJs}
jsHighlight="{10}"
response={`{
"body": [
{ "id": 250,
"name": "Mordor",
"population_range_millions": [60, 70]
"main_exports": ["cars", "machines"],
},
{ "id": 554,
"name": "Mordor",
"population_range_millions": [4, 6]
"main_exports": ["food", "machines"],
}
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}`}
/>
<br />
<CommonFilters filter="cd" />
### `ova()`
<CustomCodeBlock
header="Shows how to use ova( ) with update( )"
js={patchOvaJs}
jsHighlight="{10}"
response={`{
"body": [
{ "id": 76,
"name": "Mordor",
"population_range_millions": [205, 215]
"main_exports": ["beans", "minerals"],
},
{ "id": 156,
"name": "Mordor",
"population_range_millions": [1380, 1390]
"main_exports": ["computers", "phones"],
}
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}`}
/>
<br />
<CommonFilters filter="ova" />
### `ovr()`
<CustomCodeBlock
header="Shows how to use ovr( ) with update( )"
js={patchOvrJs}
jsHighlight="{10}"
response={`{
"body": [
{ "id": 76,
"name": "Mordor",
"population_range_millions": [205, 215]
"main_exports": ["beans", "minerals"],
},
{ "id": 556,
"name": "Mordor",
"population_range_millions": [185, 195]
"main_exports": ["oil", "beans"],
}
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}`}
/>
<br />
<CommonFilters filter="ovr" />
### `sl()`
<CustomCodeBlock
header="Shows how to use sl( ) with update( )"
js={patchSlJs}
jsHighlight="{10}"
response={`{
"body": [
{ "id": 250,
"name": "Mordor",
"population_range_millions": [60, 70]
"main_exports": ["cars", "machines"],
},
{ "id": 554,
"name": "Mordor",
"population_range_millions": [4, 6]
"main_exports": ["food", "machines"],
}
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}`}
/>
<br />
<CommonFilters filter="sl" />
### `sr()`
<CustomCodeBlock
header="Shows how to use sr( ) with update( )"
js={patchSrJs}
jsHighlight="{10}"
response={`{
"body": [
{ "id": 156,
"name": "Mordor",
"population_range_millions": [1380, 1390]
"main_exports": ["computers", "phones"],
},
{ "id": 840,
"name": "Mordor",
"population_range_millions": [320, 330]
"main_exports": ["oil", "cars", "food"],
}
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}`}
/>
<br />
<CommonFilters filter="sr" />
### `nxl()`
<CustomCodeBlock
header="Shows how to use nxl( ) with update( )"
js={patchNxlJs}
jsHighlight="{10}"
response={`{
"body": [
{ "id": 76,
"name": "Mordor",
"population_range_millions": [205, 215]
"main_exports": ["beans", "minerals"],
},
{ "id": 156,
"name": "Mordor",
"population_range_millions": [1380, 1390]
"main_exports": ["computers", "phones"],
},
{ "id": 556,
"name": "Mordor",
"population_range_millions": [185, 195]
"main_exports": ["oil", "beans"],
},
{ "id": 840,
"name": "Mordor",
"population_range_millions": [320, 330]
"main_exports": ["oil", "cars", "food"],
}
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}`}
/>
<br />
<CommonFilters filter="nxl" />
### `nxr()`
<CustomCodeBlock
header="Shows how to use nxr( ) with update( )"
js={patchNxrJs}
jsHighlight="{10}"
response={`{
"body": [
{ "id": 76,
"name": "Mordor",
"population_range_millions": [205, 215]
"main_exports": ["beans", "minerals"],
},
{ "id": 250,
"name": "Mordor",
"population_range_millions": [60, 70]
"main_exports": ["cars", "machines"],
},
{ "id": 554,
"name": "Mordor",
"population_range_millions": [4, 6]
"main_exports": ["food", "machines"],
},
{ "id": 556,
"name": "Mordor",
"population_range_millions": [185, 195]
"main_exports": ["oil", "beans"],
}
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}`}
/>
<br />
<CommonFilters filter="nxr" />
### `adj()`
<CustomCodeBlock
header="Shows how to use adj( ) with update( )"
js={patchAdjJs}
jsHighlight="{10}"
response={`{
"body": [
{ "id": 250,
"name": "Mordor",
"population_range_millions": [60, 70]
"main_exports": ["cars", "machines"],
},
{ "id": 556,
"name": "Mordor",
"population_range_millions": [185, 195]
"main_exports": ["oil", "beans"],
}
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}`}
/>
<br />
<CommonFilters filter="adj" />
## Responses
#### 200 OK
Successful request
<CommonResponses />
-103
View File
@@ -1,103 +0,0 @@
---
id: post
title: 'Creating'
description: 'Add new records to your database with Supabase'
---
import DummyData from '../common/_DummyData.mdx'
import Collapsable from '../../src/components/Collapsable'
import CommonResponses from '../common/_CommonResponses.mdx'
import FromFunction from '../common/_FromFunction.mdx'
import CustomCodeBlock from '../../src/components/CustomCodeBlock'
import { postSingleJs, postBulkJs, postUpsertJs } from './examples/post'
<DummyData />
### Create a record
<CustomCodeBlock
header="Creates a new city."
js={postSingleJs}
jsHighlight="{7-11}"
response={`{
"body": [
{ "name": "The Shire", "country_id": 554}
],
"status": 201,
"statusCode": 201,
"statusText": "Created"
}`}
/>
### Bulk create
<CustomCodeBlock
header="Creates multiple new cities."
js={postBulkJs}
jsHighlight="{7-12}"
response={`{
"body": [
{ "name": "The Shire", "country_id": 554},
{ "name": "Rohan", "country_id": 555}
],
"status": 201,
"statusCode": 201,
"statusText": "Created"
}`}
/>
### Upsert
<CustomCodeBlock
header="Creates multiple new cities and updates existing ones."
js={postUpsertJs}
jsHighlight="{7-15}"
response={`{
"body": [
{ "name": "The Shire", "country_id": 554},
{ "name": "Rohan", "country_id": 555},
{ "name": "City by the Bay", "country_id":840}
],
"status": 201,
"statusCode": 201,
"statusText": "Created"
}`}
/>
## Reference
### `from()`
<FromFunction verb='post' />
### `insert()`
```js {3}
supabase
.from(tableName)
.insert(data, options?)
```
#### `data: { array | object }`
A single `object` or an array of rows of type `object` which contain information to be saved into the selected table.
#### `options: object?`
```js
const options = {
upsert: false // Set to true to allow upserting.
}
```
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.
---
## Responses
#### 201 Created
Successful
<CommonResponses />
-705
View File
@@ -1,705 +0,0 @@
---
id: stored-procedures
title: 'Stored Procedures'
description: 'How to use stored procedures (rpc) with Supabase'
---
import Collapsable from '../../src/components/Collapsable'
import CommonFilters from '../common/CommonFilters'
import CommonResponses from '../common/_CommonResponses.mdx'
import DummyData from '../common/_DummyData.mdx'
import CustomCodeBlock from '../../src/components/CustomCodeBlock'
import {
storedSingleJs,
storedBulkJs,
storedReadingJs,
storedFilterJs,
storedNotJs,
storedMatchJs,
storedEqJs,
storedNeqJs,
storedGtJs,
storedLtJs,
storedGteJs,
storedLteJs,
storedLikeJs,
storedIlikeJs,
storedIsJs,
storedInJs,
storedCsJs,
storedCdJs,
storedOvaJs,
storedOvrJs,
storedSlJs,
storedSrJs,
storedNxlJs,
storedNxrJs,
storedAdjJs,
} from './examples/stored'
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.
This is especially useful when the logic rarely changes - like password resets and updates.
Here, we have three stored procedures that will act as our examples:
`echo_city` : Takes in objects containing a city name and returns that name.
`echo_all_cities` : Returns all rows in the table **Cities**.
`echo_all_countries` : Returns all rows in the table **Countries**.
<DummyData />
### Single call
<CustomCodeBlock
header="Example of invoking a stored procedure that taking in a name of a city and returning it."
js={storedSingleJs}
jsHighlight="{7-8}"
response={`{
"body": [
{"echo_city": "The Shire"}
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}
`}
/>
### Bulk call
This example would call a the same stored procedure above (twice), but it will also wait to receive the response only when all the calls have completed:
<CustomCodeBlock
header="Example of invoking the same stored procedure multiple times within one call."
js={storedBulkJs}
jsHighlight="{7-11}"
response={`{
"body": [
{"echo_city": "The Shire"},
{"echo_city": "Mordor"}
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}
`}
/>
### Reading data
This example shows how to call a stored function that returns a table type response:
<CustomCodeBlock
header="Example of invoking the same stored procedure multiple times within one call."
js={storedReadingJs}
jsHighlight="{7-8}"
response={`{
"body": [
{ "name": "Rio de Janeiro", "country_id": 76 },
{ "name": "Beijing", "country_id": 156 },
{ "name": "Paris", "country_id": 250 },
{ "name": "Auckland", "country_id": 554 },
{ "name": "Lagos", "country_id": 556 },
{ "name": "San Francisco", "country_id": 840 }
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}
`}
/>
## Reference
### `rpc()`
```js {2}
supabase.rpc(functionName, functionParameters)
```
#### `functionName: string`
Name of stored function in the database.
#### `functionParameters: { object? | array? }`
Parameters to be passed to the stored function.
---
## Filtering
### `filter()`
<CustomCodeBlock
header="Shows how to use filter( ) with rpc( )"
js={storedFilterJs}
jsHighlight="{9}"
response={`{
"body": [
{ "name": "Paris", "country_id": 250 },
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}`}
/>
<br />
<CommonFilters filter="filter" />
### `not()`
<CustomCodeBlock
header="Shows how to use not( ) with rpc( )"
js={storedNotJs}
jsHighlight="{9}"
response={`{
"body": [
{ "name": "Rio de Janeiro", "country_id": 76 },
{ "name": "Beijing", "country_id": 156 },
{ "name": "Auckland", "country_id": 554 },
{ "name": "Lagos", "country_id": 556 },
{ "name": "San Francisco", "country_id": 840 }
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}`}
/>
<br />
<CommonFilters filter="not" />
### `match()`
<CustomCodeBlock
header="Shows how to use match( ) with rpc( )"
js={storedMatchJs}
jsHighlight="{9}"
response={`{
"body": [
{ "name": "Beijing", "country_id": 156 },
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}`}
/>
<br />
<CommonFilters filter="match" />
### `eq()`
<CustomCodeBlock
header="Shows how to use eq( ) with rpc( )"
js={storedEqJs}
jsHighlight="{9}"
response={`{
"body": [
{ "name": "San Francisco", "country_id": 840 },
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}`}
/>
<br />
<CommonFilters filter="eq" />
### `neq()`
<CustomCodeBlock
header="Shows how to use neq( ) with rpc( )"
js={storedNeqJs}
jsHighlight="{9}"
response={`{
"body": [
{ "name": "Rio de Janeiro", "country_id": 76 },
{ "name": "Beijing", "country_id": 156 },
{ "name": "Paris", "country_id": 250 },
{ "name": "Auckland", "country_id": 554 },
{ "name": "Lagos", "country_id": 556 },
{ "name": "San Francisco", "country_id": 840 }
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}`}
/>
<br />
<CommonFilters filter="neq" />
### `gt()`
<CustomCodeBlock
header="Shows how to use gt( ) with rpc( )"
js={storedGtJs}
jsHighlight="{9}"
response={`{
"body": [
{ "name": "Auckland", "country_id": 554 },
{ "name": "Lagos", "country_id": 556 },
{ "name": "San Francisco", "country_id": 840 }
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}`}
/>
<br />
<CommonFilters filter="gt" />
### `lt()`
<CustomCodeBlock
header="Shows how to use lt( ) with rpc( )"
js={storedLtJs}
jsHighlight="{9}"
response={`{
"body": [
{ "name": "Rio de Janeiro", "country_id": 76 },
{ "name": "Beijing", "country_id": 156 }
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}`}
/>
<br />
<CommonFilters filter="lt" />
### `gte()`
<CustomCodeBlock
header="Shows how to use gte( ) with rpc( )"
js={storedGteJs}
jsHighlight="{9}"
response={`{
"body": [
{ "name": "Paris", "country_id": 250 },
{ "name": "Auckland", "country_id": 554 },
{ "name": "Lagos", "country_id": 556 },
{ "name": "San Francisco", "country_id": 840 }
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}`}
/>
<br />
<CommonFilters filter="gte" />
### `lte()`
<CustomCodeBlock
header="Shows how to use lte( ) with rpc( )"
js={storedLteJs}
jsHighlight="{9}"
response={`{
"body": [
{ "name": "Rio de Janeiro", "country_id": 76 },
{ "name": "Beijing", "country_id": 156 },
{ "name": "Paris", "country_id": 250 }
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}`}
/>
<br />
<CommonFilters filter="lte" />
### `like()`
<CustomCodeBlock
header="Shows how to use like( ) with rpc( )"
js={storedLikeJs}
jsHighlight="{9}"
response={`{
"body": [
{ "name": "Auckland", "country_id": 554 },
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}`}
/>
<br />
<CommonFilters filter="like" />
### `ilike()`
<CustomCodeBlock
header="Shows how to use ilike( ) with rpc( )"
js={storedIlikeJs}
jsHighlight="{9}"
response={`{
"body": [
{ "name": "Auckland", "country_id": 554 },
{ "name": "Lagos", "country_id": 556 },
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}`}
/>
<br />
<CommonFilters filter="ilike" />
### `is()`
<CustomCodeBlock
header="Shows how to use is( ) with rpc( )"
js={storedIsJs}
jsHighlight="{9}"
response={`{
"body": [
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}`}
/>
<br />
<CommonFilters filter="is" />
### `in()`
<CustomCodeBlock
header="Shows how to use in( ) with rpc( )"
js={storedInJs}
jsHighlight="{9}"
response={`{
"body": [
{ "name": "Rio de Janeiro", "country_id": 76 },
{ "name": "San Francisco", "country_id": 840 }
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}`}
/>
<br />
<CommonFilters filter="in" />
### `cs()`
<CustomCodeBlock
header="Shows how to use cs( ) with rpc( )"
js={storedCsJs}
jsHighlight="{9}"
response={`{
"body": [
{ "id": 556,
"name": "Nigeria",
"population_range_millions": [185, 195]
"main_exports": ["oil", "beans"],
},
{ "id": 840,
"name": "United States",
"population_range_millions": [320, 330]
"main_exports": ["oil", "cars", "food"],
}
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}`}
/>
<br />
<CommonFilters filter="cs" />
### `cd()`
<CustomCodeBlock
header="Shows how to use cd( ) with rpc( )"
js={storedCdJs}
jsHighlight="{9}"
response={`{
"body": [
{ "id": 250,
"name": "France",
"population_range_millions": [60, 70]
"main_exports": ["cars", "machines"],
},
{ "id": 554,
"name": "New Zealand",
"population_range_millions": [4, 6]
"main_exports": ["food", "machines"],
}
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}`}
/>
<br />
<CommonFilters filter="cd" />
### `ova()`
<CustomCodeBlock
header="Shows how to use ova( ) with rpc( )"
js={storedOvaJs}
jsHighlight="{9}"
response={`{
"body": [
{ "id": 76,
"name": "Brazil",
"population_range_millions": [205, 215]
"main_exports": ["beans", "minerals"],
},
{ "id": 156,
"name": "China",
"population_range_millions": [1380, 1390]
"main_exports": ["computers", "phones"],
}
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}`}
/>
<br />
<CommonFilters filter="ova" />
### `ovr()`
<CustomCodeBlock
header="Shows how to use ovr( ) with rpc( )"
js={storedOvrJs}
jsHighlight="{9}"
response={`{
"body": [
{ "id": 76,
"name": "Brazil",
"population_range_millions": [205, 215]
"main_exports": ["beans", "minerals"],
},
{ "id": 556,
"name": "Nigeria",
"population_range_millions": [185, 195]
"main_exports": ["oil", "beans"],
}
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}`}
/>
<br />
<CommonFilters filter="ovr" />
### `sl()`
<CustomCodeBlock
header="Shows how to use sl( ) with rpc( )"
js={storedSlJs}
jsHighlight="{9}"
response={`{
"body": [
{ "id": 250,
"name": "France",
"population_range_millions": [60, 70]
"main_exports": ["cars", "machines"],
},
{ "id": 554,
"name": "New Zealand",
"population_range_millions": [4, 6]
"main_exports": ["food", "machines"],
}
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}`}
/>
<br />
<CommonFilters filter="sl" />
### `sr()`
<CustomCodeBlock
header="Shows how to use sr( ) with rpc( )"
js={storedSrJs}
jsHighlight="{9}"
response={`{
"body": [
{ "id": 156,
"name": "China",
"population_range_millions": [1380, 1390]
"main_exports": ["computers", "phones"],
},
{ "id": 840,
"name": "United States",
"population_range_millions": [320, 330]
"main_exports": ["oil", "cars", "food"],
}
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}`}
/>
<br />
<CommonFilters filter="sr" />
### `nxl()`
<CustomCodeBlock
header="Shows how to use nxl( ) with rpc( )"
js={storedNxlJs}
jsHighlight="{9}"
response={`{
"body": [
{ "id": 76,
"name": "Brazil",
"population_range_millions": [205, 215]
"main_exports": ["beans", "minerals"],
},
{ "id": 156,
"name": "China",
"population_range_millions": [1380, 1390]
"main_exports": ["computers", "phones"],
},
{ "id": 556,
"name": "Nigeria",
"population_range_millions": [185, 195]
"main_exports": ["oil", "beans"],
},
{ "id": 840,
"name": "United States",
"population_range_millions": [320, 330]
"main_exports": ["oil", "cars", "food"],
}
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}`}
/>
<br />
<CommonFilters filter="nxl" />
### `nxr()`
<CustomCodeBlock
header="Shows how to use nxr( ) with rpc( )"
js={storedNxrJs}
jsHighlight="{9}"
response={`{
"body": [
{ "id": 76,
"name": "Brazil",
"population_range_millions": [205, 215]
"main_exports": ["beans", "minerals"],
},
{ "id": 250,
"name": "France",
"population_range_millions": [60, 70]
"main_exports": ["cars", "machines"],
},
{ "id": 554,
"name": "New Zealand",
"population_range_millions": [4, 6]
"main_exports": ["food", "machines"],
},
{ "id": 556,
"name": "Nigeria",
"population_range_millions": [185, 195]
"main_exports": ["oil", "beans"],
}
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}`}
/>
<br />
<CommonFilters filter="nxr" />
### `adj()`
<CustomCodeBlock
header="Shows how to use adj( ) with rpc( )"
js={storedAdjJs}
jsHighlight="{9}"
response={`{
"body": [
{ "id": 250,
"name": "France",
"population_range_millions": [60, 70]
"main_exports": ["cars", "machines"],
},
{ "id": 556,
"name": "Nigeria",
"population_range_millions": [185, 195]
"main_exports": ["oil", "beans"],
}
],
"status": 200,
"statusCode": 200,
"statusText": "OK"
}`}
/>
<br />
<CommonFilters filter="adj" />
## Responses
#### 200 OK
Successful request
#### 201 Created
Successful
<CommonResponses />
-293
View File
@@ -1,293 +0,0 @@
---
id: subscribe
title: 'Subscribing'
description: 'Subscribe to realtime changes in your database with Supabase'
---
import DummyData from '../common/_DummyData.mdx'
import FromFunction from '../common/_FromFunction.mdx'
import Collapsable from '../../src/components/Collapsable'
import CustomCodeBlock from '../../src/components/CustomCodeBlock'
import {
subscribeAllJs,
subscribeTableJs,
subscribeInsertsJs,
subscribeUpdatesJs,
subscribeDeletesJs,
subscribeMultipleJs,
subscribeUnsubscribeJs,
subscribeRemoveJs,
} from './examples/subscribe'
Subscribe to realtime changes in your own database.
We will be using these tables as reference for our examples.
<DummyData />
### Listen to all database changes
<CustomCodeBlock
header="Subscribes to all database changes in realtime."
js={subscribeAllJs}
jsHighlight="{8}"
/>
<br />
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;`
### Listening to a specific table
<CustomCodeBlock
header="Subscribes to a specific table for changes in realtime."
js={subscribeTableJs}
jsHighlight="{8}"
/>
<br />
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;`
### Listening only to INSERT
<CustomCodeBlock
header="Subscribes only to the INSERT event."
js={subscribeInsertsJs}
jsHighlight="{9-11}"
/>
### Listening only to UPDATE
<CustomCodeBlock
header="Subscribes only to the UPDATE event."
js={subscribeUpdatesJs}
jsHighlight="{9-11}"
/>
<br />
If you want to receive the "previous" data for updates,
you will need to set `REPLICA IDENTITY` to `FULL`, like this:
`ALTER TABLE your_table REPLICA IDENTITY FULL;`
### Listening only to DELETE
<CustomCodeBlock
header="Subscribes only to the DELETE event."
js={subscribeDeletesJs}
jsHighlight="{9-11}"
/>
<br />
You will not be able to delete data from your database unless you set your set your table to use FULL `REPLICA IDENTITY`, like this:
`ALTER TABLE your_table REPLICA IDENTITY FULL;`
<!-- ### Listening to multiple events
<CustomCodeBlock
header="Subscribes to multiple but not all events."
js={subscribeMultipleJs}
jsHighlight="{9-10}"
/> -->
### Unsubscribing
<CustomCodeBlock
header="Unsubscribes from a specific subscription."
js={subscribeUnsubscribeJs}
jsHighlight="{15}"
/>
### Removing a subscription
<CustomCodeBlock
header="Disconnects from a subscription fully."
js={subscribeRemoveJs}
jsHighlight="{15}"
/>
## Reference
### `from()`
<FromFunction verb="subscribe" />
### `on()`
<!-- prettier-ignore -->
```js {3}
const mySubscription = supabase
.from('tableName')
.on('eventType', callbackFunction)
```
#### `eventType: string { "INSERT" | "UPDATE" | "DELETE" | "*" }`
The database event which you would like to receive updates for, or you can use the special wildcard `*` to listen to all changes.
#### `callbackFunction: function`
A callback that will handle the payload that is sent whenever your database changes. See all Change Events below to understand all the possible payloads.
---
### `subscribe()`
<!-- prettier-ignore -->
```js {4}
const mySubscription = supabase
.from(tableName)
.on(eventType, callbackFunction)
.subscribe()
```
Subscribes to the database table specified in `from()` and starts listening to it. An object of type _subscription_ will be returned.
```js {1}
mySubscription.subscribe()
```
If the subscription already exists, but has been unsubscribed from with the function `unsubscribe()`, it can be subscribed to again through the above method.
---
### `unsubscribe()`
<!-- prettier-ignore -->
```js {2}
mySubscription
.unsubscribe()
```
Stop listening to changes. At any point you can call `subscribe` on the subscription object to restart the listeners.
If you don't need to connect again in the future, use `removeSubscription()` instead.
---
### `removeSubscription()`
<!-- prettier-ignore -->
```js {2}
supabase
.removeSubscription(mySubscription)
```
Disconnects and destroys a subscription. This is the preferred method for cleaning up subscriptions which you no longer require.
#### `mySubscription: subscription`
A subscription that was previously created. If you don't have access to the subscription, you can always call `getSubscriptions()`.
---
### `getSubscriptions()`
<!-- prettier-ignore -->
```js {2}
supabase
.getSubscriptions()
```
Returns an array of all your subscriptions (including disconnected subscriptions).
<Collapsable title="Toggle Example Response">
<!-- prettier-ignore -->
```js
[
{
uuid: 'xxxx-xxxx-xxxx-xxxx',
state: 'CONNECTED',
tableName: 'users',
eventListeners: {
'*': null,
'INSERT': null,
'UPDATE': null,
'DELETE': null,
}
},
{
uuid: 'yyyy-yyyy-yyyy-yyyy',
state: 'DISCONNECTED',
tableName: 'messages',
eventListeners: {
'*': null,
'INSERT': null,
'UPDATE': null,
'DELETE': null,
}
}
]
```
</Collapsable>
---
## Change Events
@TODO what happens on bulk insert/update/delete?
### New record created
Upon inserting or creating a new row, the following will be returned by our listener:
```json
{
"schema": "public",
"table": "countries",
"commit_timestamp": "2020-01-01T00:00:00Z",
"eventType": "INSERT",
"new": {
"id": 533,
"name": "Columbia",
"iso2": "CO",
"population_range_millions": [40, 50],
"main_exports": ["oil", "minerals"]
}
}
```
### Existing record updated
Upon updating a row, the following will be returned by our listener:
`
```json
{
"schema": "public",
"table": "countries",
"commit_timestamp": "2020-01-01T00:00:00Z",
"eventType": "UPDATE",
"old": {},
"new": {
"id": 76,
"name": "Brazil",
"iso2": "BR",
"population_range_millions": [205, 215],
"main_exports": ["beans", "minerals"]
}
}
```
### Existing record deleted
Upon deleting a row, the following will be returned by our listener:
```json
{
"schema": "public",
"table": "countries",
"commit_timestamp": "2020-01-01T00:00:00Z",
"eventType": "DELETE",
"old": {
"id": 76
}
}
```
-81
View File
@@ -1,81 +0,0 @@
---
id: user-management
title: User Management
description: Use Supabase to Authenticate and Authorize your users.
---
import CustomCodeBlock from '../../src/components/CustomCodeBlock'
import { signup, login, userData, logout, errorHandling, setAccessToken } from './examples/users'
### Introduction
Supabase makes it easy to manage your users.
When a user signs up, Supabase assigns them a unique ID. You can reference this ID anywhere in your database. For example, you might create a `profiles` table references the user using a `user_id` field.
Supabase provides the routes to sign up, login, log out, and manage users in your apps and websites.
### Sign up
<CustomCodeBlock header="New user." js={signup} />
<br />
Allow your users to sign up and create a new account.
After they have signed up, all interactions using the Supabase JS client will be performed as "that user".
### Log in
<CustomCodeBlock header="Existing user." js={login} />
<br />
If an account is created, users can login to your app.
After they have logged in, all interactions using the Supabase JS client will be performed as "that user".
### User data
<CustomCodeBlock header="Get the logged in user." js={userData} />
<br />
Get the JSON data for the logged in user.
### Log out
<CustomCodeBlock header="Clear the user's session." js={logout} />
<br />
After calling log out, all interactions using the Supabase JS client will be "anonymous".
### Error handling
<CustomCodeBlock header="Shows how to parse errors returned from the server." js={errorHandling} />
<br />
### Third Party Logins
We currently support the following OAuth providers:
- Google
- Github
- Gitlab
- Bitbucket
You can enable providers by navigating to Authentication > Settings > External OAuth Providers and inputting your `Client ID` and `Secret` for each.
To fetch these you need to:
1. Generate `Client ID` and `Secret` ([google](https://console.developers.google.com/apis/credentials), [github](https://github.com/settings/applications/new), [gitlab](https://gitlab.com/oauth/applications), [bitbucket](https://support.atlassian.com/bitbucket-cloud/docs/use-oauth-on-bitbucket-cloud/))
2. Enter Authorized Redirect URI: `http://<your-project>.supabase.co/auth/v1/callback` on provider dashboard
You can now test your integration by navigating to: `https://<your-project>.supabase.co/auth/v1/authorize?provider=<provider-name>`. This is where you should send your users to authenticate. Options for `provider` are `google`, `github`, `gitlab`, or `bitbucket`.
After authenticating you should be redirected to `<your-site-url>/?access_token=xyzabc&expires_in=3600&refresh_token=abcdef&token_type=bearer`. This base url can be updated on the Supabase dashboard at Authorization > Settings.
The user will now appear in your database in the `auth.users` table.
You can now use the `access_token` in the url above in an Authorize header like: `Authorization: Bearer xyzabc` when making requests to your REST or Realtime APIs in order to authenticate as that user. If using supabase-js then you can set the `accessToken` on the client:
<CustomCodeBlock header="Sets the accessToken inside supabase-js" js={setAccessToken} />
<br />
If you require any help with these steps please contact `alpha@supabase.io`
Loaded 100 of 189 files, more files were not shown because too many files have changed in this diff. Show more