Merge branch 'master' into feat/phone-docs
No files matched your search
@@ -2,17 +2,25 @@ REPO_DIR=$(shell pwd)
|
||||
|
||||
help:
|
||||
@echo "\SCRIPTS\n"
|
||||
@echo "make github.users # pull a list of all contributors"
|
||||
@echo "make github.contributors # pull a list of all contributors"
|
||||
@echo "make github.issues # pull a list of all issue creators"
|
||||
@echo "make github.repos # pull a list of our repos"
|
||||
@echo "make github.traction # get a history of stargazers for our individual repos"
|
||||
|
||||
github.users:
|
||||
curl -sS https://api.github.com/repos/supabase/supabase/contributors \
|
||||
| jq -r 'map_values({username: .login, avatar_url: .avatar_url}) \
|
||||
github.contributors.%:
|
||||
curl -sS https://api.github.com/repos/supabase/$*/contributors \
|
||||
| jq -r 'map_values({ username: .login }) \
|
||||
| unique \
|
||||
| sort_by(.username)' \
|
||||
> $(REPO_DIR)/web/src/data/contributors/contributors.json
|
||||
> $(REPO_DIR)/web/src/data/contributors/$*.json
|
||||
|
||||
.PHONY: github.rcontributorsepos
|
||||
github.contributors: \
|
||||
github.contributors.supabase \
|
||||
github.contributors.supabase-js \
|
||||
github.contributors.supabase-py \
|
||||
github.contributors.supabase-flutter \
|
||||
github.contributors.supabase-dart
|
||||
|
||||
github.issues:
|
||||
curl -sS https://api.github.com/repos/supabase/supabase/issues \
|
||||
|
||||
@@ -25,6 +25,7 @@ For full documentation, visit [supabase.io/docs](https://supabase.io/docs)
|
||||
- [Community Forum](https://github.com/supabase/supabase/discussions). Best for: help with building, discussion about database best practices.
|
||||
- [GitHub Issues](https://github.com/supabase/supabase/issues). Best for: bugs and errors you encounter using Supabase.
|
||||
- [Email Support](https://supabase.io/docs/support#business-support). Best for: problems with your database or infrastructure.
|
||||
- [Discord](https://discord.supabase.com). Best for: sharing you applications and hanging out with the community.
|
||||
|
||||
## Status
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ Para ver la documentación completa, visita [supabase.io/docs](https://supabase.
|
||||
- [Foro de la comunidad](https://github.com/supabase/supabase/discussions). Mejor para: ayuda construyendo, discusiones acerca de las mejores practicas de base de datos.
|
||||
- [GitHub Issues](https://github.com/supabase/supabase/issues). Mejor para: bugs y errores que te puedes encontrar utilizando Supabase.
|
||||
- [Soporte por e-mail](https://supabase.io/docs/support#business-support). Mejor para: problemas con la base de datos o infraestructura.
|
||||
- [Discord](https://discord.supabase.com). Mejor para: compartir tus aplicaciones y pasar el rato con la comunidad.
|
||||
|
||||
## Estatus
|
||||
|
||||
|
||||
@@ -138,7 +138,7 @@ values={[
|
||||
|
||||
```sh
|
||||
1. Go to the "API" section.
|
||||
2. Find "todos" in the "Tables an Views" section.
|
||||
2. Find "todos" in the "Tables and Views" section.
|
||||
3. Switch between the Javascript and the cURL docs using the tabs.
|
||||
```
|
||||
|
||||
|
||||
@@ -128,7 +128,7 @@ returns smallint as $$
|
||||
|
||||
var num_affected = plv8.execute(
|
||||
'udpate profiles set first_name = $1 where id = $2',
|
||||
[id, first_name]
|
||||
[first_name, id]
|
||||
);
|
||||
|
||||
return num_affected;
|
||||
@@ -155,4 +155,4 @@ $$ language plv8;
|
||||
## Resources
|
||||
|
||||
- Official [`plv8` documentation](https://plv8.github.io/).
|
||||
- [plv8 Github Repository](https://github.com/plv8/plv8).
|
||||
- [plv8 Github Repository](https://github.com/plv8/plv8).
|
||||
@@ -17,7 +17,6 @@ Our CLI is still under heavy development, and is missing some features:
|
||||
|
||||
- You cannot yet deploy your local changes to your live project using the CLI. You will need to take a "dump" of your database schema
|
||||
and run it on your live database.
|
||||
- We have not yet added Storage to the local development suite.
|
||||
- The self-hosted version of Supabase does not include a UI yet.
|
||||
We are working on this in stages, starting with our [UI library](https://github.com/supabase/ui)
|
||||
([more context](https://github.com/supabase/supabase/discussions/1001#discussioncomment-558696)).
|
||||
@@ -33,7 +32,7 @@ In the meantime, here are some suggested tools for interacting with your Postgre
|
||||
## Prerequisites
|
||||
|
||||
Our CLI makes heavy use of [Docker Compose](https://docs.docker.com/compose/install), so make sure it is installed and configured to
|
||||
[run with elevated priveleges][https://docs.docker.com/engine/install/linux-postinstall/#manage-docker-as-a-non-root-user].
|
||||
[run with elevated priveleges](https://docs.docker.com/engine/install/linux-postinstall/#manage-docker-as-a-non-root-user).
|
||||
|
||||
You will also need to install [NPM](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm).
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ By the end of this guide you'll have an app which allows users to login and upda
|
||||
<img height="500px" src="/img/supabase-flutter-demo.png" alt="Supabase User Management example" />
|
||||
|
||||
### Github
|
||||
Whenever you get stuck at any point, take a look at [this repo](https://github.com/dshukertjr/flutter_supabase_quickstart).
|
||||
Whenever you get stuck at any point, take a look at [this repo](https://github.com/supasquad/supabase-flutter-quickstart).
|
||||
|
||||
## Project set up
|
||||
|
||||
@@ -161,7 +161,7 @@ Then let's install the only additional dependency: [supabase-flutter](https://gi
|
||||
Open the app and copy and paste the following inside `pubspec.yaml` under `dependencies`.
|
||||
|
||||
```yaml
|
||||
supabase_flutter: ^0.0.4
|
||||
supabase_flutter: ^0.0.6
|
||||
```
|
||||
|
||||
Run `flutter pub get` to install the dependencies.
|
||||
@@ -283,6 +283,26 @@ class AuthState<T extends StatefulWidget> extends SupabaseAuthState<T> {
|
||||
}
|
||||
```
|
||||
|
||||
### Set up AuthRequiredState
|
||||
|
||||
We might want to show certain pages to the users only if they are signed in.
|
||||
For that we can create a handy `AuthRequiredState` class that we can inherit from for pages where the users need to be authenticated.
|
||||
`AuthRequiredState` will inherit `SupabaseAuthRequiredState` which is provided by `supabase_flutter` package.
|
||||
|
||||
```dart title="lib/components/auth_required_state.dart"
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:supabase_flutter/supabase_flutter.dart';
|
||||
|
||||
class AuthRequiredState<T extends StatefulWidget>
|
||||
extends SupabaseAuthRequiredState<T> {
|
||||
@override
|
||||
void onUnauthenticated() {
|
||||
/// Users will be sent back to the LoginPage if they sign out.
|
||||
Navigator.of(context).pushNamedAndRemoveUntil('/login', (route) => false);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Let's also create a constant file to make it easier to use Supabase client.
|
||||
|
||||
```dart title="lib/utils/constants.dart"
|
||||
@@ -412,13 +432,14 @@ class _LoginPageState extends AuthState<LoginPage> {
|
||||
### Set up Account page
|
||||
|
||||
After a user is signed in we can allow them to edit their profile details and manage their account.
|
||||
Let's create a new component for that called `account_page.dart`.
|
||||
Note that this page will also inherit `AuthState` as it will handle user sign out.
|
||||
Let's create a new widget called `account_page.dart` for that.
|
||||
Note that this page will inherit `AuthRequiredState` as user needs to be authenticated to view this page.
|
||||
|
||||
```dart title="lib/pages/account_page.dart"
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:supabase_flutter_guide/components/auth_state.dart';
|
||||
import 'package:supabase_flutter_guide/components/auth_required_state.dart';
|
||||
import 'package:supabase_flutter_guide/utils/constants.dart';
|
||||
import 'package:supabase/supabase.dart';
|
||||
|
||||
class AccountPage extends StatefulWidget {
|
||||
const AccountPage({Key? key}) : super(key: key);
|
||||
@@ -427,20 +448,19 @@ class AccountPage extends StatefulWidget {
|
||||
_AccountPageState createState() => _AccountPageState();
|
||||
}
|
||||
|
||||
class _AccountPageState extends AuthState<AccountPage> {
|
||||
class _AccountPageState extends AuthRequiredState<AccountPage> {
|
||||
late final _usernameController = TextEditingController();
|
||||
late final _websiteController = TextEditingController();
|
||||
var _loading = false;
|
||||
|
||||
Future<void> _getProfile() async {
|
||||
Future<void> _getProfile(String userId) async {
|
||||
setState(() {
|
||||
_loading = true;
|
||||
});
|
||||
final user = supabase.auth.user()!;
|
||||
final response = await supabase
|
||||
.from('profiles')
|
||||
.select()
|
||||
.eq('id', user.id)
|
||||
.eq('id', userId)
|
||||
.single()
|
||||
.execute();
|
||||
if (response.error != null && response.status != 406) {
|
||||
@@ -496,9 +516,16 @@ class _AccountPageState extends AuthState<AccountPage> {
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_getProfile();
|
||||
super.initState();
|
||||
void onAuthenticated(Session session) {
|
||||
final user = session.user;
|
||||
if (user != null) {
|
||||
_getProfile(user.id);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void onUnauthenticated() {
|
||||
Navigator.of(context).pushReplacementNamed('/login');
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -538,7 +565,6 @@ class _AccountPageState extends AuthState<AccountPage> {
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Launch!
|
||||
|
||||
Now that we have all the components in place, let's update `lib/main.dart`:
|
||||
|
||||
@@ -4,42 +4,22 @@ title: Contributing
|
||||
description: Want to help?
|
||||
---
|
||||
|
||||
import Sponsors from '../../src/components/Sponsors'
|
||||
|
||||
## How to contribute
|
||||
|
||||
Want to contribute? Why not jump into our GitHub repo and:
|
||||
|
||||
- [Sponsor Supabase](https://github.com/sponsors/supabase).
|
||||
- [Answer Discussions](https://github.com/supabase/supabase/discussions).
|
||||
- Submit an issue.
|
||||
- Report a performance issue or a part of the documentation that you find confusing.
|
||||
- Create a pull request.
|
||||
- Try one of our products and give feedback.
|
||||
- Translate this website.
|
||||
- [Vote on a new client library](https://github.com/supabase/supabase/issues/5) for your favorite language.
|
||||
- [Translate our Readme](https://github.com/supabase/supabase/issues/1341).
|
||||
- Try our products and give feedback.
|
||||
- Spread the word if you like what we are doing.
|
||||
- Add your project or company to our showcase.
|
||||
|
||||
|
||||
## Contributors
|
||||
|
||||
To add yourself as a contributor:
|
||||
|
||||
Open [this page](https://github.com/supabase/supabase/blob/master/web/docs/handbook/contributing.mdx) on GitHub and then click the pencil icon.
|
||||
|
||||

|
||||
|
||||
Enter your GitHub profile name and link on a new line.
|
||||
|
||||

|
||||
|
||||
Enter a title for your pull request and click "Propose Changes":
|
||||
|
||||

|
||||
|
||||
One of the Supabase maintainers will approve your PR in the next few hours.
|
||||
|
||||
<!-- Add your github handle below this line. Every name should be on a new line -->
|
||||
[awalias](https://github.com/awalias).
|
||||
[kiwicopple](https://github.com/kiwicopple).
|
||||
[abhinav-TB](https://github.com/abhinav-TB).
|
||||
[jacobfenger](https://github.com/jacobfenger).
|
||||
<!-- Add your github above this line. Every name should be on a new line -->
|
||||
## Sponsors
|
||||
|
||||
<Sponsors />
|
||||
@@ -0,0 +1,83 @@
|
||||
---
|
||||
id: supasquad
|
||||
title: SupaSquad
|
||||
description: Supabase Advocate program
|
||||
---
|
||||
|
||||
The SupaSquad is an official Supabase advocate program where community members help build and manage the Supabase community.
|
||||
|
||||
- Official recognition in the Supabase community.
|
||||
- Direct connection to the Supabase team.
|
||||
- Help steer the Supabase community.
|
||||
|
||||

|
||||
|
||||
## Requirements
|
||||
|
||||
As a member of the Squad, you choose the approach where you'll provide the most value.
|
||||
You can help in one of five ways:
|
||||
|
||||
### Maintainer
|
||||
|
||||
Help maintain Supabase repositories. This includes building client librararies, managing issues, and fixing bugs.
|
||||
|
||||
### Expert
|
||||
|
||||
Answer user questions on Github [Discussions](https://github.com/supabase/supabase/discussions), Discord, and various other social platforms.
|
||||
|
||||
### Advocate
|
||||
|
||||
Spread the word on social channels and help to answer Supabase-related questions in the broader community and social channels.
|
||||
|
||||
### Builder
|
||||
|
||||
Build Supabase examples, blog about them, and them add to the [SupaSquad GitHub Org](https://github.com/supasquad).
|
||||
|
||||
### Author
|
||||
|
||||
Write guest blog posts, create documentation, and help Supabase global expansion through translation.
|
||||
|
||||
### Moderator
|
||||
|
||||
Help us maintain the community guidelines in our GitHub and Community-led communities such as Discord, [Reddit](https://reddit.com/r/Supabase/),
|
||||
[StackOverflow](https://stackoverflow.com/questions/tagged/supabase) etc.
|
||||
|
||||
## Benefits for SupaSquad members
|
||||
|
||||
- Access to a Supabase Discord channel providing direct communication with the team, Discord badges, and elevated privileges.
|
||||
- Special AMA sessions with members of the Supabase team.
|
||||
- Monthly DevRel committee call with industry-leading Developer Advocates (many of whom are [angel investors](https://supabase.io/blog/2021/03/25/angels-of-supabase)), where you can learn from the best.
|
||||
- We'll help you build your audience by promoting content via the Supabase social channels.
|
||||
- Featured profile on Supabase website.
|
||||
- Early access to new features (and the opportunity to provide feedback to the team!).
|
||||
- Free credits that you can use for Squad efforts.
|
||||
- Direct access to members of the Supabase team for questions, suggestions, etc.
|
||||
- Help shape the future of the program.
|
||||
- Invited to the [SupaSquad GitHub Org](https://github.com/supasquad) to collaborate with the other squad members.
|
||||
- Exclusive Supabase Team swag drops usually exclusively reserved to the Supabase core team.
|
||||
|
||||
## How to join
|
||||
|
||||
|
||||
1. Apply to join the program using [this form](https://airtable.com/shr0FtLqLfhpuEya8).
|
||||
2. We will start taking interviewing members from `1 September 2021`.
|
||||
3. Entry is capped to 20 founding members so we can grow the community at a healthy pace and provide a great experience to all new users.
|
||||
4. Membership is valid for one year, and can be renewed every year.
|
||||
|
||||
|
||||
## FAQs
|
||||
|
||||
<details>
|
||||
<summary><i>Why are you only admitting 20 new members?</i></summary>
|
||||
The entire Supabase team is only 20 people, so as you can imagine adding another 20 people sounds like a lot to us! We wish we could admit everyone who wanted to join.
|
||||
But we also want to make sure everyone who joins the Squad has an awesome experience. In the future we will probably expand the intake to include a monthly quota.
|
||||
</details>
|
||||
<details>
|
||||
<summary><i>What is expected?</i></summary>
|
||||
Mostly just enthusiasm. If you are interested in Open Source and want to get involved, the SupaSquad program is a great channel. You'll be given opportunities to contribute
|
||||
to the community in whatever ways match your skillset.
|
||||
</details>
|
||||
<details>
|
||||
<summary><i>What if I become too busy to contribute?</i></summary>
|
||||
No worries! The program isn't a job. It's just an opportunity to build your skillset and audience within the Supabase ecosystem.
|
||||
</details>
|
||||
@@ -102,6 +102,7 @@ module.exports = {
|
||||
},
|
||||
prism: {
|
||||
defaultLanguage: 'js',
|
||||
additionalLanguages: ['dart'],
|
||||
plugins: ['line-numbers', 'show-language'],
|
||||
theme: require('@kiwicopple/prism-react-renderer/themes/vsDark'),
|
||||
darkTheme: require('@kiwicopple/prism-react-renderer/themes/vsDark'),
|
||||
|
||||
@@ -84,12 +84,12 @@ module.exports = {
|
||||
collapsed: false,
|
||||
items: [
|
||||
'guides/examples',
|
||||
'guides/with-angular',
|
||||
'guides/with-flutter',
|
||||
'guides/with-nextjs',
|
||||
'guides/with-react',
|
||||
'guides/with-svelte',
|
||||
'guides/with-vue-3',
|
||||
'guides/with-angular',
|
||||
'guides/with-flutter',
|
||||
'guides/self-hosting',
|
||||
],
|
||||
},
|
||||
@@ -97,7 +97,13 @@ module.exports = {
|
||||
type: 'category',
|
||||
label: 'See Also',
|
||||
collapsed: false,
|
||||
items: ['handbook/contributing', 'company/terms', 'company/privacy', 'company/aup'],
|
||||
items: [
|
||||
'handbook/contributing',
|
||||
'handbook/supasquad',
|
||||
'company/terms',
|
||||
'company/privacy',
|
||||
'company/aup',
|
||||
],
|
||||
},
|
||||
],
|
||||
guides: [
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
import React from 'react'
|
||||
import sponsors from '../data/sponsors.json'
|
||||
|
||||
|
||||
export default function Sponsors() {
|
||||
|
||||
const tiers = [
|
||||
{
|
||||
tier_name: '$5,000 a month',
|
||||
heading: 'Enterprise: $5,000 per month',
|
||||
transactions: sponsors.filter((x) => (x.tier == '$5,000 a month')),
|
||||
},
|
||||
{
|
||||
tier_name: '$2,500 a month',
|
||||
heading: 'Agency: $2,500 per month',
|
||||
transactions: sponsors.filter((x) => (x.tier == '$2,500 a month')),
|
||||
},
|
||||
{
|
||||
tier_name: '$1,000 a month',
|
||||
heading: 'Startup: $1,000 per month',
|
||||
transactions: sponsors.filter((x) => (x.tier == '$1,000 a month')),
|
||||
},
|
||||
{
|
||||
tier_name: '$49 a month',
|
||||
heading: 'Evangelist: $49 per month',
|
||||
transactions: sponsors.filter((x) => (x.tier == '$49 a month')),
|
||||
},
|
||||
{
|
||||
tier_name: '$19 a month',
|
||||
heading: 'Supporter: $19 per month',
|
||||
transactions: sponsors.filter((x) => (x.tier == '$19 a month')),
|
||||
},
|
||||
{
|
||||
tier_name: '$5 a month',
|
||||
heading: 'Contributor: $5 per month',
|
||||
transactions: sponsors.filter((x) => (x.tier == '$5 a month')),
|
||||
},
|
||||
]
|
||||
|
||||
return (
|
||||
<div >
|
||||
|
||||
{tiers.map(
|
||||
(t) =>
|
||||
!!t.transactions.length && (
|
||||
<>
|
||||
<h4 className="">{t.heading}</h4>
|
||||
<div className="row is-multiline" style={{ paddingLeft: 15 }}>
|
||||
{t.transactions.map((x) => (
|
||||
<div className="col col--3" key={x.sponsor}>
|
||||
<a className="avatar" href={`https://github.com/${x.sponsor}`}>
|
||||
<img
|
||||
className="avatar__photo avatar__photo--sm"
|
||||
src={`https://github.com/${x.sponsor}.png`}
|
||||
/>
|
||||
<div className="avatar__intro">
|
||||
<h5 className="avatar__name" >{x.sponsor}</h5>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<br />
|
||||
</>
|
||||
)
|
||||
)}
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -6,51 +6,19 @@ import maintainers from '../data/maintainers.json'
|
||||
import GithubCard from '../components/GithubCard'
|
||||
import { repos } from '../data/github'
|
||||
|
||||
import Sponsors from '../components/Sponsors'
|
||||
|
||||
export default function Oss() {
|
||||
const [activePill, setActivePill] = React.useState('All')
|
||||
const context = useDocusaurusContext()
|
||||
const { siteConfig = {} } = context
|
||||
|
||||
|
||||
|
||||
const maintainerTags = maintainers
|
||||
.reduce((acc, x) => acc.concat(x.tags), []) // get all tags
|
||||
.filter((v, i, a) => a.indexOf(v) === i) // remove duplicates
|
||||
.sort((a, b) => a.localeCompare(b)) // alphabetical
|
||||
const maintainerPills = ['All'].concat(maintainerTags)
|
||||
const tiers = [
|
||||
{
|
||||
tier_name: '$5,000 a month',
|
||||
heading: 'Enterprise: $5,000 per month',
|
||||
transactions: sponsors.filter((x) => (x.tier == '$5,000 a month')),
|
||||
},
|
||||
{
|
||||
tier_name: '$2,500 a month',
|
||||
heading: 'Agency: $2,500 per month',
|
||||
transactions: sponsors.filter((x) => (x.tier == '$2,500 a month')),
|
||||
},
|
||||
{
|
||||
tier_name: '$1,000 a month',
|
||||
heading: 'Startup: $1,000 per month',
|
||||
transactions: sponsors.filter((x) => (x.tier == '$1,000 a month')),
|
||||
},
|
||||
{
|
||||
tier_name: '$49 a month',
|
||||
heading: 'Evangelist: $49 per month',
|
||||
transactions: sponsors.filter((x) => (x.tier == '$49 a month')),
|
||||
},
|
||||
{
|
||||
tier_name: '$19 a month',
|
||||
heading: 'Supporter: $19 per month',
|
||||
transactions: sponsors.filter((x) => (x.tier == '$19 a month')),
|
||||
},
|
||||
{
|
||||
tier_name: '$5 a month',
|
||||
heading: 'Contributor: $5 per month',
|
||||
transactions: sponsors.filter((x) => (x.tier == '$5 a month')),
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
return (
|
||||
<Layout title={`${siteConfig.title}`} description={siteConfig.tagline}>
|
||||
<section className={'section-lg'}>
|
||||
@@ -71,30 +39,7 @@ export default function Oss() {
|
||||
<section className={'section-lg'}>
|
||||
<div className="container">
|
||||
<h2 className="with-underline">Sponsors</h2>
|
||||
{tiers.map(
|
||||
(t) =>
|
||||
!!t.transactions.length && (
|
||||
<>
|
||||
<h4 className="">{t.heading}</h4>
|
||||
<div className="row is-multiline">
|
||||
{t.transactions.map((x) => (
|
||||
<div className="col col--3" key={x.sponsor}>
|
||||
<a className="avatar" href={`https://github.com/${x.sponsor}`}>
|
||||
<img
|
||||
className="avatar__photo avatar__photo--sm"
|
||||
src={`https://github.com/${x.sponsor}.png`}
|
||||
/>
|
||||
<div className="avatar__intro">
|
||||
<h5 className="avatar__name">{x.sponsor}</h5>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<br />
|
||||
</>
|
||||
)
|
||||
)}
|
||||
<Sponsors />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -163,38 +108,3 @@ export default function Oss() {
|
||||
</Layout>
|
||||
)
|
||||
}
|
||||
|
||||
function ContributorCard({ title, description, href, stars, handle }) {
|
||||
return (
|
||||
<a className={'card'} href={href} style={{ height: '100%' }}>
|
||||
<div className="card__body">
|
||||
<h4 style={styles.h4} style={{ margin: 0 }}>
|
||||
{title.toUpperCase()}
|
||||
</h4>
|
||||
<small>{description}</small>
|
||||
</div>
|
||||
<hr style={styles.hr} />
|
||||
<div style={styles.cardBase}>
|
||||
<div>@{handle}</div>
|
||||
<div>{stars} ★</div>
|
||||
</div>
|
||||
</a>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = {
|
||||
hr: {
|
||||
margin: '15px 0 10px 0',
|
||||
},
|
||||
h3: {
|
||||
margin: 0,
|
||||
textTransform: 'capitalize',
|
||||
},
|
||||
cardBase: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
padding: '0 15px 10px 15px',
|
||||
fontSize: '0.8em',
|
||||
},
|
||||
}
|
||||
|
Before Width: | Height: | Size: 86 KiB After Width: | Height: | Size: 79 KiB |
|
After Width: | Height: | Size: 1.3 MiB |
@@ -35,7 +35,7 @@ One of the best things about building Supabase is the community. We're even luck
|
||||
|
||||
### Where?
|
||||
|
||||
Blog post coming soon. Follow our [Twitter](https://twitter.com/supabase) to get notified immediately.
|
||||
Read the [blog post](/blog/2021/07/26/supabase-community-day).
|
||||
|
||||
## Tuesday 27 July: Storage v2
|
||||
|
||||
|
||||
@@ -8,46 +8,43 @@ authorURL: https://github.com/roryw10
|
||||
image: epsilon3/og-epsilon3.jpg
|
||||
thumb: epsilon3/cover-epsilon3.jpg
|
||||
tags:
|
||||
- launch-week
|
||||
- case-study
|
||||
date: '2021-07-26'
|
||||
toc_depth: 2
|
||||
---
|
||||
|
||||
Epsilon3 are a USA based Y-Combinator backed startup leveraging telemetry data to digitise paper based procedures for complex
|
||||
testing and operations. Their product is rapidly becoming the OS for space projects and complex operations.
|
||||
Epsilon3 is a USA-based Y Combinator startup. They digitize paper-based procedures in the space industry using telemetry data,
|
||||
simplifying testing and operations. Their product is rapidly becoming the OS for space projects and complex operations.
|
||||
|
||||
Learn how the team at Epsilon3 use Supabase to help teams execute secure and reliable operations in an industry that
|
||||
project spend runs into the billions.
|
||||
Learn how the team at Epsilon3 uses Supabase to help teams execute secure and reliable operations in an industry where project
|
||||
spend runs into the billions.
|
||||
|
||||
### Space Operations
|
||||
|
||||
Epsilon3 are modernising the industry by leveraging telemetry data to digitise paper procedures in space operations.
|
||||
Their customers need to run testing and operational procedures in real time. Using Epsilon3's solution means people can
|
||||
collaborate online as a team instead of being siloed and separated, an increasingly important requirement in a post-pandemic working world.
|
||||
Epsilon3 are powering an industry where reliability is a must. In the space industry missions cost billions and need to run reliably.
|
||||
Epsilon3's customers run testing and operational procedures in real-time. Epsilon3's solution allows online collaboration as a team,
|
||||
instead of being siloed and separated which is an increasingly important requirement in a post-pandemic working world.
|
||||
Epsilon3 is powering an industry where reliability is paramount. In the space industry, missions cost billions and need to run reliably.
|
||||
|
||||

|
||||

|
||||
|
||||
The stakes are high when working on projects where failure entails huge potential financial losses. Epsilon3's software saves
|
||||
operators time and reduces errors to improve complex operations. Their customers are already using their software and successfully
|
||||
sending satellites into space, and are about to use Epsilon3's software for an operational Rocket Launch. As a result, their
|
||||
software reputation for improving the quality standard for complex operations has led to demand from other industries.
|
||||
The team now have enquiries from clients in the robotics, logistics and medical equipment sectors who need a structured and standardised
|
||||
way of running procedures and keeping audit trails.
|
||||
Epsilon3's software saves operators time and reduces errors to improve complex operations. Their customers are using their software and
|
||||
successfully sending satellites into space and are about to use Epsilon3's software for an operational Rocket Launch. As a result, their
|
||||
reputation for improving the quality standard for complex operations has led to demand from other industries. The team is receiving
|
||||
enquiries from clients in the robotics, logistics and medical equipment sectors who need a structured and standardized way of running
|
||||
procedures and keeping audit trails.
|
||||
|
||||
**Moving fast in regulated markets**
|
||||
## Moving fast in regulated markets
|
||||
|
||||
The team has a background in engineering from Northrop, Google, and SpaceX and understand the technical benefits Postgres offers as a
|
||||
battle tested open-source relational database.
|
||||
As a startup, Epsilon3 needs to move fast and scale. They require security, reliability, and performance.
|
||||
|
||||
Whilst the team know they want to use Postgres, they also understand setting up a scalable back-end takes time and must be maintained.
|
||||
Realtime functionality is also a key for their customers so they can see how running procedures are progressing in real time.
|
||||
The team has a background in engineering from Northrop, Google, and SpaceX and understands the technical benefits Postgres offers as a
|
||||
battle-tested open-source relational database.
|
||||
|
||||
As a startup, Epsilon3 need to move fast AND scale. They require security, reliability, and performance.
|
||||
Real-time functionality is also a key for their customers to see how running procedures are progressing as the changes occur.
|
||||
|
||||
The space industry is highly regulated adding complexity. For example, in the USA deployments must be in an ITAR-compliant way like AWS
|
||||
GovCloud while customers in countries outside the USA may need to host their data within their own country.
|
||||
This means that Epsilon3 must be able to offer flexible hosting options, including on premises deployment.
|
||||
The space industry is highly regulated, adding complexity. For example, in the USA, deployments must be in an ITAR-compliant way
|
||||
(for instance AWS GovCloud supports ITAR compliance) while customers in countries outside the USA may need to host their data within their own
|
||||
country. These customer requirements mean Epsilon3 must be able to offer flexible hosting options, including on-premises deployment.
|
||||
|
||||
<Quote
|
||||
img="aaron-epsilon3.png"
|
||||
@@ -69,23 +66,24 @@ This means that Epsilon3 must be able to offer flexible hosting options, includi
|
||||
</p>
|
||||
</Quote>
|
||||
|
||||
**Supabase gives Postgres users Supa-powers**
|
||||
### Supabase gives Postgres users Superpowers
|
||||
|
||||
The team implemented a self hosted Supabase setup. For a customer in production in the USA this means they can use AWS infrastructure with
|
||||
the Supabase API powering an RDS Postgres instance. This gives the perfect balance of rapid development, reduced DevOps, and flexible hosting
|
||||
options - crucial for their customers. As Supabase uniquely offers realtime for Postgres they are able to allow their customers to see updates
|
||||
from running procedures. Supabase also offers well supported client libraries that make row level security easy to use, which is crucial for the
|
||||
Epsilon3 team to deliver on their future roadmap. Finally all this is easy and fast for the team to set up, even when self hosting which means
|
||||
the team can focus on what they do best - helping their customers run complex operations smoothly.
|
||||
The team implemented a self-hosted Supabase setup. They use AWS with a self-hosted Supabase API powering an RDS Postgres instance.
|
||||
This setup gives a balance of rapid development, reduced DevOps, and flexible hosting options. As Supabase uniquely offers real-time for
|
||||
Postgres, it allows their customers to see updates from running procedures. Supabase offers well-supported client libraries that make
|
||||
Postgres Row Level Security easy to use, which is a critical item on the Epsilon3 roadmap.
|
||||
|
||||
With this implementation Epsilon3 get all the benefits of Postgres plus the smooth developer experience and support that Supabase is known for,
|
||||
without making compromises to meet compliance needs.
|
||||
All this was easy for the team to set up, even with self-hosting, so the team was able to focus on what they do best—helping their customers
|
||||
run complex operations smoothly. With this implementation, Epsilon3 gets all the benefits of Postgres, plus the smooth developer experience and
|
||||
support that Supabase is known for, without compromising their compliance needs.
|
||||
|
||||

|
||||

|
||||
|
||||
### Self-hosted Supabase, a superpower
|
||||
|
||||
Self-hosting Supabase means the crew at Epsilon3 are able to move fast to revolutionise space operations securely and reliably in realtime
|
||||
whilst staying compliant. The team are now seeing demand from other industries and are confident in their scaling capability because
|
||||
they know it's just Postgres under the hood. Check out the Epsilon3 website to learn more about the team and their OS for space operations.
|
||||
If you are interested in self-hosting Supabase then you can do XYZ action.
|
||||
Self-hosting Supabase allows the crew at Epsilon3 to move fast. They are revolutionizing space operations securely and reliably in real-time whilst
|
||||
staying compliant. The team is now seeing demand from other industries and is confident in their scaling capability because they know it's
|
||||
just Postgres under the hood.
|
||||
|
||||
Check out the [Epsilon3 website](https://www.epsilon3.io/) to learn more about the team and their OS for space operations. If you are interested
|
||||
in self-hosting Supabase then you can **contact us** to learn more.
|
||||
@@ -0,0 +1,136 @@
|
||||
---
|
||||
title: 'Supabase Community Day'
|
||||
description: Community Day
|
||||
author: steve_chavez
|
||||
author_url: https://github.com/steve-chavez
|
||||
author_image_url: https://github.com/steve-chavez.png
|
||||
authorURL: https://github.com/steve-chavez
|
||||
thumb: launch-week-sql-day-1-community-day/launch-week-sql-day-1-community-day-thumb.jpg
|
||||
image: launch-week-sql-day-1-community-day/launch-week-sql-day-1-community-day-og.jpg
|
||||
tags:
|
||||
- launch-week
|
||||
date: '2021-07-26'
|
||||
toc_depth: 2
|
||||
---
|
||||
|
||||
Supabase has grown a lot [^1] since last [Launch Week](https://supabase.io/blog/2021/03/25/launch-week),
|
||||
but it wouldn't be possible without some amazing open source tools.
|
||||
Since we're shipping a few upgrades this week we feel it's only fair
|
||||
to shine a spotlight on some tools and community efforts that make Supabase possible.
|
||||
|
||||
## PostgreSQL version 13.3
|
||||
|
||||

|
||||
|
||||
PostgreSQL is a big part of Supabase, and it's also a huge inspiration - the speed that they ship, their community organization,
|
||||
and their absolute dedication towards reliability. PostgreSQL 13.3 was released in June and (from today) every new Supabase project will
|
||||
be on [PostgreSQL version 13.3](/blog/2021/07/26/supabase-postgres-13).
|
||||
|
||||
### Giving back
|
||||
|
||||
Supabase makes it easy to get started with Postgres, but we think you should try it even if you don't want to use Supabase. Here's a
|
||||
few ways we make it easy to use PostgreSQL without Supabase:
|
||||
|
||||
- Supabase was the first company to put Postgres in the [Digital Ocean Marketplace](https://marketplace.digitalocean.com/apps/supabase-postgres).
|
||||
Since then it's been installed over 1000 times (not by us!).
|
||||
- We provide a Postgres image in the [AWS marketplace](https://aws.amazon.com/marketplace/pp/prodview-lk2pfa5nafecg).
|
||||
- We're packaging the Marketplace version, [along with "Bundles"](/blog/2021/07/26/supabase-postgres-13#postgresql-bundles)
|
||||
- We're developing a few extensions: [supautils](https://github.com/supabase/supautils), [pg_net](https://github.com/supabase/pg_net), and a couple more soon to be announced.
|
||||
|
||||
### Get involved
|
||||
|
||||
- Follow the official [PostgreSQL Twitter](https://twitter.com/PostgreSQL) account.
|
||||
- Join the official [mailing lists](https://www.postgresql.org/community/).
|
||||
|
||||
## PostgREST version 8.0
|
||||
|
||||

|
||||
|
||||
This new PostgREST stable version comes with the improvements we've made to make it truly enterprise-grade. Due to our commitment with OSS,
|
||||
all of our improvements are upstreamed, so you can fully use them on your own self-hosted projects.
|
||||
|
||||
### Highlights
|
||||
|
||||
**Improved Performance**: Due to Supabase's high throughput requirements, PostgREST 8.0 handles up to 50% more throughput on
|
||||
GET requests, according to our benchmarks. We converted all SELECT queries to use prepared statements and reduced logging
|
||||
verbosity to make this possible.
|
||||
|
||||
**Reduced downtime**: we need PostgREST to be more "set it and forget it", so reloading schema cache now has zero downtime.
|
||||
|
||||
**Dynamic Configuration**: we've made it easier to handle PostgREST configuration at scale (we manage thousands of PostgREST instances).
|
||||
This new version includes the ability to use an in-database configuration that is reloadable through a `NOTIFY` command.
|
||||
|
||||
**Less admin burden**: PostgREST previously required the `pg_listen` utility to reload its schema cache. This is no longer needed.
|
||||
The schema cache is reloadable with a simple `NOTIFY` command.
|
||||
|
||||
**Better diagnostic information**: in the rare cases where PostgREST fails, we want to find the exact root cause quickly.
|
||||
For this we've improved its logging by adding logging levels and timestamps to all server errors.
|
||||
|
||||
**Simpler OpenAPI**: showing a complete OpenAPI output used to require a highly-privileged `anon` role. With the new `openapi-mode`,
|
||||
this is no longer needed and `anon` can be kept with minimal privileges.
|
||||
|
||||
The community has made many more enhancements and bug fixes for the new version. See
|
||||
[v8.0 CHANGELOG](https://github.com/PostgREST/postgrest/releases/tag/v8.0.0) for the full list.
|
||||
|
||||
### Get Started
|
||||
|
||||
Want to get started with PostgREST? The Supabase community has built a number of client libraries to make it simpler to use:
|
||||
|
||||
- Javascript: [postgrest-js](https://github.com/supabase/postgrest-js)
|
||||
- Rust: [postgrest-rs](https://github.com/supabase/postgrest-rs)
|
||||
- Go: [postgrest-go](https://github.com/supabase/postgrest-go)
|
||||
- Python: [postgrest-py](https://github.com/supabase/postgrest-py)
|
||||
- Dart: [postgrest-dart](https://github.com/supabase/postgrest-dart)
|
||||
- C#: [postgrest-csharp](https://github.com/supabase/postgrest-csharp)
|
||||
- Swift: [postgrest-swift](https://github.com/supabase/postgrest-swift)
|
||||
- Ruby: [postgrest-rb](https://github.com/supabase/postgrest-rb)
|
||||
- Kotlin: [postgrest-kt](https://github.com/supabase/postgrest-kt)
|
||||
|
||||
### Get involved
|
||||
|
||||
- Help with [PostgREST development](https://github.com/PostgREST/postgrest/blob/main/.github/CONTRIBUTING.md).
|
||||
- Help with [PostgREST docs translations](https://github.com/PostgREST/postgrest-docs/issues/393).
|
||||
- Follow the official [PostgREST Twitter](https://twitter.com/postgrest_org) account.
|
||||
|
||||
## Supabase Flutter/Dart (Beta release)
|
||||
|
||||

|
||||
|
||||
While the Supabase team have been busy with the Javascript libraries, the community have been beavering away with Dart. They've even
|
||||
[built fully-functional apps](https://www.producthunt.com/posts/spot-2d300f54-7a0a-4dbf-aee2-4a75311217cc) using Supabase Auth and Storage.
|
||||
|
||||
Today the Community are releasing both the Flutter and Dart libraries in Beta (with a bit of help from the Supabase team).
|
||||
|
||||
### Get started
|
||||
|
||||
- Check out the [Flutter Quickstart Guide](https://supabase.io/docs/guides/with-flutter)
|
||||
- Check out the code:
|
||||
- Supabase Flutter: [GitHub](https://github.com/supabase/supabase-flutter/) | [Release](https://pub.dev/packages/supabase_flutter)
|
||||
- Supabase Dart: [GitHub](https://github.com/supabase/supabase-dart/) | [Release](https://pub.dev/packages/supabase)
|
||||
|
||||
### Get involved
|
||||
|
||||
- Help [write](https://supabase.io/docs/handbook/supasquad#author) the Flutter Docs.
|
||||
- Help [maintain](https://supabase.io/docs/handbook/supasquad#maintainer) the [Flutter](https://github.com/supabase/supabase-flutter/)
|
||||
and [Dart](https://github.com/supabase/supabase-dart/) libraries.
|
||||
|
||||
## Supabase Discord
|
||||
|
||||

|
||||
|
||||
OK, OK, we get it - GitHub [Discussions](https://github.com/supabase/supabase/discussions) aren't enough for y'all. While we've been trying
|
||||
to keep the conversation contained to our GitHub org, the community has been creating [subreddits](https://www.reddit.com/r/Supabase/),
|
||||
StackOverflow [tags](https://stackoverflow.com/questions/tagged/supabase), and GitHub [topics](https://github.com/topics/supabase).
|
||||
|
||||
A few weeks ago one of the community created a Community-led Discord, and so the team figured we might as well join the fun.
|
||||
|
||||
We'll still be using Discussions for debugging, but if you're looking for a place to hang out with Supabase developers, Discord is where to find it.
|
||||
|
||||
### Get involved
|
||||
|
||||
Join the Supabase Community Discord: [discord.supabase.com](http://discord.supabase.com), say hi, and start building.
|
||||
|
||||
[^1]:
|
||||
Supabase has been one of the fastest growing startups [on GitHub](https://github.com/supabase/supabase) for four consecutive quarters:
|
||||
207% in [Q3](https://runacap.com/ross-index/q3-2020/) 2020; 1,373% in [Q4](https://runacap.com/ross-index/q4-2020/) 2020;
|
||||
462% in [Q1](https://runacap.com/ross-index/q1-2021/) 2021; 1,653% in [Q2](https://runacap.com/ross-index/q2-2021/) 2021.
|
||||
@@ -0,0 +1,122 @@
|
||||
---
|
||||
title: 'Supabase is now on Postgres 13.3'
|
||||
description: From today, new Supabase projects will be on a version of Supabase Postgres that runs on Postgres 13.3.
|
||||
author: angelico_de_los_reyes
|
||||
author_url: https://github.com/dragarcia
|
||||
author_image_url: https://github.com/dragarcia.png
|
||||
authorURL: https://github.com/dragarcia
|
||||
image: pg13/postgres-13-og.jpg
|
||||
thumb: pg13/postgres-13-thumb.jpg
|
||||
tags:
|
||||
- launch-week
|
||||
- database
|
||||
date: '2021-07-26'
|
||||
toc_depth: 2
|
||||
---
|
||||
|
||||
From today, new Supabase projects will be on a version of [Supabase Postgres](https://github.com/supabase/postgres) that runs
|
||||
on [Postgres 13.3](https://www.postgresql.org/about/news/postgresql-13-released-2077/). This won't be the only big change however in this version.
|
||||
Here are a few other things that have changed under the hood.
|
||||
|
||||
## PostgreSQL version 13.3
|
||||
|
||||
We've jumped from PostgreSQL 12.0 to PostgreSQL [version 13.3](https://www.postgresql.org/docs/13/release-13-3.html), introducing
|
||||
significant performance improvements and some great new functionality. Some changes include:
|
||||
|
||||
- native [UUID generation](https://www.postgresql.org/docs/13/functions-uuid.html) (!) using `gen_random_uuid`
|
||||
- a new JSONB [datetime](https://www.postgresql.org/docs/13/functions-json.html) function
|
||||
- vacuuming indexes in [parallel](https://www.postgresql.org/docs/13/sql-vacuum.html)
|
||||
- [incremental sorting](https://www.postgresql.org/docs/13/using-explain.html#USING-EXPLAIN-BASICS)
|
||||
- smaller [btree indexes](https://www.postgresql.org/docs/13/btree-implementation.html#BTREE-DEDUPLICATION)
|
||||
- improvements to [extended statistics](https://www.postgresql.org/docs/13/planner-stats.html#PLANNER-STATS-EXTENDED)
|
||||
|
||||
## Supabase Versioning
|
||||
|
||||
Our [Postgres repo](https://github.com/supabase/postgres) has jumped from `0.15.0` to `13.3.0`. From now on, both major and minor versions of
|
||||
Supabase Postgres will follow PostgreSQL. This makes it much easier to ascertain what version of PostgreSQL is installed. In the situation wherein
|
||||
there are no updates to PostgreSQL in between releases, the patch version will be bumped up.
|
||||
|
||||
## Large System Extensions (LSE) enabled for ARM instances
|
||||
|
||||
<small>
|
||||
*Disclaimer for self-hosting: This is not available for x86 instances. All instances on the
|
||||
Supabase platform have this enabled by default.*
|
||||
</small>
|
||||
|
||||
The recent wave of Graviton 2 instances from AWS introduces support for the Large System Extensions (LSE). This looks to greatly enhance
|
||||
application performance through atomics, and
|
||||
[improves locking and synchronisation performance across large systems](https://github.com/aws/aws-graviton-getting-started#building-for-graviton-and-graviton2).
|
||||
|
||||
### Preliminary Benchmarks
|
||||
|
||||
Below is a comparison between the ARM versions of Supabase Postgres `0.15.0` and `13.3.0`. Both are using `m6gd.8xlarge` instances
|
||||
and follow the PostgreSQL configuration [here](https://www.percona.com/blog/2021/01/22/postgresql-on-arm-based-aws-ec2-instances-is-it-any-good/).
|
||||
The following configuration of `pgbench` was used.
|
||||
|
||||
```bash hideCopy
|
||||
pgbench -i -s 150
|
||||
```
|
||||
|
||||
Running the benchmark with 2, 4, 8, 16, 64, and 128 clients:
|
||||
|
||||
```bash hideCopy
|
||||
pgbench -P 5 -c {num_clients} -j {num_clients} -T 300 -M prepared postgres
|
||||
```
|
||||
|
||||

|
||||
|
||||
## Ubuntu 20.04
|
||||
|
||||
We have taken the opportunity to upgrade new projects from Ubuntu 18.04 to Ubuntu 20.04. A switch to Ubuntu 20.04 guarantees that the underlying
|
||||
OS of Supabase Postgres is supported by the Canonical team up until the year 2025 (2023 for Ubuntu 18.04).
|
||||
|
||||
## Built from source
|
||||
|
||||
Driven by the need to enable LSE, the underlying PostgreSQL in this version was built from the ground up instead of downloaded binaries.
|
||||
Supabase Postgres can now be easily upgraded whenever a new major or minor version of PostgreSQL is released. When PostgreSQL 14 comes out,
|
||||
expect Supabase Postgres 14 to quickly follow.
|
||||
|
||||
## New Extensions
|
||||
|
||||
### `pgRouting`
|
||||
|
||||
An extension of PostGIS, [`pgRouting`](https://pgrouting.org/) provides geospatial routing functionality.
|
||||
|
||||
More information can be found [here](https://docs.pgrouting.org/latest/en/index.html).
|
||||
|
||||
### `wal2json`
|
||||
|
||||
Converts WAL output into clean and organized JSON objects.
|
||||
|
||||
More information can be found [here](https://github.com/eulerto/wal2json).
|
||||
|
||||
## Enhanced security
|
||||
|
||||
To help combat brute force attacks, `fail2ban` has now been configured to protect direct connections to Postgres. This applies to both
|
||||
ports `5432` (PostgreSQL) and `6543` (PgBouncer).
|
||||
|
||||
IPs get banned for 10 minutes after three failed attempts, and we'll continue to fine-tune and improve the protections applied to the
|
||||
database servers based on evolving traffic patterns.
|
||||
|
||||
## PostgreSQL bundles
|
||||
|
||||
`[Coming Soon]`
|
||||
|
||||
Last but not the least, we're diversifying the images of Supabase Postgres available in the AWS and Digital Ocean Marketplaces.
|
||||
|
||||
Instead of a single option, we'll soon offer four configurations of PostgreSQL. Each bundle offers functionality for
|
||||
common use-cases. For example, if you're using Postgres with Serverless functions, you might want to run the PgBouncer bundle. If you want an
|
||||
HTTP API with your Postgres offering you might want to run the PostgREST bundle.
|
||||
|
||||
| `Name` | `PostgreSQL` | `PgBouncer` | `PostgREST` |
|
||||
| ----------------------------------- | ------------ | ----------- | ----------- |
|
||||
| Supabase Postgres | ✅ | | |
|
||||
| Supabase Postgres: PgBouncer Bundle | ✅ | ✅ | |
|
||||
| Supabase Postgres: PostgREST Bundle | ✅ | | ✅ |
|
||||
| Supabase Postgres: Complete Bundle | ✅ | ✅ | ✅ |
|
||||
|
||||
Each offering will be available for both the `x86` and `arm` architectures.
|
||||
|
||||
## Try PostgreSQL 13
|
||||
|
||||
Try the new features of PostgreSQL 13.3 today by creating a [new project](https://app.supabase.io/) on Supabase.
|
||||
@@ -0,0 +1,94 @@
|
||||
---
|
||||
title: 'Spot: a video sharing app built with Flutter'
|
||||
description: Spot is a geolocation-based video-sharing app with some social networking features.
|
||||
author: rory_wilding
|
||||
author_url: https://github.com/roryw10
|
||||
author_image_url: https://github.com/roryw10.png
|
||||
authorURL: https://github.com/roryw10
|
||||
image: spot/og-spot-flutter-supabase.jpg
|
||||
thumb: spot/cover-spot-flutter-supabase.jpg
|
||||
tags:
|
||||
- case-study
|
||||
date: '2021-07-27'
|
||||
toc_depth: 2
|
||||
---
|
||||
|
||||
Learn why Tyler decided Flutter and Supabase are the perfect tech-stack shipping innovative ideas fast.
|
||||
|
||||
[Tyler Shukert](https://twitter.com/dshukertjr) is an indie developer who has been building websites and applications for seven years.
|
||||
Tyler is a Firebase & Flutter expert who recently discovered Supabase. After falling in love with Supabase,
|
||||
Tyler decided to launch his latest app. [Spot](https://www.producthunt.com/posts/spot-2d300f54-7a0a-4dbf-aee2-4a75311217cc)
|
||||
is a geolocation-based video-sharing app with some social networking features.
|
||||
|
||||
## NoSQL doesn't mean No Schema
|
||||
|
||||
Tyler loves how easy it is to create high-quality web and mobile applications with Firebase. For the past few years he has honed
|
||||
his Flutter, Angular, and Firebase skills to quickly ship mobile and web apps. But the more his development expertise grew,
|
||||
the more he understood the limitations of Firebase.
|
||||
|
||||
Before starting a project, Tyler is never sure if the project will grow. It could be an overnight success, or it might need to
|
||||
pivot in a different direction. He finds this is particularly difficult with Firebase as he faces a denormalization dilemma.
|
||||
Denormalization means combining the data into a single table to make data retrieval faster. Google promotes denormalization
|
||||
as best practice for a snappier app experience. Denormalisation in Firebase takes work and requires additional development
|
||||
time. For new projects, it is often unclear if they will reach a scale justifying the effort denormalization requires.
|
||||
In relational databases like Postgres, data is normalized, meaning reduced data redundancy with maintained data integrity.
|
||||
|
||||
## Supabase + Flutter: a match made in heaven
|
||||
|
||||
When Tyler discovered Supabase on Twitter, he was intrigued by the promise of Postgres with Firebase-like features.
|
||||
He wanted the benefits of SQL and Relational schemas, and decided to build an app to test Supabase.
|
||||
|
||||
Tyler had been thinking about building Spot, a mobile app for sharing geo-based video content. When he previously planned Spot,
|
||||
he felt like hacking around Firebase would be too much effort. After researching the PostGIS extension for geospatial data,
|
||||
he realized Supabase was the perfect fit. As an avid Flutter fan, Supabase's Dart library was a bonus.
|
||||
Tyler loves the open-source nature of Supabase and immediately began contributing to the Dart library to enable functionality that he needed.
|
||||
|
||||
Tyler decided that Spot would be perfect to showcase the power of Supabase and Flutter. Since he's active in the open-source community,
|
||||
he decided to open-source the whole project, making Spot one of the most interesting Supabase examples.
|
||||
|
||||

|
||||
|
||||
## Comparing Firebase to Supabase
|
||||
|
||||
Although Spot seems like simple, it has a lot of complicated components. Implementing social "Likes" requires `count` functionality,
|
||||
which is notoriously tricky in Firebase. In Supabase, because it's just Postgres under the hood, `count` is implemented
|
||||
using a simple SQL `count` query.
|
||||
|
||||
Supabase has Row-Level Security, which Tyler uses as a filter - something he can't do with Firebase.
|
||||
|
||||
Spot uses Supabase Storage for managing large video files. Firebase Storage [has a reputation](https://stackoverflow.com/questions/43851742/firebase-storage-very-slow-compared-to-firebase-hosting) for slowness until it is public, which was a privacy concern for Tyler. With Supabase Storage, this wasn't an issue - storage is performant and secure.
|
||||
|
||||
The Firebase API pricing model makes it is difficult to predict pricing upfront for new projects. With Supabase,
|
||||
Tyler doesn't need to worry about how many API calls his project makes.
|
||||
|
||||
Supabase gives Spot speed, performance, and predictable pricing.
|
||||
|
||||
As of today, Tyler has around 3000 installs for Spot and is getting ready to add new functionality. He is confident Supabase,
|
||||
Postgres, and his data structure will enable future development.
|
||||
|
||||
|
||||
<Quote
|
||||
img="tyler-spot.jpg"
|
||||
caption="Tyler Shukert, creator of Spot."
|
||||
>
|
||||
<p>
|
||||
As soon as I saw Supabase I knew it was the perfect technology to use alongside Flutter to build apps faster than ever.
|
||||
For apps like Spot where we handle user submitted files, it is very easy to manage them securely.
|
||||
</p>
|
||||
<p>
|
||||
Supabaseを最初発見した時にこれとFlutterを組み合わせれば今まで以上に爆速でアプリ開発ができるだろうと思いました。
|
||||
Spotのようにユーザーがファイルを投稿するアプリの場合でもセキュアに取り扱うのが簡単で本当に助かります。
|
||||
</p>
|
||||
</Quote>
|
||||
|
||||
|
||||
## Spot is Open Source
|
||||
|
||||
With Supabase, Tyler can use Flutter to build a performant app quickly at a low cost. Tyler is now a massive fan of the Supabase
|
||||
experience and has even joined the SupaSquad.
|
||||
|
||||
You can download and install spot for [iOS](https://apps.apple.com/us/app/spot-videos/id1564675926?utm_source=supabase&utm_campaign=static)
|
||||
and [Android](https://play.google.com/store/apps/details?id=app.spotvideo&utm_source=supabase&utm_campaign=static)
|
||||
to see just how snappy his setup is.
|
||||
Tyler has fully open-sourced his example - you can [clone the repo](https://github.com/dshukertjr/spot)
|
||||
and use it as the basis of your next big idea.
|
||||
@@ -0,0 +1,169 @@
|
||||
---
|
||||
title: 'Supabase Storage now in Beta'
|
||||
description: Supabase Storage moves into Beta.
|
||||
author: inian
|
||||
image: launch-week-sql-day-2/supabase-storage-beta-og.jpg
|
||||
thumb: launch-week-sql-day-2/supabase-storage-beta.jpg
|
||||
tags:
|
||||
- storage
|
||||
- launch-week
|
||||
date: '2021-07-27'
|
||||
toc_depth: 2
|
||||
---
|
||||
|
||||
At Supabase, one of our core values is [Kaizen](https://en.wikipedia.org/wiki/Kaizen) - continuous improvement. And that's exactly what we've been doing with Storage since it [launched](https://supabase.io/blog/2021/03/30/supabase-storage) three months ago. Today, we are launching the Sequel to Storage Alpha (I bet you didn't see that coming): Storage Beta!
|
||||
|
||||
## Streaming Media
|
||||
|
||||
We've added support for streaming audio and video files.
|
||||
|
||||
Clients can use the `Content-Range` HTTP header to request specific parts of a file from a server. This allows them to intelligently download the parts of the video that a user is viewing, without buffering irrelevant sections of the media file. Supabase Storage now supports this header, making it easier to host and watch [nyan cat videos](https://www.youtube.com/watch?v=SkgTxQm9DWM) all day long.
|
||||
|
||||
<video width="99%" autoPlay="autoplay" muted playsInline controls={true}>
|
||||
<source
|
||||
src="/new/videos/blog/launch-week-storage-2/nyan-cat.mp4"
|
||||
type="video/mp4"
|
||||
muted
|
||||
playsInline
|
||||
/>
|
||||
</video>
|
||||
|
||||
## Public Buckets
|
||||
|
||||
Public Buckets have been one of our most requested features. We launched without them because there are too [many horror stories](https://www.google.com/search?q=s3+bucket+negligence+award&oq=s3+bucket+negligence+award) of S3 buckets unintentionally exposing objects. We wanted to take the time to implement safeguards against this.
|
||||
|
||||
To enable this feature safely, buckets are made private by default, with an extremely prominent warning in the dashboard when you choose to make them public.
|
||||
|
||||
You can make objects public in S3 via multiple mechanisms (e.g. tags, or prefixes). While this allows for flexibility, it makes it hard to discover publicly exposed objects. To prevent any confusion, we decided that buckets must be public in their entirety. This public visibility straightforward - if it's in a public bucket, it's public!
|
||||
|
||||
Objects in public buckets can be accessed via a URL without any Authorization tokens or headers. This makes them perfect for hosting assets for your web or mobile application.
|
||||
|
||||
Public buckets still require [Auth Policies](https://supabase.io/docs/guides/storage#policy-examples) to upload and delete objects, allowing you to securely manage their contents.
|
||||
|
||||
<video width="99%" autoPlay="autoplay" muted playsInline controls={true}>
|
||||
<source src="/new/images/blog/2021-june/public-buckets.mp4" type="video/mp4" muted playsInline />
|
||||
</video>
|
||||
|
||||
## Directory uploads
|
||||
|
||||
You can now upload an entire directory to Supabase Storage and the directory structure is fully preserved after the upload. We used the [File and Directory entries API](https://developer.mozilla.org/en-US/docs/Web/API/File_and_Directory_Entries_API) for implementing this. This is a non-standard API, but we didn't find any compatibility issues in the browsers we support. So, now you can upload the [Storage Github repo](https://github.com/supabase/storage-api/) to storage 🤓
|
||||
|
||||
<video width="99%" autoPlay="autoplay" muted playsInline controls={true}>
|
||||
<source
|
||||
src="/new/videos/blog/launch-week-storage-2/directory-uploads.mp4"
|
||||
type="video/mp4"
|
||||
muted
|
||||
playsInline
|
||||
/>
|
||||
</video>
|
||||
|
||||
## A New Policy Editor
|
||||
|
||||
Postgres [Row Level Security](https://www.postgresql.org/docs/13/ddl-rowsecurity.html) (RLS) is at the core of Supabase Storage and Auth. RLS lets you define complex policies, tightly integrated with Supabase Auth users, using the language you're already comfortable with - SQL.
|
||||
|
||||
However, getting started with RLS can be daunting. To make it more approachable for beginners, we've included a set of pre-defined templates on our Dashboard, covering common use-cases.
|
||||
|
||||

|
||||
|
||||
Once you've selected a template, you choose which operations to allow and the Dashboard determines which API functions can access the bucket. For example, a user with INSERT permissions will be able to call the `createObject`, `copyObject` and `getSignedObject` functions in the `supabase-js` library.
|
||||
|
||||

|
||||
|
||||
After writing the policy definition (which can be any valid SQL expression), you get an opportunity to review the final policy before saving. We made sure that there is no magic going on behind the scenes: you can always see the underlying SQL definition of the policies. As you become more comfortable with Row Level Security, you can define these policies directly using our SQL editor.
|
||||
|
||||
## Using Storage in Local development
|
||||
|
||||
It took some time to enable Storage on self-hosted Supabase. We wanted to provide a completely local experience during development, but storage had a hard dependency on an object storage service like S3. This required developers to create an S3 bucket, an IAM user in AWS, and add the credentials of the IAM user to the local setup, which was far from an ideal experience.
|
||||
|
||||
From day 1, Supabase Storage was designed so that it would be easy to add new Storage backends. We knew we'd add more storage options like Google Cloud Storage or Backblaze, but little did we expect that this would be useful for our self-hosting setup! We implemented a new Storage Backend which [use a local filesystem](https://github.com/supabase/storage-api/blob/master/src/backend/file.ts) for storing objects. You can now get started with Storage without any additional setup, giving you a completely self-contained instance of Supabase.
|
||||
|
||||
Check out our updated [self hosting guide](https://supabase.io/docs/guides/self-hosting) and our [CLI](https://github.com/supabase/cli) to get started.
|
||||
|
||||
## Upload anything
|
||||
|
||||
At launch, you could pass in a `File` object and `supabase-js` used `FormData` to send a request to the storage server to upload the file. This made it easy to send the cache control information and other options directly to the server as a multipart request.
|
||||
|
||||
However, `FormData` is only supported in the browser, making `supabase-js` incompatible with Node.js. The simplest way to solve this would have been to include the [FormData polyfill](https://www.npmjs.com/package/form-data) along with the library.
|
||||
|
||||
At Supabase, we are [maniacal about performance](https://supabase.io/blog/2020/12/13/supabase-dashboard-performance). Keeping our client libraries lean is a key differentiator. Our entire client library (including the clients for postgrest, storage, realtime and auth) is just 15.8 kb. If you are just interested in using a single service like storage, you can use the `storage-js` library directly which is [even smaller](https://bundlephobia.com/package/@supabase/storage-js@1.4.0). This made including polyfills like Formdata a no-go.
|
||||
|
||||

|
||||
|
||||
We also considered shipping separate bundles for Node.js and the browser. This would have avoided polyfills for APIs which are already supported in each browser. However, this comes with an increase in complexity to our build process, and users would need to choose which flavor of the library to use in different environments like React Native, Deno, etc. We want to make our libraries universal.
|
||||
|
||||
Instead, we modified the storage server to accept Binary data directly. With this change, you can directly upload binary Data and even NodeJS streams to the storage API.
|
||||
|
||||

|
||||
|
||||
With this change in place, the client library supports uploading `ArrayBuffer`, `ArrayBufferView`, `Blob`, `Buffer`, `File`, `FormData`, `NodeJS.ReadableStream`, `ReadableStream<Uint8Array>` - without any change to the bundle size! This should enable you to use storage from an even wider range of environments.
|
||||
|
||||
## Context menus
|
||||
|
||||
The storage explorer in our Dashboard feels like using a file explorer in your operating system. There were a lot of challenges to make it feel intuitive and robust, since S3 is a not a traditional filesystem. For example, S3 doesn't support a move operation natively - you need to copy the object to the new location and delete the original object. S3 also doesn't have a concept of directory, which means there is no API call to rename a directory. But to make the storage explorer feel like a native file explorer, we implemented these features.
|
||||
|
||||
Context menus on folders
|
||||

|
||||
|
||||
Context menus on files
|
||||

|
||||
|
||||
### The case of the disappearing folders
|
||||
|
||||
As we already mentioned, S3 doesn't really have a concept of directories. So if a user uploads an object with path `dir/subdir/avatar.png`, the dir and subdir are automatically "created" and there is no explicit API call to create them.
|
||||
|
||||
This leads to an issue where if a user creates an empty directory and refreshes the page, the directory disappears since it is not persisted to S3. To simulate a normal filesystem (where empty directories are not garbage collected), we upload an empty file when the user creates a directory on the dashboard. The dashboard hides this placeholder file and the placeholder is deleted when the user uploads an object in the directory - voila, no more disappearing directores!
|
||||
|
||||
## Performance improvements for large buckets
|
||||
|
||||
We significantly improved rendering for a large number of items in the Dashboard. We use a virtualization library to render the objects in view and actively discard DOM elements which are not currently rendered from memory. This makes scrolling through thousands of items buttery smooth.
|
||||
|
||||
Here is a demo testing rendering the heaviest object known to mankind - the `node_modules` folder!
|
||||
|
||||
<video width="99%" autoPlay="autoplay" muted playsInline controls={true}>
|
||||
<source
|
||||
src="/new/videos/blog/launch-week-storage-2/large-buckets.mp4"
|
||||
type="video/mp4"
|
||||
muted
|
||||
playsInline
|
||||
/>
|
||||
</video>
|
||||
|
||||
## API changes
|
||||
|
||||
Supabase Storage now supports `upsert`. Shoutout to [@ankitjena](https://github.com/ankitjena) for
|
||||
[this Pull Request](https://github.com/supabase/storage-api/pull/32).
|
||||
|
||||

|
||||
|
||||
We also have automated API docs generated [here](https://supabase.github.io/storage-api/#/) if you want to use the Storage API directly.
|
||||
|
||||
### Storage in the wild
|
||||
|
||||
We have a few production applications using Supabase Storage. Wataru is using Storage to power his community site [Shikutoku](https://shikutoku.me/) and Tyler is using Supabase Storage to store short video clips uploaded to his [Spot app](https://supabase.io/blog/2021/07/27/spot-flutter-with-postgres) built with Flutter
|
||||
|
||||
<Quote img="tyler-spot.jpg" caption="Tyler Shukert, creator of Spot">
|
||||
<p>
|
||||
As soon as I saw Supabase I knew it was the perfect technology to use alongside Flutter to build
|
||||
apps faster than ever. For apps like Spot where we handle user submitted files, it is very easy
|
||||
to manage them securely.
|
||||
</p>
|
||||
<p>
|
||||
Supabaseを最初発見した時にこれとFlutterを組み合わせれば今まで以上に爆速でアプリ開発ができるだろうと思いました。Spotのようにユーザーがファイルを投稿するアプリの場合でもセキュアに取り扱うのが簡単で本当に助かります。
|
||||
</p>
|
||||
</Quote>
|
||||
|
||||
<Quote img="wataru.jpeg" caption="Wataru Yonamine, creator of Shikutoku">
|
||||
<p>
|
||||
I think it’s a great service, simple and scalable. I like that the dashboard makes it easy to
|
||||
check and search for images.
|
||||
</p>
|
||||
<p>
|
||||
シンプルで拡張性のある素晴らしいサービスだと思います。ダッシュボードで画像が確認しやすく、検索できるのもいいですね。
|
||||
</p>
|
||||
</Quote>
|
||||
|
||||
## What's next
|
||||
|
||||
We're planning a Content Delivery Network for faster downloads, as well as basic transformation and optimization support for media files (like resizing, etc). We will continue our Kaizen on smaller improvements like allowing configurable upload limits and improving service stability and scalability.
|
||||
|
||||
Anything else you want to see or can help implement in Storage? Reach out on our [Discord channel](https://discord.supabase.com/) and give Storage a try by [creating a project](https://app.supabase.io/) on Supabase!
|
||||
@@ -17,12 +17,12 @@ const a: A = data
|
||||
const Annoucement = () => {
|
||||
if (!a.show) return null
|
||||
return (
|
||||
<div className="bg-brand-700 dark:bg-brand-800">
|
||||
<div className="bg-indigo-400 dark:bg-indigo-400">
|
||||
<div className="flex items-center justify-center py-2 mx-auto space-x-2 text-white lg:container lg:px-16 xl:px-20 text-sm md:text-base">
|
||||
<span>{a.text}</span>
|
||||
<a
|
||||
href={a.link.url}
|
||||
className="inline-flex items-center px-2 py-1 space-x-1 text-xs transition-colors bg-white rounded-full text-brand-800 dark:hover:text-brand-800 hover:text-brand-800 hover:bg-opacity-90"
|
||||
className="inline-flex items-center px-2 py-1 space-x-1 text-xs transition-colors bg-indigo-900 rounded text-white dark:hover:text-indigo-100 hover:text-indigo-100 hover:bg-opacity-90"
|
||||
>
|
||||
{a.link.text} <IconArrowRight size="tiny" />
|
||||
</a>
|
||||
|
||||
@@ -2,7 +2,7 @@ import React, { useState } from 'react'
|
||||
import Link from 'next/link'
|
||||
import { useRouter } from 'next/router'
|
||||
|
||||
import { Button, Badge, IconGitHub } from '@supabase/ui'
|
||||
import { Button, Badge, IconStar } from '@supabase/ui'
|
||||
import FlyOut from '~/components/UI/FlyOut'
|
||||
import Transition from 'lib/Transition'
|
||||
|
||||
@@ -241,8 +241,8 @@ const Nav = (props: Props) => {
|
||||
</div>
|
||||
<div className="hidden lg:flex items-center sm:space-x-3">
|
||||
<a href="https://github.com/supabase/supabase" target="_blank">
|
||||
<Button type="default" icon={<IconGitHub />}>
|
||||
GitHub
|
||||
<Button type="default" icon={<IconStar />}>
|
||||
Star us on GitHub
|
||||
</Button>
|
||||
</a>
|
||||
<a href="https://app.supabase.io/api/login">
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"show": false,
|
||||
"text": "We have released the April recap!",
|
||||
"show": true,
|
||||
"text": "We're now on Discord!",
|
||||
"link": {
|
||||
"url": "https://supabase.io/blog/2021/05/03/supabase-beta-april-2021",
|
||||
"text": "Read more"
|
||||
"url": "http://discord.supabase.com",
|
||||
"text": "Join"
|
||||
}
|
||||
}
|
||||
@@ -29,12 +29,12 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"title": "Optimised database instances",
|
||||
"title": "Optimzed database instances",
|
||||
"tooltip": "Why? Unique workload requirements, heavy reads and writes, compliance",
|
||||
"tiers": {
|
||||
"free": false,
|
||||
"pro": false,
|
||||
"enterprise": true
|
||||
"enterprise": "Starting from $50/month"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -58,7 +58,7 @@ const { data, error } = await supabase
|
||||
const { data, error } = await supabase
|
||||
.storage
|
||||
.from('avatars')
|
||||
.move('pubic/space-cat.png', 'private/space-cat.png')
|
||||
.move('public/space-cat.png', 'private/space-cat.png')
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
"steve_chavez": {
|
||||
"author": "Steve Chavez",
|
||||
"author_url": "https://github.com/steve-chavez",
|
||||
"position": "Engineering",
|
||||
"position": "Engineering & PostgREST maintainer",
|
||||
"username": "steve-chavez",
|
||||
"author_image_url": "https://github.com/steve-chavez.png"
|
||||
}
|
||||
|
||||
@@ -166,14 +166,14 @@ function BlogPostPage(props: any) {
|
||||
images: [
|
||||
{
|
||||
url: `https://supabase.io${basePath}/images/blog/${
|
||||
props.blog.thumb ? props.blog.thumb : props.blog.image
|
||||
props.blog.image ? props.blog.image : props.blog.thumb
|
||||
}`,
|
||||
},
|
||||
],
|
||||
}}
|
||||
/>
|
||||
<DefaultLayout>
|
||||
<div className="bg-white dark:bg-dark-800 overflow-hidden py-12">
|
||||
<div className="bg-white dark:bg-dark-800 overflow-hidden mb-12">
|
||||
<div className="container px-8 sm:px-16 xl:px-20 lg:mt-16 mx-auto">
|
||||
<div className="max-w-6xl mx-auto">
|
||||
<div className="lg:py-12 grid grid-cols-12 lg:gap-16">
|
||||
|
||||
@@ -148,7 +148,7 @@ export default function IndexPage() {
|
||||
Pay as you go
|
||||
</h2>
|
||||
<p className="mt-4">
|
||||
<span className="text-4xl font-normal text-gray-900 dark:text-white">$75</span>
|
||||
<span className="text-4xl font-normal text-gray-900 dark:text-white">$25</span>
|
||||
<Typography.Text type="secondary">/project /month plus usage costs</Typography.Text>
|
||||
</p>
|
||||
<p className="my-4 text-sm text-gray-500">
|
||||
@@ -293,7 +293,7 @@ export default function IndexPage() {
|
||||
<div className="relative h-full table">
|
||||
<p>
|
||||
<span className="text-4xl font-normal text-gray-900 dark:text-white">
|
||||
$75
|
||||
$25
|
||||
</span>
|
||||
<Typography.Text> /project /month plus usage costs</Typography.Text>
|
||||
</p>
|
||||
@@ -393,6 +393,27 @@ export default function IndexPage() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bg-gray-50 dark:bg-gray-800 border-t dark:border-gray-600">
|
||||
<div className="container mx-auto px-6 lg:px-16 xl:px-20 relative py-16 sm:py-18 md:py-24 lg:py-24">
|
||||
<Typography.Title level={2}>Changelog</Typography.Title>
|
||||
|
||||
<div className="mt-4">
|
||||
<Typography.Title level={4}>28 July 2021</Typography.Title>
|
||||
<Typography className="w-full">
|
||||
<p>
|
||||
Clarified pricing on the "Optimzed database instances" to include the starting price
|
||||
of $50/month.
|
||||
</p>
|
||||
</Typography>
|
||||
</div>
|
||||
<div className="mt-4">
|
||||
<Typography.Title level={4}>29 March 2021</Typography.Title>
|
||||
<Typography>Released our Beta pricing.</Typography>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<CTABanner />
|
||||
</DefaultLayout>
|
||||
)
|
||||
|
||||
|
After Width: | Height: | Size: 128 KiB |
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 207 KiB |
|
After Width: | Height: | Size: 54 KiB |
|
After Width: | Height: | Size: 113 KiB |
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 41 KiB |
|
After Width: | Height: | Size: 112 KiB |
|
After Width: | Height: | Size: 78 KiB |
|
After Width: | Height: | Size: 75 KiB |
|
After Width: | Height: | Size: 88 KiB |
|
After Width: | Height: | Size: 213 KiB |
|
After Width: | Height: | Size: 176 KiB |
|
After Width: | Height: | Size: 197 KiB |
|
After Width: | Height: | Size: 175 KiB |
|
After Width: | Height: | Size: 104 KiB |
|
After Width: | Height: | Size: 63 KiB |
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 81 KiB |
|
After Width: | Height: | Size: 99 KiB |
|
After Width: | Height: | Size: 72 KiB |
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 324 KiB |
|
After Width: | Height: | Size: 157 KiB |
@@ -5,9 +5,41 @@
|
||||
<link>https://supabase.io</link>
|
||||
<description>Latest news from Supabase</description>
|
||||
<language>en</language>
|
||||
<lastBuildDate>Sun, 25 Jul 2021 16:00:00 GMT</lastBuildDate>
|
||||
<lastBuildDate>Mon, 26 Jul 2021 16:00:00 GMT</lastBuildDate>
|
||||
<atom:link href="https://supabase.io/blog/rss.xml" rel="self" type="application/rss+xml"/>
|
||||
|
||||
<item>
|
||||
<guid>https://supabase.io/blog/2021/07/27/storage-beta</guid>
|
||||
<title>Supabase Storage now in Beta</title>
|
||||
<link>https://supabase.io/blog/2021/07/27/storage-beta</link>
|
||||
<description>Supabase Storage moves into Beta.</description>
|
||||
<pubDate>Mon, 26 Jul 2021 16:00:00 GMT</pubDate>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<guid>https://supabase.io/blog/2021/07/27/spot-flutter-with-postgres</guid>
|
||||
<title>Spot: a video sharing app built with Flutter</title>
|
||||
<link>https://supabase.io/blog/2021/07/27/spot-flutter-with-postgres</link>
|
||||
<description>Spot is a geolocation-based video-sharing app with some social networking features.</description>
|
||||
<pubDate>Mon, 26 Jul 2021 16:00:00 GMT</pubDate>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<guid>https://supabase.io/blog/2021/07/26/supabase-postgres-13</guid>
|
||||
<title>Supabase is now on Postgres 13.3</title>
|
||||
<link>https://supabase.io/blog/2021/07/26/supabase-postgres-13</link>
|
||||
<description>From today, new Supabase projects will be on a version of Supabase Postgres that runs on Postgres 13.3.</description>
|
||||
<pubDate>Sun, 25 Jul 2021 16:00:00 GMT</pubDate>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<guid>https://supabase.io/blog/2021/07/26/supabase-community-day</guid>
|
||||
<title>Supabase Community Day</title>
|
||||
<link>https://supabase.io/blog/2021/07/26/supabase-community-day</link>
|
||||
<description>Community Day</description>
|
||||
<pubDate>Sun, 25 Jul 2021 16:00:00 GMT</pubDate>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<guid>https://supabase.io/blog/2021/07/26/epsilon3-self-hosting</guid>
|
||||
<title>Epsilon3 Self-Host Supabase To Revolutionize Space Operations </title>
|
||||
|
||||