Merge branch 'master' of github.com:supabase/supabase

This commit is contained in:
Terry Sutton committed 2022-11-02 20:54:57 -02:30
commit f7d60aad4b
20 files changed
+925 -745

No files matched your search

+3
View File
@@ -2,6 +2,8 @@ name: Publish to Image Registry
on:
push:
branches:
- 'studio'
tags:
- '*'
workflow_dispatch:
@@ -25,6 +27,7 @@ jobs:
latest=false
tags: |
type=ref,event=tag
type=sha,prefix={{date 'YYYYMMDD'}},enable=${{ github.ref_type == 'branch' }}
type=raw,value=${{ inputs.version }},enable=${{ github.event_name != 'push' }}
- uses: docker/setup-qemu-action@v2
@@ -70,6 +70,7 @@ NEXT_PUBLIC_SUPABASE_ANON_KEY=YOUR_SUPABASE_ANON_KEY
## Basic Setup
<Tabs
groupId="language"
defaultValue="js"
values={[
{label: 'JavaScript', value: 'js'},
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -619,7 +619,7 @@ Currently recognized methods are:
- `otp` - any one-time password based sign in (email code, SMS code, magic
link).
- `oauth` - any OAuth based sign in (social login).
- `mfa/totp` - a TOTP additional factor.
- `totp` - a TOTP additional factor.
This list will expand in the future.
@@ -152,102 +152,6 @@ request_id
After triggering `http_post`, use [`http_get_result`](#http_get_result) to get the result of the request.
## `http_collect_response` {#http_collect_response}
Given a `request_id` reference, retrieves the response.
When `async:=false` is set it is recommended that [statement_timeout](https://www.postgresql.org/docs/13/runtime-config-client.html) is set for the maximum amount of time the caller is willing to wait in case the response is slow to populate.
### Signature
:::caution
This is a Postgres SECURITY DEFINER function
:::
```sql
net.http_collect_response(
-- request_id reference
request_id bigint,
-- when `true`, return immediately. when `false` wait for the request to complete before returning
async bool default true
)
-- http response composite wrapped in a result type
returns net.http_response_result
strict
volatile
parallel safe
```
### Usage
:::caution
`net.http_collect_response` must be in a separate transaction from the calls to `net.http_<method>`
:::
```sql
select
net.http_post(
url:='https://httpbin.org/post',
body:='{"hello": "world"}'::jsonb
) as request_id;
request_id
----------
1
(1 row)
select * from net.http_collect_response(1, async:=false);
status | message | response
--------+---------+----------
SUCCESS ok (
status_code := 200,
headers := '{"date": ...}',
body := '{"args": ...}'
)::net.http_response_result
select
(response).body::json
from
net.http_collect_response(request_id:=1);
body
-------------------------------------------------------------------
{
"args": {},
"data": "{\"hello\": \"world\"}",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Content-Length": "18",
"Content-Type": "application/json",
"Host": "httpbin.org",
"User-Agent": "pg_net/0.2",
"X-Amzn-Trace-Id": "Root=1-61031a5c-7e1afeae69bffa8614d8e48e"
},
"json": {
"hello": "world"
},
"origin": "135.63.38.488",
"url": "https://httpbin.org/post"
}
(1 row)
```
Where `response` is a composite:
```sql
status_code integer
headers jsonb
body text
```
Possible values for `net.http_response_result.status` are `('PENDING', 'SUCCESS', 'ERROR')`
## Resources
- Source code: [github.com/supabase/pg_net](https://github.com/supabase/pg_net/)
@@ -28,7 +28,7 @@ npm install @supabase/supabase-js
In [multiplayer.dev](https://multiplayer.dev), client's cursor positions are sent to other clients in the room. However, cursor positions will be randomly generated for this example.
You need to get the public `anon` access token from your project's [API settings](https://app.supabase.com/project/_/settings/api). Then you can set up the Suapbase client and start sending a client's cursor positions to other clients in channel `room1`:
You need to get the public `anon` access token from your project's [API settings](https://app.supabase.com/project/_/settings/api). Then you can set up the Supabase client and start sending a client's cursor positions to other clients in channel `room1`:
```js
const { createClient } = require('@supabase/supabase-js')
@@ -27,7 +27,7 @@ Let's start building the Svelte app from scratch.
### Initialize a Svelte app
We can use the [SvelteKit Skeleton Project](https://kit.svelte.dev/docs) to initialize
an app called `supabase-sveltekit` (for this tutorial you do not need TypeScript, ESLint, Prettier, or Playwright):
an app called `supabase-sveltekit` (for this tutorial enable TypeScript, but you do not need ESLint, Prettier, or Playwright):
```bash
npm init svelte@next supabase-sveltekit
@@ -59,8 +59,8 @@ import { env } from '$env/dynamic/public'
export const supabaseClient = createClient(env.PUBLIC_SUPABASE_URL, env.PUBLIC_SUPABASE_ANON_KEY)
```
And one optional step is to update the CSS file `public/global.css` to make the app look nice.
You can find the full contents of this file [here](https://raw.githubusercontent.com/supabase/supabase/master/examples/user-management/svelte-user-management/src/app.css).
And one optional step is to add the CSS file at `src/routes/styles.css` to make the app look nice.
You can find the full contents of this file [here](https://raw.githubusercontent.com/supabase/supabase/master/examples/user-management/sveltekit-user-management/src/routes/styles.css).
### Supabase Auth Helpers
@@ -435,19 +435,17 @@ Let's create an avatar for the user so that they can upload a profile photo. We
### Add the new widget
And then we can add the widget to the Account page:
And then we can add the widget to the Account component:
```html title="src/routes/Account.svelte"
<script>
// Import the new component
import Avatar from './Avatar.svelte'
// rest of script
</script>
<form
use:getProfile
class="form-widget"
on:submit|preventDefault="{updateProfile}"
>
<form class="form-widget" on:submit|preventDefault="{updateProfile}">
<!-- Add to body -->
<Avatar bind:url={avatarUrl} size={10} on:upload={updateProfile} />
+12 -12
View File
@@ -43,18 +43,6 @@ const sidebars = {
'generated/upsert',
'generated/delete',
'generated/rpc',
{
type: 'category',
label: 'Modifiers',
items: [
'generated/using-modifiers',
'generated/limit',
'generated/order',
'generated/range',
'generated/single',
],
collapsed: true,
},
{
type: 'category',
label: 'Filters',
@@ -86,6 +74,18 @@ const sidebars = {
],
collapsed: true,
},
{
type: 'category',
label: 'Modifiers',
items: [
'generated/using-modifiers',
'generated/limit',
'generated/order',
'generated/range',
'generated/single',
],
collapsed: true,
},
],
collapsed: true,
},
@@ -0,0 +1,122 @@
---
title: Supabase Beta October 2022
description: New SDKs, quickstarts, Functions tricks, and more. But, more importantly, Launch Week 6️ has a date!
author: ant_wilson
image: 2022-october/monthly-update-october-2022.jpg
thumb: 2022-october/monthly-update-october-2022.jpg
tags:
- release-notes
date: '2022-11-02'
toc_depth: 3
---
During October, we shipped something for everybody: new SDKs, quickstarts, Functions tricks, and more. All are listed here just for you. But, more importantly, Launch Week 6️⃣ has a date!
## supabase-js v2 and supabase-flutter v1 released
![supabase-js v2 and supabase-flutter v1 released](/images/blog/2022-october/supabase-js-v2-supabase-flutter-v1-header.jpg)
The new versions of our two most popular SDKs have been fully released. It couldn’t have happened without our amazing community, thanks to everyone involved. Now, it’s time to build 🛠
[Try supabase-js V2](https://supabase.com/docs/reference/javascript/)<br/>
[Try flutter-supabase V1](https://supabase.com/docs/reference/dart)
## New Next.js quickstart & Next.js 13 example
![New Next.js quickstart & Next.js 13 example](/images/blog/2022-october/next-header.jpg)
Next.js is all the rage right now 🔥 
Next.js Conf raised the bar for dev conferences. We had the honor of being a Gold Sponsor, so we revamped our [Next.js Quickstart guide](https://supabase.com/docs/guides/with-nextjs) to include our pre-built Auth UI and [Auth Helpers.](https://supabase.com/docs/guides/auth/auth-helpers/nextjs)
And Next.js 13 was announced! Making it extremely easy to fetch and cache data from our [Serverless API](https://supabase.com/docs/guides/api). So we put together an [example to try it out](https://github.com/supabase/supabase/tree/master/examples/caching/with-nextjs-13).
## Supabase Auth and Server-Side Rendering
![Supabase Auth and Server-Side Rendering](/images/blog/2022-october/authentication-server-side-docs.jpg)
The Auth team published an in-depth doc explaining how Supabase Auth supports server-side rendering. Includes an explanation of the authentication flow and answers to some of the more common questions.
[Read the docs](https://supabase.com/docs/guides/auth/server-side-rendering).
## Database Testing with pgTAP
![Database Testing with pgTAP](/images/blog/2022-october/database-testing-postgres-pgtap.jpg)
Do you have 100% code coverage? Probably not, because that’s usually the last thing you think of, but *definitely* not if you don’t have database tests. We just shipped a framework for Database Tests which makes it incredibly easy to test your database using pgTAP an pg_prove.
[Read the docs](https://supabase.com/docs/guides/database/testing).
## Edge Functions Update
![Edge Functions Update](/images/blog/2022-october/functions-new-methods.jpg)
Functions now support GET requests! Other HTTP verbs such as PUT, PATCH, and DELETE are supported too.
[Check this example](https://github.com/supabase/supabase/blob/master/examples/edge-functions/supabase/functions/restful-tasks/index.ts)
## Quick Product Updates
- supabase-py 🐍 now has functions support! [PR](https://github.com/supabase-community/supabase-py/pull/179)
- You can now detect users’ location from Edge Functions easily by using `X-Forwarded-For header`. [Example](https://github.com/supabase/supabase/tree/master/examples/edge-functions/supabase/functions/location)
- Return `provider_refresh_token` along with `provider_access_token`. [PR](https://github.com/supabase/gotrue/pull/641)
- Added a `refreshSession` method to allow users to forcefully refresh a session instead of waiting for it to autorefresh upon expiry. Thanks to [@j4w8n](https://github.com/j4w8n) for the [PR](https://github.com/supabase/gotrue-js/pull/505) 🙇🏻‍♂️
- Logging: realtime, storage, postgrest, and pgbouncer released.
- Trigger a file download by adding the download query parameter to your storage objects. storage-api. [PR](https://github.com/supabase/storage-api/issues/122)
## Made with Supabase
![Made with Supabase](/images/blog/2022-october/twitter-card-header.jpg)
There were so many amazing apps Made with Supabase this month that we couldn’t choose just one… so here are three:
🚰 [Remote Water Feeder](https://twitter.com/SomangshuG/status/1581888060643774465) by Somangshu Goswami <br/>
📊 [Decile App](https://github.com/decileapp/decile) by [Krishna](https://twitter.com/ntkris) <br/>
📑 [Explainpaper](https://www.explainpaper.com/) by [Aman Jha](https://twitter.com/amanjha__) and [Jade](https://twitter.com/functionofjade)
If you want to see +100 other apps, check [the replies](https://twitter.com/supabase/status/1585226233742229504).
## Extended Community Highlights
![Community](/images/blog/2022-june/community.jpg)
- Mark Buggraf sat down to chat about postgres-wasm with LogRocket. [Podcast](https://podrocket.logrocket.com/opensourcing-postgres-wasm)
- A collection of awesome Supabase resources. [awesome-supabase](https://github.com/lyqht/awesome-supabase)
- All the Happy Hour Hacktoberfest episodes. [Episode 1](https://www.youtube.com/watch?v=qRSYenBLHHQ) | [Episode 2](https://www.youtube.com/watch?v=-RlivqzNIso) | [Episode 3](https://www.youtube.com/watch?v=LzDIptBGtUw)
- Hacking the PostgREST Headers: Oh, the Things You Can Do! [Article](https://dev.to/burggraf/hacking-the-postgrest-headers-oh-the-things-you-can-do-ck2)
- Why we’re moving away from Firebase. [Blog post](https://koptional.com/article/why-we%E2%80%99re-moving-away-from-firebase)
- Basejump SaaS starter for Supabase. [Repo](https://github.com/usebasejump/basejump)
- SvelteKit + Supabase CRUD with RLS: Row-Level Security! [Video](https://www.youtube.com/watch?v=iKzjfHARXpc)
- Building a startup (build log 2#): Authenticating students with Supabase. [Blog Post](https://dev.to/paul_emechebe/building-a-startup-build-log-2-authenticating-users-with-supabase-1p1b)
- CRUD with Supabase in Flutter. [Tutorial](https://sadabwasim.medium.com/crud-with-supabase-in-flutter-dbe97fa0c15)
- Phone Auth with self-hosted Supabase. [Video](https://www.youtube.com/watch?v=z3sE-ix2uok)
- My Future with Elixir: set-theoretic types. [Blog Post](https://elixir-lang.org/blog/2022/10/05/my-future-with-elixir-set-theoretic-types/)
- Upload media to Supabase from remote URL with nodejs. [Blog Post](https://www.antoinemesnil.com/posts/upload-media-supabase)
- Say goodbye to backend development. [Video](https://www.youtube.com/watch?v=9CuTxeioKF4)
## Launch Week 6 date announced
We are ending 2022 on a high note ✊. Mark your calendars: Launch Week 6 is happenning on **December 12-16**.
In the meantime, [revisit LW5](https://supabase.com/launch-week).
## We’re hiring
Come join one of the fastest-growing open source projects ever 🤗
- [Sales Engineer](https://boards.greenhouse.io/supabase/jobs/4711141004)
- [Lead Billing and API Engineer](https://boards.greenhouse.io/supabase/jobs/4652333004)
- [View all our openings](https://boards.greenhouse.io/supabase)
## Meme Zone
If you made it this far in the blog post you deserve a treat. [Follow us on Twitter](https://twitter.com/supabase) for more.
![Supabase meme October 2022](/images/blog/2022-october/beta-update-october-meme.jpeg)
## Get started
- Start using Supabase today: **[app.supabase.com](https://app.supabase.com/)**
- Make sure to **[star us on GitHub](https://github.com/supabase/supabase)**
- Follow us **[on Twitter](https://twitter.com/supabase)**
- Subscribe to our **[YouTube channel](https://www.youtube.com/c/supabase)**
Binary file not shown.

After

Width:  |  Height:  |  Size: 200 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

+155 -5
View File
@@ -1100,9 +1100,14 @@ pages:
```
Using Modifiers:
description: |
Modifiers can be used on `select()` queries.
Filters work on the row level—they allow you to return rows that
only match certain conditions without changing the shape of the rows.
Modifiers are everything that don't fit that definition—allowing you to
change the format of the response (e.g., returning a CSV string).
If a Stored Procedure returns a table response, you can also apply modifiers to the `rpc()` function.
Modifiers must be specified after filters. Some modifiers only apply for
queries that return rows (e.g., `select()` or `rpc()` on a function that
returns a table response).
limit():
description: |
@@ -1180,13 +1185,17 @@ pages:
Using Filters:
description: |
Filters allow you to only return rows that match certain conditions.
Filters can be used on `select()`, `update()`, and `delete()` queries.
If a Stored Procedure returns a table response, you can also apply filters.
If a Database function returns a table response, you can also apply filters.
### Applying Filters
You must apply your filters to the end of your query. For example:
Filters must be applied after any of `select()`, `update()`, `upsert()`,
`delete()`, and `rpc()` and before
[modifiers](/docs/reference/dart/using-modifiers).
```dart
final data = await supabase
@@ -1202,7 +1211,8 @@ pages:
### Chaining
Filters can be chained together to produce advanced queries. For example:
Filters can be chained together to produce advanced queries. For example,
to query cities with population between 1,000 and 10,000:
```dart
final data = await supabase
@@ -1212,6 +1222,146 @@ pages:
.lt('population', 10000);
```
### Conditional Chaining
Filters can be built up one step at a time and then executed. For example:
```dart
final filterByName = null;
final filterPopLow = 1000;
final filterPopHigh = 10000;
var query = supabase
.from('cities')
.select('name, country_id');
if (filterByName != null) { query = query.eq('name', filterByName); }
if (filterPopLow != null) { query = query.gte('population', filterPopLow); }
if (filterPopHigh != null) { query = query.lt('population', filterPopHigh); }
final data = await query;
```
### Filter by values within a JSON column
<Tabs>
<TabItem value="schema" label="Schema">
```sql
create table
users (
id int8 primary key,
name text,
address jsonb
);
insert into
users (id, name, address)
values
(1, 'Michael', '{ "postcode": 90210 }'),
(2, 'Jane', null);
```
</TabItem>
<TabItem default value="dart" label="Flutter">
```dart
final data = await supabase
.from('users')
.select()
.eq('address->postcode', 90210);
```
</TabItem>
<TabItem value="result" label="Result">
```json
{
"data": [
{
"id": 1,
"name": "Michael",
"address": {
"postcode": 90210
}
}
],
"status": 200,
"statusText": "OK"
}
```
</TabItem>
</Tabs>
### Filter Foreign Tables
You can filter on foreign tables in your `select()` query using dot
notation:
<Tabs>
<TabItem value="schema" label="Schema">
```sql
create table
countries (id int8 primary key, name text);
create table
cities (
id int8 primary key,
country_id int8 not null references countries,
name text
);
insert into
countries (id, name)
values
(1, 'Germany'),
(2, 'Indonesia');
insert into
cities (id, country_id, name)
values
(1, 2, 'Bali'),
(2, 1, 'Munich');
```
</TabItem>
<TabItem default value="dart" label="Flutter">
```dart
final data = await supabase
.from('countries')
.select('''
name,
cities!inner (
name
)
''')
.eq('cities.name', 'Bali');
```
</TabItem>
<TabItem value="result" label="Result">
```json
{
"data": [
{
"name": "Indonesia",
"cities": [
{
"name": "Bali"
}
]
}
],
"status": 200,
"statusText": "OK"
}
```
</TabItem>
</Tabs>
.or():
description: |
Finds all rows satisfying at least one of the filters.
@@ -1,7 +1,7 @@
import React from 'react'
import { useRouter } from 'next/router'
import { observer } from 'mobx-react-lite'
import { DatabaseLayout } from 'components/layouts'
import { LogsLayout } from 'components/layouts'
import LogsPreviewer from 'components/interfaces/Settings/Logs/LogsPreviewer'
import { NextPageWithLayout } from 'types'
import { LogsTableName } from 'components/interfaces/Settings/Logs'
@@ -20,6 +20,6 @@ export const LogPage: NextPageWithLayout = () => {
)
}
LogPage.getLayout = (page) => <DatabaseLayout title="Database">{page}</DatabaseLayout>
LogPage.getLayout = (page) => <LogsLayout title="Database">{page}</LogsLayout>
export default observer(LogPage)
@@ -1,7 +1,7 @@
import React from 'react'
import { useRouter } from 'next/router'
import { observer } from 'mobx-react-lite'
import { DatabaseLayout } from 'components/layouts'
import { LogsLayout } from 'components/layouts'
import LogsPreviewer from 'components/interfaces/Settings/Logs/LogsPreviewer'
import { NextPageWithLayout } from 'types'
import { LogsTableName } from 'components/interfaces/Settings/Logs'
@@ -20,6 +20,6 @@ export const LogPage: NextPageWithLayout = () => {
)
}
LogPage.getLayout = (page) => <DatabaseLayout title="Database">{page}</DatabaseLayout>
LogPage.getLayout = (page) => <LogsLayout title="Database">{page}</LogsLayout>
export default observer(LogPage)