Pull master and resolve conflicts

This commit is contained in:
Joshen Lim committed 2023-02-20 15:33:23 +08:00
commit 45263b0fab
410 files changed
+18480 -21101

No files matched your search

-92
View File
@@ -1,92 +0,0 @@
name: Tests
# Controls when the workflow will run
on:
schedule:
- cron: '0 4/6 * * *'
workflow_dispatch:
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
autotests:
name: Run tests and generate Allure Report
strategy:
matrix:
node: ['14']
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./tests
steps:
- uses: actions/checkout@v2
- name: Set up JDK
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Set up Node
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node }}
- name: Install dependencies
run: npm ci
- uses: supabase/setup-cli@v1
- run: supabase start
- name: Run Test
run: npm run test:local
env:
SUPABASE_DB_PORT: 54322
SUPABASE_DB_PASS: postgres
SUPABASE_DB_HOST: localhost
SUPABASE_GOTRUE: http://localhost:54321
SUPABASE_URL: http://localhost:54321
SUPABASE_KEY_ANON: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24ifQ.625_WdcF3KHqz5amU0x2X5WWHP-OEs_4qj0ssLNHzTs
SUPABASE_KEY_ADMIN: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSJ9.vI9obAHOGyVVKa3pD--kJlyxp-Z2zV9UUMAhKpNLAcU
- name: Stop infrastructure
if: always()
run: supabase stop
- name: Get Allure history
uses: actions/checkout@v2
if: always()
continue-on-error: true
with:
repository: supabase/test-reports
ref: gh-pages
path: gh-pages
- name: Allure Report action
uses: simple-elf/allure-report-action@master
if: always()
with:
github_repo: test-reports
allure_results: tests/allure-results
allure_history: allure-history
subfolder: supabase-integration
keep_reports: 50
- name: Deploy report to Github Pages
if: always()
uses: peaceiris/actions-gh-pages@v2
env:
EXTERNAL_REPOSITORY: supabase/test-reports
ACTIONS_DEPLOY_KEY: ${{ secrets.DEPLOY_TO_TEST_REPORTS_KEY }}
PUBLISH_BRANCH: gh-pages
PUBLISH_DIR: allure-history
- name: Post the link to the report
if: always()
uses: Sibz/github-status-action@v1
with:
authToken: ${{ secrets.GITHUB_TOKEN }}
context: 'Test report'
state: 'success'
sha: ${{ github.event.pull_request.head.sha || github.sha }}
target_url: https://supabase.github.io/test-reports/supabase-integration/${{ github.run_number }}
+28
View File
@@ -0,0 +1,28 @@
name: Deploy OG Images
on:
push:
branches:
- main
paths:
- 'supabase/functions/og-images'
workflow_dispatch:
jobs:
deploy:
runs-on: ubuntu-latest
env:
SUPABASE_ACCESS_TOKEN: ${{ secrets.SUPABASE_ACCESS_TOKEN }}
PROJECT_ID: ${{ secrets.PROJECT_ID }}
steps:
- name: Check out repo
- uses: actions/checkout@v3
- name: Setup the Supabase CLI
- uses: supabase/setup-cli@v1
with:
version: 1.0.0
- run: supabase functions deploy og-images --project-ref $PROJECT_ID
+18 -13
View File
@@ -11,14 +11,17 @@ jobs:
steps:
- name: Check out repo
uses: actions/checkout@v2
# disable this check while we migrate to monorepo
- name: Run prettier
uses: EPMatt/reviewdog-action-prettier@v1
with:
github_token: ${{ secrets.github_token }}
reporter: github-pr-review
level: warning
command: npx prettier -c 'apps/**/*.{js,jsx,ts,tsx,css,md,json}'
run: |-
npx prettier -c 'apps/**/*.{js,jsx,ts,tsx,css,md,json}'
# [Joshen] Temp disable the following due to an issue
# https://github.com/EPMatt/reviewdog-action-prettier/issues/34
# uses: EPMatt/reviewdog-action-prettier@v1
# with:
# github_token: ${{ secrets.github_token }}
# reporter: github-pr-review
# level: warning
# command: npx prettier -c 'apps/**/*.{js,jsx,ts,tsx,css,md,json}'
# run: |-
# function run_check() {
@@ -40,9 +43,11 @@ jobs:
- name: Check out repo
uses: actions/checkout@v2
- name: Run prettier
uses: EPMatt/reviewdog-action-prettier@v1
with:
github_token: ${{ secrets.github_token }}
reporter: github-pr-review
level: warning
command: npx prettier -c 'i18n/**/*.{js,jsx,ts,tsx,css,md,json}'
run: |-
npx prettier -c 'i18n/**/*.{js,jsx,ts,tsx,css,md,json}'
# uses: EPMatt/reviewdog-action-prettier@v1
# with:
# github_token: ${{ secrets.github_token }}
# reporter: github-pr-review
# level: warning
# command: npx prettier -c 'i18n/**/*.{js,jsx,ts,tsx,css,md,json}'
+1
View File
@@ -7,6 +7,7 @@ on:
- studio
paths:
- 'studio/**'
- 'package-lock.json'
jobs:
build:
runs-on: ubuntu-latest
+2
View File
@@ -8,10 +8,12 @@ on:
branches: [master]
paths:
- 'studio/**'
- 'package-lock.json'
pull_request:
branches: [master]
paths:
- 'studio/**'
- 'package-lock.json'
jobs:
build:
runs-on: ubuntu-latest
+2 -1
View File
@@ -4,6 +4,7 @@ node_modules
out
.docz
tmp
.swp
coverage
allure-results
@@ -119,4 +120,4 @@ typings/
**/supabase/.branches
**/supabase/.temp
apps/new-docs/*
apps/new-docs/*
+2 -2
View File
@@ -57,7 +57,7 @@ To contribute code to [Supabase](https://supabase.com), you must fork the [Supab
[Supabase](https://supabase.com) uses [Turborepo](https://turborepo.org/docs) to manage and run this monorepo.
1. Install the dependences in the root of the repo.
1. Install the dependencies in the root of the repo.
```sh
npm install # install dependencies
@@ -113,7 +113,7 @@ Following the changes to the [Supabase docs](https://supabase.com/blog/new-supab
- Inside of `apps/docs` create a `.env.local` file with the following: `NEXT_PUBLIC_NEW_DOCS=true`
Now when you run a local devlopment docs server you will see the new docs site.
Now when you run a local development docs server you will see the new docs site.
---
+2 -2
View File
@@ -1,6 +1,6 @@
<p align="center">
<img width="300" src="https://raw.githubusercontent.com/supabase/supabase/master/packages/common/assets/images/supabase-logo-wordmark--light.svg#gh-light-mode-only">
<img width="300" src="https://raw.githubusercontent.com/supabase/supabase/master/packages/common/assets/images/supabase-logo-wordmark--dark.svg#gh-dark-mode-only">
<img src="https://user-images.githubusercontent.com/8291514/213727234-cda046d6-28c6-491a-b284-b86c5cede25d.png#gh-light-mode-only">
<img src="https://user-images.githubusercontent.com/8291514/213727225-56186826-bee8-43b5-9b15-86e839d89393.png#gh-dark-mode-only">
</p>
---
-3
View File
@@ -1,3 +0,0 @@
node_modules
build
.docusaurus
-10
View File
@@ -1,10 +0,0 @@
# Supabase Docs
### Contributing to the specs
- `cd /web/spec/`
- run `make` which will pull the latest TSDoc with your updates
- add your comments to `supabase.yml` | `postgrest.yml` | `gotrue.yml` | `realtime.yml`
- run `npm run gen:supabase` inside the `/spec` folder which will generate the Docusaurus pages
- run `npm run build` to make sure the build is working
- submit your PR
-7
View File
@@ -1,7 +0,0 @@
---
id: careers
title: Work at Supabase
description: We're hiring. Start your career at Supabase.
---
[Browse open roles](https://boards.greenhouse.io/supabase).
-3
View File
@@ -1,3 +0,0 @@
Supabase is an open source Firebase alternative. We're backed by Y Combinator, Mozilla, Coatue, and a bunch of [amazing developers](https://supabase.com/blog/angels-of-supabase).
Supabase is a platform which makes it incredibly easy to build _and_ scale your projects.
-1
View File
@@ -1 +0,0 @@
Apply for this role using our [online form](https://boards.greenhouse.io/supabase).
@@ -1,3 +0,0 @@
:::note
We're currently on a Hiring Freeze and only open to very specific roles. You're still welcome to apply, but we might take a while to respond!
:::
-11
View File
@@ -1,11 +0,0 @@
- We hire in batches, but accept applications on a rolling basis, so now is always a good time to apply :)
- The entire process is fully remote and all communication will happen over email or via video chat.
- Once you've submitted your application, the team will review your submission, and may reach out for a short screening interview over video call.
- If you pass the screen you will be invited to up to four follow up interviews. The calls:
- usually take between 20-45 minutes each depending on the interviewer
- are all 1:1
- will be with both founders, a member of either the growth or engineering team (depending on the role), and usually one other person from your immediate team or function.
- Once the interviews are over, the team will meet to discuss several roles and candidates and may:
- ask one or two follow-up questions over email or a quick call
- go directly to making an offer
-91
View File
@@ -1,91 +0,0 @@
<a className="card" href="/careers/founders" style={{marginBottom: 10}}>
<div className="card__body">
<h3>Ex-Founders</h3>
<p>Create your own role.</p>
</div>
</a>
<a className="card" href="/careers/data-engineers" style={{marginBottom: 10}}>
<div className="card__body">
<h3>Data Engineers</h3>
<p>Develop insights with the Growth Team.</p>
</div>
</a>
<a className="card" href="/careers/growth-marketer" style={{marginBottom: 10}}>
<div className="card__body">
<h3>Growth Marketer</h3>
<p>Get our tools in front of the next billion developers.</p>
</div>
</a>
<a className="card" href="/careers/auth-engineers" style={{marginBottom: 10}}>
<div className="card__body">
<h3>Auth Engineers</h3>
<p>Develop and Maintain our Auth Products.</p>
</div>
</a>
<a className="card" href="/careers/postgres-experts" style={{marginBottom: 10}}>
<div className="card__body">
<h3>Postgres Experts</h3>
<p>Go deep on Postgres internals and extensions.</p>
</div>
</a>
<a className="card" href="/careers/technical-writers" style={{marginBottom: 10}}>
<div className="card__body">
<h3>Technical Writers</h3>
<p>Take the lead on our internal and external written communications</p>
</div>
</a>
<a className="card" href="/careers/sre" style={{marginBottom: 10}}>
<div className="card__body">
<h3>Cloud Platform Engineers and SRE's</h3>
<p>Build our cloud platform.</p>
</div>
</a>
<a className="card" href="/careers/developer-advocate" style={{marginBottom: 10}}>
<div className="card__body">
<h3>Developer Advocate</h3>
<p>Get more developers interested in Postgres and Supabase.</p>
</div>
</a>
<a className="card" href="/careers/support-and-qa" style={{marginBottom: 10}}>
<div className="card__body">
<h3>Support Engineers</h3>
<p>Build internal tooling, automated tests, and support processes.</p>
</div>
</a>
<a className="card" href="/careers/full-stack-developers" style={{marginBottom: 10}}>
<div className="card__body">
<h3>Full-stack Engineers</h3>
<p>Build our Dashboard, tools, tests, and infra.</p>
</div>
</a>
<a className="card" href="/careers/graphic-web-designers" style={{marginBottom: 10}}>
<div className="card__body">
<h3>Graphic / Web Designers</h3>
<p>Build our brand and visual communication.</p>
</div>
</a>
<a className="card" href="/careers/front-end-developers" style={{marginBottom: 10}}>
<div className="card__body">
<h3>Front End Developers</h3>
<p>Build our Dashboard, tools, tests, and client libraries.</p>
</div>
</a>
<a className="card" href="/careers/technical-recruiter" style={{marginBottom: 10}}>
<div className="card__body">
<h3>Technical recruiter</h3>
<p>Take the lead on our technical recruitment.</p>
</div>
</a>
-9
View File
@@ -1,9 +0,0 @@
- 100% remote. Work anywhere in the world. No location-based adjustment to your salary.
- Autonomous work. We work collaboratively on projects, but you set your own pace.
- We're a startup. It's unstructured.
- Collectively founded more than a dozen venture-backed companies.
- More than 10 different nationalities.
- We deeply believe in the efficacy of collaborative open source. We support existing communities and tools, rather than building "yet another xx".
- We "dogfood" everything. If you use it in your project, we use it in Supabase.
-43
View File
@@ -1,43 +0,0 @@
---
id: careers-auth-engineers
slug: auth-engineers
title: Auth Engineers.
description: Supabase is hiring Auth Engineers
---
import Roles from '@site/docs/careers/_snippets/roles.mdx'
import About from '@site/docs/careers/_snippets/about.mdx'
import Team from '@site/docs/careers/_snippets/team.mdx'
import Apply from '@site/docs/careers/_snippets/apply.mdx'
import Process from '@site/docs/careers/_snippets/process.mdx'
## About the role
- [Auth](https://supabase.com/auth) is one of the most popular products in the Supabase stack
- Be a Maintainer of our Open Source Auth repos written in [golang](https://github.com/supabase/gotrue) and [typescript](https://github.com/supabase/gotrue-js)
- Be a key decision maker in the Supabase Auth team
- Expand our auth offering and work with our users to prioritize the product roadmap
- Previous working experience of Authorization and Authentication is a must
- Experience working with OAuth, SSO, SAML etc.
- Advise our users on how best to make use of Gotrue and Postgres RLS policies
- Help grow the Auth team
## About Supabase
<About />{' '}
## About the team
<Team />{' '}
## Apply
<Apply />{' '}
## Process
<Process />{' '}
## All roles
<Roles />{' '}
-48
View File
@@ -1,48 +0,0 @@
---
id: careers-data-engineers
slug: data-engineers
title: Data Engineers.
description: Supabase is hiring Data Engineers
---
import Roles from '@site/docs/careers/_snippets/roles.mdx'
import About from '@site/docs/careers/_snippets/about.mdx'
import Team from '@site/docs/careers/_snippets/team.mdx'
import Apply from '@site/docs/careers/_snippets/apply.mdx'
import Process from '@site/docs/careers/_snippets/process.mdx'
## About the role
- Be the business intelligence star player at Supabase by helping dig deep into the data we are generating. Deep knowledge of SQL and relevant tooling is a must.
- Help customer success & sales team by working to identify and monitor:
- Usage Insights
- Find and segment cohorts based around account level data, behavior, traffic sources, and measure their subsequent behaviors
- Find and monitor product qualified leads based around account and behavior characteristics
- Customer health segmentation into actionable cohorts (e.g. healthy, churn, at risk)
- Help identify opportunities high touch, low touch, & tech touch customer success & sales approaches
- Help sales & customer success identify opportunity for unscheduled outreach
- Working with internal tooling team to identify and implement solutions for growth, sales, customer success teams needs
- Help customer success team with data to prepare for client quarterly business reviews
- Help team put human and automated procedures in place based around data insights
- Monitoring and measurement of feature usage - maintaining any data pipelines or queries as we continue to update and add features
- Assisting with setup and measurement of growth experiments
## About Supabase
<About />{' '}
## About the team
<Team />{' '}
## Apply
<Apply />{' '}
## Process
<Process />{' '}
## All roles
<Roles />{' '}
-66
View File
@@ -1,66 +0,0 @@
---
id: careers-developer-advocate
slug: developer-advocate
title: Developer Advocate (US Timezone).
description: Supabase is hiring Developer Advocates and Community Managers
---
import Roles from '@site/docs/careers/_snippets/roles.mdx'
import About from '@site/docs/careers/_snippets/about.mdx'
import Team from '@site/docs/careers/_snippets/team.mdx'
import Apply from '@site/docs/careers/_snippets/apply.mdx'
import Process from '@site/docs/careers/_snippets/process.mdx'
## About the role
Supabase is looking for a Developer Advocate in US timezone. Supabase is a fully remote company and this is a remote role, that being said, we have some specific timezone and location coverage needs, so candidates who can operate in US timezone and can easily reach events within the US will be preferred.
## Responsibilities
- Attend conferences, meetups, and other events in person and in US (time).
- Develop and deliver engaging talks and educational materials.
- Write articles and create video tutorials
- Represent Supabase online via social media (Twitter, TikTok) and live coding streaming on a regular schedule.
- Work with the rest of the team, and the marketing team to develop swag and memes.
- Build examples using Supabase and other frameworks.
- Improve our documentation.
- Aid in the development of our client libraries.
- Respond to GitHub Issues and Discussions.
- Aid in developing the SupaSquad community program
For the right candidate, additional responsibilities may include:
- Working with the Founders to construct and execute on a hiring plan to grow the Developer Relations team.
## Required skills
- 3+ Years Experience as a Software Engineer.
- Fluent in spoken and written English.
- Familiar with popular JavaScript frameworks (React, Vue, Svelte, Node.js)
- Experience working with GitHub source code management, and CI/CD tools.
## Nice to have
- Prior DevRel experience not required but need to show some background and desire for the outlined responsibilities.
- Fluency in another spoken language.
- Familiar with Postgres, Golang, or mobile app development is a plus.
## About Supabase
<About />{' '}
## About the team
<Team />{' '}
## Apply
<Apply />{' '}
## Process
<Process />{' '}
## All roles
<Roles />{' '}
-58
View File
@@ -1,58 +0,0 @@
---
id: careers-developer-success
slug: developer-success
title: Developer Success Engineer
description: Supabase is hiring Developer Success Engineers
---
import Roles from '@site/docs/careers/_snippets/roles.mdx'
import About from '@site/docs/careers/_snippets/about.mdx'
import Team from '@site/docs/careers/_snippets/team.mdx'
import Apply from '@site/docs/careers/_snippets/apply.mdx'
import Process from '@site/docs/careers/_snippets/process.mdx'
## About the role
Supabase is hiring Developer Success Engineers. Help us build the easiest database platform in the world.
### Responsibilities
- Focused on unblocking developers, backlog of issues.
- Priority focus on Enterprise customers.
- Help high-value customers with implementation and monitoring.
- Build internal tools for support team.
- Produce tests and documentation to mitigate recurring support tickets.
- Triage/clean/close issues on any of our repos.
- Work with the community on all of our channels: GitHub, Discord, and Email.
## About you
- 2+ years experience in engineering or a highly technical support role.
- You must love remote work.
- You possess exceptional communication skills.
- Availability to work within a weekend and on-call rota.
## Bonus if you:
- Are a Polyglot developer, with some skill in Node.js/JavaScript.
- Have PostgreSQL experience.
## About Supabase
<About />{' '}
## About the team
<Team />{' '}
## Apply
<Apply />{' '}
## Process
<Process />{' '}
## All roles
<Roles />{' '}
-40
View File
@@ -1,40 +0,0 @@
---
id: careers-founders
slug: founders
title: Ex-Founders.
description: Supabase is hiring ex-Founders
---
import Roles from '@site/docs/careers/_snippets/roles.mdx'
import About from '@site/docs/careers/_snippets/about.mdx'
import Team from '@site/docs/careers/_snippets/team.mdx'
import Apply from '@site/docs/careers/_snippets/apply.mdx'
import Process from '@site/docs/careers/_snippets/process.mdx'
## About the role
The Supabase team is a group of founders who previously scaled businesses to millions in revenue, hundreds of employees, and worked in a multitude of industries:
fintech, healthcare & medtech, crypto, insurance, agritech, marketplaces, and of course - open source dev tools.
We recognize the value of the founder mindset.
If you're a founder and you're looking for an opportunity to work with other founders, tell us how you can help Supabase succeed and we'll give you the resources to make it happen.
## About Supabase
<About />{' '}
## About the team
<Team />{' '}
## Apply
<Apply />{' '}
## Process
<Process />{' '}
## All roles
<Roles />{' '}
@@ -1,83 +0,0 @@
---
id: careers-front-end
slug: front-end-developers
title: Front End Developers
description: Supabase is hiring Front End Developers
---
import Roles from '@site/docs/careers/_snippets/roles.mdx'
import About from '@site/docs/careers/_snippets/about.mdx'
import Team from '@site/docs/careers/_snippets/team.mdx'
import Apply from '@site/docs/careers/_snippets/apply.mdx'
import Process from '@site/docs/careers/_snippets/process.mdx'
## About the role
We're looking for a Senior Front End Developer to join our team to help change the way developers build their applications.
You'll be primarily responsible for growing our NextJS app to a comprehensive development stack, including our backend API, user authentication and expanding our React UI.
You'll be an indispensable part of team, by working very closely with our front end team, designers, founders and backend engineers; you'll be directly contributing to technical choices, building a team culture and co authoring internal processes for a growing team. We want to expand our development team rapidly throughout 2022 and want you to be at the centre of growing and nurturing this talent.
This is an opportunity to truly take ownership of a web platform, defining how it evolves, and how we can can scale our users, team, product and processes.
## What we need
You will have a background of working and leading developers, building trust across a team and continually evolving and improving standards and processes.
You are a strong web developer, having worked with front end JS frameworks in production, ideally at high user scale, and for user facing applications.
You care about attention to detail, the quality and robustness of code you write, but also about collaborating with others. Reviewing fairly and honestly other team member's work and helping them become the best they can be.
You've worked in multi disciplinary teams before, working with designers, developers, marketeers, customer support and sales staff. You communicate problems at high level and can effectively convey your assumptions, issues and progress to others well and honestly.
## Responsibilities
- Build our dashboard, iterating existing features and building great new features.
- Take ownership of the dashboard front end stack, planning and iterating on it based on a roadmap that you have an active voice in moulding.
- Build tools within the Supabase ecosystem, occasionally dog fooding our own work.
- Interact with the wider developer community with blog posts, social media, discord; speaking at events and interacting with customers on a daily basis.
- Build out the test suite for the Dashboard.
- Improve the speed and code quality of our Dashboard.
## Must have skills
- 5+ years experience in web development (JavaScript, HTML5, CSS3, SCSS/LESS).
- Have an understanding of modern JS (ES6 etc).
- Experience with Node.
- Experience with React (We use NextJS everywhere).
- Experience with state management (Mobx, Redux etc).
- Experience of any kind of React UI Components.
- Willingness to work in an agile environment.
- Willingness to evolve and shape the development tools/stack.
- Willing to train and mentor junior developers.
- Fluent in the English language.
## Nice to have skills
- Opinions and ideas on how to align teams up to work really effectively.
- Experience working on large projects, and the code and contribution complexities that come with it.
- Has used tailwind.
- Web accessibility experience.
- Experience with PostgreSQL.
- Experience with design software (Figma, Sketch).
## About Supabase
<About />{' '}
## About the team
<Team />{' '}
## Apply
<Apply />{' '}
## Process
<Process />{' '}
## All roles
<Roles />{' '}
-53
View File
@@ -1,53 +0,0 @@
---
id: careers-full-stack
slug: full-stack-developers
title: Full Stack Developers.
description: Supabase is hiring Full Stack Developers
---
import Roles from '@site/docs/careers/_snippets/roles.mdx'
import About from '@site/docs/careers/_snippets/about.mdx'
import Team from '@site/docs/careers/_snippets/team.mdx'
import Apply from '@site/docs/careers/_snippets/apply.mdx'
import Process from '@site/docs/careers/_snippets/process.mdx'
## About the role
Supabase is hiring Full Stack Developers.
### Responsibilities
- Build our Dashboard.
- Build tools within the Supabase ecosystem.
- Build example applications.
- Write blog posts.
- Respond to GitHub Discussions.
- Write tests.
### Preferred skills
- Typescript
- Elixir/Erlang
- Go Lang
- React / HTML / CSS / Next.js
- Tailwind
## About Supabase
<About />{' '}
## About the team
<Team />{' '}
## Apply
<Apply />{' '}
## Process
<Process />{' '}
## All roles
<Roles />{' '}
@@ -1,82 +0,0 @@
---
id: careers-graphic-web-designer
slug: graphic-web-designers
title: Graphic / Web Designers
description: Supabase is hiring Designers
---
import Roles from '@site/docs/careers/_snippets/roles.mdx'
import About from '@site/docs/careers/_snippets/about.mdx'
import Team from '@site/docs/careers/_snippets/team.mdx'
import Apply from '@site/docs/careers/_snippets/apply.mdx'
import Process from '@site/docs/careers/_snippets/process.mdx'
## About the role
We're looking for Graphic / Web Designers to join our team to help change the way developers build their applications.
You'll be primarily responsible for growing our marketing and brand collateral across the entire Supabase ecosystem.
You'll be an indispensable part of team, by working very closely with our sales, marketing, front end team, founders and backend engineers; you'll be directly contributing to brand decisions, building a team culture and co authoring internal processes for a growing team. We want to expand our marketing efforts rapidly throughout 2022 and want you to be at the centre of growing and nurturing our brand, while also nurturing new talent that come on board.
This is an opportunity to truly take ownership of a fast growing developer tools outward facing visual communication, defining how it evolves, and how we can can scale it with our new products and new types of users.
## What we need
You will have a background of working with developers, building trust across a team and continually evolving and improving standards and processes.
You are a strong designer, with an extreme attention to detail. You are someone who strives to make visual communication the best it can be where others would give up.
You care about the quality and robustness of the designs you create while also collaborating with others in a healthy way. Reviewing fairly and honestly other team member's work and helping them become the best they can be.
You've worked in multi disciplinary teams before, working with other designers, developers, marketeers, customer support and sales staff. You communicate problems at high level and can effectively convey your assumptions, issues and progress to others well and honestly.
## Responsibilities
- Maintain a design library for Supabase brand, covering web assets, social media, video assets, icons.
- Help grow and maintain a shared library in Figma for UI components
- Design and maintain document templates / presentation templates, while also working with the sales/growth team to realize the best format for co-collaboration.
- Work with the design and front end team to improve our visual language, create brand guidelines and help maintain a consistent supabase visual voice across all our mediums.
- Deliver clear and well annotated mockups for marketing websites, documentation websites, blog posts and web applications
- Make the best Swag in the world
## Must have skills
- You can make what is complicated visually simple and easy to understand.
- You can jump between departments easily and communicate clearly so that the best solutions can be realised
- Understands how to design for power tools (dashboards - denser, contextual elements appear when needed, multiple states of visual information), vs marketing (landing pages - spacious, eye pleasing, sales driven, all elements visible)
- You are familiar with all modern design software, from figma/sketch to adobe suite
- You can deliver quickly, even in situations were there is little time for preparing.
## Experience
- At least 3 years professional experience as a Designer, working freelance/agency. Preferably with experience in a start up environment, Developer tool / SASS product.
- Fluent in English language.
- Willingness to work in an agile environment
## Nice to have skills
- Prior knowledge of databases (postgres)
- You are also an engineer, (ie, You can build what you design)
- Interest in training and mentoring others
- web skills, such as HTML, JS, CSS, React, NextJS etc
## About Supabase
<About />{' '}
## About the team
<Team />{' '}
## Apply
<Apply />{' '}
## Process
<Process />{' '}
## All roles
<Roles />{' '}
-67
View File
@@ -1,67 +0,0 @@
---
id: careers-growth-marketer
slug: growth-marketer
title: Growth Marketer.
description: Supabase is hiring a Growth Marketer
---
import Roles from '@site/docs/careers/_snippets/roles.mdx'
import About from '@site/docs/careers/_snippets/about.mdx'
import Team from '@site/docs/careers/_snippets/team.mdx'
import Apply from '@site/docs/careers/_snippets/apply.mdx'
import Process from '@site/docs/careers/_snippets/process.mdx'
## About the role
Supabase is looking for a growth marketer to help continue to raise awareness of Supabase within the developer community. This role will require working across the entire customer lifecycle helping shape programs that drive awareness, activation, engagement, and expansion. In this role you will play a key role in establishing and operating the marketing and growth strategies for supabase by working cross-functionally with our engineering and growth teams to ensure we have the best possible marketing strategy and execution.
The ideal candidate has experience helping grow products which enable developers. You should be both strategic and highly execution focussed.
**Some of the things you will be doing:**
- Planning and executing the Supabase marketing strategy
- Designing and executing on industry specific marketing campaigns
- Help promote and amplify all things Supabase: events, hackathons, our DevRel team profiles, launch week
- Outbound to co-ordinate and schedule events & conferences that we can participate in
- Outbound to find channels for content distribution (written, video, podcasts, interviews etc)
- Outbound to find partnership opportunities with code schools & 3rd parties for content co-creation
- Understand whats driving our user acquisition funnel and assets required to increase activation
- Monitor and measure our entire portfolio of assets and communicating the results of our marketing efforts internally so we understand what is most effective
- Create enterprise grade marketing materials that we can start to distribute from our own website and across other channels such as LinkedIn and DZone
- Find interesting case study opportunities and help turn them into content we can distribute across different segments
- Liaise and work with our incredible DevRel team to help them identify opportunities and amplify their efforts
- work with our amazing team of community writers to help find topics to write about
- Scope out and action our SEO strategy
- Help running email campaigns
- Community management
## Skills and Experience
- Building marketing funnels and running outbound campaigns
- Creating and managing social media campaigns
- Marketing to software developers & developer tooling space
- Marketing collateral aimed at enterprise and cloud native customers
- Metrics driven & an experimental mindset
- Marketing automation and CRM tools
- Experience with analytics platforms
- SEO experience
## About Supabase
<About />{' '}
## About the team
<Team />{' '}
## Apply
<Apply />{' '}
## Process
<Process />{' '}
## All roles
<Roles />{' '}
-44
View File
@@ -1,44 +0,0 @@
---
id: careers-postgres-experts
slug: postgres-experts
title: Postgres Experts.
description: Supabase is hiring Postgres Experts
---
import Roles from '@site/docs/careers/_snippets/roles.mdx'
import About from '@site/docs/careers/_snippets/about.mdx'
import Team from '@site/docs/careers/_snippets/team.mdx'
import Apply from '@site/docs/careers/_snippets/apply.mdx'
import Process from '@site/docs/careers/_snippets/process.mdx'
## About the role
Supabase is hiring Postgres Experts.
### Responsibilities
- Contribute to the Postgres Core.
- Work on Postgres open source tooling.
- Help engineer Postgres Reliability and observability into our cloud platform.
- Develop multi-tenant solutions for thousands of databases.
- Debug database issues and provide customer support if required.
## About Supabase
<About />{' '}
## About the team
<Team />{' '}
## Apply
<Apply />{' '}
## Process
<Process />{' '}
## All roles
<Roles />{' '}
-46
View File
@@ -1,46 +0,0 @@
---
id: careers-sre
slug: sre
title: Cloud Platform Engineers and SREs.
description: Supabase is hiring Cloud Platform Engineers and SREs
---
import Roles from '@site/docs/careers/_snippets/roles.mdx'
import About from '@site/docs/careers/_snippets/about.mdx'
import Team from '@site/docs/careers/_snippets/team.mdx'
import Apply from '@site/docs/careers/_snippets/apply.mdx'
import Process from '@site/docs/careers/_snippets/process.mdx'
## About the role
Supabase is hiring Cloud Platform Engineers and Site Reliability Engineers.
### Responsibilities
- Help build the Supabase Cloud offering.
- Improve our system architecture to reduce costs while balancing security and performance.
- Work on designing and tracking metrics for platform uptime.
- Increase observability into our system by capturing relevant metrics and logs.
- Implement and maintain intrusion detection, automated remediation and patch management systems.
- Design CI/CD systems to speed up deploys with proper change and release management processes.
- Work on our SOC2 and GDPR compliance initiatives.
## About Supabase
<About />{' '}
## About the team
<Team />{' '}
## Apply
<Apply />{' '}
## Process
<Process />{' '}
## All roles
<Roles />{' '}
-70
View File
@@ -1,70 +0,0 @@
---
id: careers-support
slug: support-and-qa
title: Support Engineers.
description: Supabase is hiring Support Engineers
---
import Roles from '@site/docs/careers/_snippets/roles.mdx'
import About from '@site/docs/careers/_snippets/about.mdx'
import Team from '@site/docs/careers/_snippets/team.mdx'
import Apply from '@site/docs/careers/_snippets/apply.mdx'
import Process from '@site/docs/careers/_snippets/process.mdx'
## About the role
Supabase is hiring Developer Support Engineers.
### Responsibilities
- Providing initial responses to all support cases.
- Triaging support cases. Including directing users to previous answers, code examples, documentation, or escalating to specific technical or business team members.
- Monitoring GitHub issues, discussions, twitter, email, and other feedback channels.
- Creating test cases and improving test coverage, if you have experience with testing.
For the right candidate, additional responsibilities may include:
- Establishing a workflow to reduce 'time to response' and 'time to fix' that can scale to multiple team members.
- Identifying where internal tooling might be developed or obtained to improve support efficiency.
- Establishing key support metrics and identifying how best to measure them.
- Working with the Founders to construct and execute on a hiring plan to grow the support team.
### Requirements
- 1+ year tech experience.
- Familiar with popular JavaScript frameworks (React, Vue, Svelte) and Node.js.
- Experience working with GitHub source code management, and CI/CD tools.
## Nice to have
- Experience writing tests
- Familiar with Postgres and Golang is a plus.
## Timezones
- We're looking for global coverage, in particular the US, European and APAC timezone.
## Four day work week
This role is optionally a four-day workweek if you are interested in working from Friday to Monday. We can also discuss a shorter (pro-rated) week.
In particular we would like to hire people who would be willing to work on weekends (or at least one of the days (Saturday or Sunday).
## About Supabase
<About />{' '}
## About the team
<Team />{' '}
## Apply
<Apply />{' '}
## Process
<Process />{' '}
## All roles
<Roles />{' '}
@@ -1,59 +0,0 @@
---
id: careers-technical-recruiter
slug: technical-recruiter
title: Technical Recruiter
description: Supabase is hiring Technical Recruiters
---
import Roles from '@site/docs/careers/_snippets/roles.mdx'
import About from '@site/docs/careers/_snippets/about.mdx'
import Team from '@site/docs/careers/_snippets/team.mdx'
import Apply from '@site/docs/careers/_snippets/apply.mdx'
import Process from '@site/docs/careers/_snippets/process.mdx'
## About the role
#### Key Responsibilities:
- Be accountable for implementing inclusive recruiting practices and finding ways to engage more under-represented talent for technical roles
- Ability to understand and communicate the business' current technical challenges to entice candidates who are driven by solving interesting problems
- Accountable to starting a candidate search project from scratch through requirement gathering, job posting, sourcing, networking, previous applicants follow-ups etc
#### Requirements:
- Minimum 2+ years technical recruiting experience across the full hiring process from sourcing to the offer stage
- Technical knowledge of different coding languages/technical stacks/terminology
- You have expertise in filling Engineering, Infrastructure, Data Science, and other technical roles.
- Self motivated Technical Recruiter that enjoys working in a fun, fast paced environment!
- A solid understanding of what makes a great candidate experience
- You enjoy reaching out to others and learning what drives them in their career
- You are not afraid to own all parts of an operation in a remote setting
- Ability to communicate effectively and effortlessly with candidates and internal stakeholders of all career levels
- Excellent interpersonal skills, resourcefulness, and follow-up
#### Candidate Nice to Haves
- A continuous improvement mindset with an iterative approach to making things better. Whether it's your interview technique, pipeline optimization or anything else that you discover.
- Fluency with Greenhouse or other Applicant Tracking Systems, as well as various sourcing platforms (e.g., LinkedIn, GitHub, Work at a Startup, etc)
- You're Comfortable coordinating all candidate touch points
- You can plan out batch days & other projects to drive excellence for our candidate experience and quality of interviews
## About Supabase
<About />{' '}
## About the team
<Team />{' '}
## Apply
<Apply />{' '}
## Process
<Process />{' '}
## All roles
<Roles />{' '}
-62
View File
@@ -1,62 +0,0 @@
---
id: careers-technical-writers
slug: technical-writers
title: Technical Writers.
description: Supabase is hiring Technical Writers
---
import Roles from '@site/docs/careers/_snippets/roles.mdx'
import About from '@site/docs/careers/_snippets/about.mdx'
import Team from '@site/docs/careers/_snippets/team.mdx'
import Apply from '@site/docs/careers/_snippets/apply.mdx'
import Process from '@site/docs/careers/_snippets/process.mdx'
## About the role
Do you know what amazing documentation looks like?
Do you have experience building for the web?
Are you an engaging writer with an eye for detail?
Responsibilities includes:
- Blog posts for the Supabase website
- Helping other team members communicate their wins with edits and suggestions
- Writing internal docs such as: documenting processes, how-to guides etc.
- Writing and Organizing our documentation, and generally setting the direction on how they are structured
- Helping with enterprise orientated marketing collateral: thought leadership, white papers, case studies
- Working directly with the Founders, Growth, and Dev Rel teams on strategy
Must Have:
- Intermediate understanding of Postgres
- Full stack development experience
- Fluent in English
- Track record of producing content for a developer audience
- Enjoys working online remotely with minimal supervision
Nice to Have:
- Understanding of SEO
- Previous experience with SaaS content marketing
## About Supabase
<About />{' '}
## About the team
<Team />{' '}
## Apply
<Apply />{' '}
## Process
<Process />{' '}
## All roles
<Roles />{' '}
-10
View File
@@ -1,10 +0,0 @@
---
id: handbook
title: Handbook
description: 'What is the Supabase Handbook?'
slug: /handbook
---
## What is this?
This is the internal Supabase guide. It is a work in progress.
-25
View File
@@ -1,25 +0,0 @@
---
id: contributing
title: Contributing
description: Want to help?
---
## How to contribute
Supabase has many [open source repos](https://github.com/orgs/supabase/repositories). Some of the more popular ones are:
- [Supabase](https://github.com/supabase/supabase) - Our Dashboard, Websites, and example apps
- [Supabase-js](https://github.com/supabase/supabase-js) - A clientside library written in Typescript
- [Gotrue](https://github.com/supabase/gotrue) - Our auth server, written in Go
- [Realtime](https://github.com/supabase/realtime) - A server for streaming changes from Postgres, written in Elixir
- [browse all](https://github.com/orgs/supabase/repositories)
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 to one of our [repos](https://github.com/orgs/supabase/repositories)
- Report a performance issue or a part of the documentation that you find confusing.
- Create a pull request in one of our [repos](https://github.com/orgs/supabase/repositories)
- [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.
-89
View File
@@ -1,89 +0,0 @@
---
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.
![Supabase SupaSquad](/img/supabase-squad.png)
## Requirements
As a member of the Squad, you choose the approach where you'll provide the most value.
You can help in one of five ways:
### Maintainer
Help maintain Supabase repositories. This includes building client libraries, managing issues, and fixing bugs.
### Expert
Answer user questions on GitHub [Discussions](https://github.com/supabase/supabase/discussions), [Discord](https://discord.supabase.com), 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](https://discord.supabase.com), [Reddit](https://reddit.com/r/Supabase/),
[StackOverflow](https://stackoverflow.com/questions/tagged/supabase) etc.
## Benefits for SupaSquad members
- Access to a Supabase Discord channel providing direct communication with the team, Discord badges, and elevated privileges.
- Special AMA sessions with members of the Supabase team.
- Monthly DevRel committee call with industry-leading Developer Advocates (many of whom are [angel investors](https://supabase.com/blog/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.
- 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.
- 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>
-239
View File
@@ -1,239 +0,0 @@
module.exports = {
title: 'Supabase',
tagline: 'Build in a weekend. Scale to millions.',
url: 'https://supabase.com',
baseUrl: '/',
favicon: '/favicon.ico',
organizationName: 'supabase', // Usually your GitHub org/user name.
projectName: 'supabase', // Usually your repo name.
themeConfig: {
forceDarkMode: true,
darkMode: true,
colorMode: {
// "light" | "dark"
defaultMode: 'dark',
// Hides the switch in the navbar
// Useful if you want to support a single color mode
disableSwitch: false,
// Should we use the prefers-color-scheme media-query,
// using user system preferences, instead of the hardcoded defaultMode
respectPrefersColorScheme: false,
// Dark/light switch icon options
switchConfig: {
// Icon for the switch while in dark mode
darkIcon: ' ',
darkIconStyle: {
marginTop: '1px',
},
lightIcon: ' ',
lightIconStyle: {
marginTop: '1px',
},
},
},
sidebarCollapsible: true,
algolia: {
apiKey: '766d56f13dd1e82f43253559b7c86636',
indexName: 'supabase',
},
image: '/img/supabase-og-image.png', // used for meta tag, in particular og:image and twitter:image
metaImage: '/img/supabase-og-image.png',
navbar: {
// classNames: 'shadow--md',
// title: 'supabase',
hideOnScroll: true,
logo: {
alt: 'Supabase',
src: '/supabase-light.svg',
srcDark: '/supabase-dark.svg',
},
items: [
{
href: 'https://github.com/supabase/supabase',
className: 'navbar-item-github',
position: 'right',
},
{
href: 'https://twitter.com/supabase',
className: 'navbar-item-twitter',
position: 'right',
},
{
label: 'Careers',
to: 'https://boards.greenhouse.io/supabase',
activeBasePath: '/careers',
position: 'left',
},
{
label: 'Handbook',
to: '/handbook',
activeBaseRegex: '/handbook',
position: 'left',
},
],
},
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'),
},
footer: {
links: [
{
title: 'Company',
items: [
{
label: 'Blog',
to: 'https://supabase.com/blog',
},
{
label: 'Humans.txt',
to: 'https://supabase.com/humans.txt',
},
{
label: 'Lawyers.txt',
to: 'https://supabase.com/lawyers.txt',
},
],
},
{
title: 'Team',
items: [
{
label: 'Handbook',
href: '/handbook',
},
],
},
{
title: 'Community',
items: [
{
label: 'GitHub',
href: 'https://github.com/supabase/supabase',
},
{
label: 'Twitter',
href: 'https://twitter.com/supabase',
},
{
label: 'DevTo',
href: 'https://dev.to/supabase',
},
{
label: 'Discord',
href: 'https://discord.supabase.com',
},
{
label: 'RSS',
href: 'https://supabase.com/rss.xml',
},
],
},
{
title: 'Resources',
items: [
{
label: 'Brand Assets',
to: 'https://supabase.com/brand-assets',
},
],
},
],
copyright: `Copyright © ${new Date().getFullYear()} Supabase.`,
},
},
presets: [
[
'@docusaurus/preset-classic',
{
docs: {
sidebarPath: require.resolve('./sidebars.js'),
routeBasePath: '/',
},
theme: {
customCss: require.resolve('./src/css/custom.css'),
},
blog: false,
},
],
],
plugins: [
// [
// '@docusaurus/plugin-content-docs',
// {
// id: 'supabase-client', // for first plugin-content-docs with "resources/" path
// // homePageId: "doc2",
// path: './ref/supabase', // Path to data on filesystem, relative to site dir.
// routeBasePath: 'ref/supabase', // URL Route.
// include: ['**/*.md', '**/*.mdx'],
// sidebarPath: require.resolve('./sidebar_spec_supabase.js'),
// // disableVersioning: true, // if not set with versions, throw: Identifier 'React' has already been declared
// },
// ],
// [
// '@docusaurus/plugin-content-docs',
// {
// id: 'postgrest-client', // for first plugin-content-docs with "resources/" path
// // homePageId: "doc2",
// path: './ref/postgrest', // Path to data on filesystem, relative to site dir.
// routeBasePath: 'ref/postgrest', // URL Route.
// include: ['**/*.md', '**/*.mdx'],
// sidebarPath: require.resolve('./sidebar_spec_postgrest.js'),
// // disableVersioning: true, // if not set with versions, throw: Identifier 'React' has already been declared
// },
// ],
// [
// '@docusaurus/plugin-content-docs',
// {
// id: 'gotrue-client', // for first plugin-content-docs with "resources/" path
// // homePageId: "doc2",
// path: './ref/gotrue', // Path to data on filesystem, relative to site dir.
// routeBasePath: 'ref/gotrue', // URL Route.
// include: ['**/*.md', '**/*.mdx'],
// sidebarPath: require.resolve('./sidebar_spec_gotrue.js'),
// // disableVersioning: true, // if not set with versions, throw: Identifier 'React' has already been declared
// },
// ],
// [
// '@docusaurus/plugin-content-docs',
// {
// id: 'realtime-client', // for first plugin-content-docs with "resources/" path
// // homePageId: "doc2",
// path: './ref/realtime', // Path to data on filesystem, relative to site dir.
// routeBasePath: 'ref/realtime', // URL Route.
// include: ['**/*.md', '**/*.mdx'],
// sidebarPath: require.resolve('./sidebar_spec_realtime.js'),
// // disableVersioning: true, // if not set with versions, throw: Identifier 'React' has already been declared
// },
// ],
// [
// '@docusaurus/plugin-content-docs',
// {
// id: 'realtime-server', // for first plugin-content-docs with "resources/" path
// path: './tools/realtime', // Path to data on filesystem, relative to site dir.
// routeBasePath: 'docs/realtime', // URL Route.
// include: ['**/*.md', '**/*.mdx'],
// sidebarPath: require.resolve('./sidebar_realtime_server.js'),
// // disableVersioning: true, // if not set with versions, throw: Identifier 'React' has already been declared
// },
// ],
// [
// '@docusaurus/plugin-content-docs',
// {
// id: 'postgrest', // for first plugin-content-docs with "resources/" path
// // homePageId: "doc2",
// path: './ref/postgrest', // Path to data on filesystem, relative to site dir.
// routeBasePath: 'ref/postgrest', // URL Route.
// include: ['**/*.md', '**/*.mdx'],
// sidebarPath: require.resolve('./sidebar_spec_postgrest.js'),
// // disableVersioning: true, // if not set with versions, throw: Identifier 'React' has already been declared
// },
// ],
],
}
-15098
View File
File diff suppressed because it is too large. Load diff
-41
View File
@@ -1,41 +0,0 @@
{
"name": "supabase",
"version": "0.0.3",
"private": true,
"scripts": {
"start": "docusaurus start --port 3005",
"build": "docusaurus build"
},
"dependencies": {
"@docusaurus/core": "^2.0.0-alpha.63",
"@docusaurus/preset-classic": "^2.0.0-alpha.63",
"@kiwicopple/prism-react-renderer": "github:kiwicopple/prism-react-renderer",
"mermaid": "^8.13.8",
"react": "^16.8.4",
"react-dom": "^16.8.4",
"react-inlinesvg": "^2.0.1"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"@types/node": "^14.14.14",
"axios": "^0.21.1",
"babel-plugin-css-modules-transform": "^1.6.2",
"clsx": "^1.1.1",
"dotenv": "^10.0.0",
"js-yaml": "^3.14.0",
"minimist": "^1.2.5",
"ts-node": "^9.0.0",
"typescript": "^4.1.3"
}
}
-16
View File
@@ -1,16 +0,0 @@
module.exports = {
docs: [
{
type: 'category',
label: 'Introduction',
items: ['handbook'],
collapsed: false,
},
{
type: 'category',
label: 'See Also',
collapsed: false,
items: ['handbook/contributing', 'handbook/supasquad'],
},
],
}
File diff suppressed because it is too large. Load diff
-82
View File
@@ -1,82 +0,0 @@
import React, { useState } from 'react'
import clsx from 'clsx'
import Layout from '@theme/Layout'
import Link from '@docusaurus/Link'
import useDocusaurusContext from '@docusaurus/useDocusaurusContext'
import useBaseUrl from '@docusaurus/useBaseUrl'
import styles from './styles.module.css'
export default function Home() {
const context = useDocusaurusContext()
const { siteConfig = {} } = context
return (
<Layout title={`${siteConfig.title}`} description={siteConfig.tagline}>
<main className="HomePage">
{/* HEADER */}
<header className={clsx('hero full', styles.heroBanner)}>
<div className="container">
<div className="row">
<div className="col col--5">
<h2 className="hero__title">{siteConfig.tagline}</h2>
<p className="hero__subtitle">
Supabase is the open source Firebase alternative.
</p>
<div>
<Link
className={clsx(
'button hero--button button--md button--secondary button--outline responsive-button',
styles.button
)}
to={useBaseUrl('/handbook')}
style={{ marginLeft: 0, marginTop: 10 }}
>
Learn More
</Link>
<Link
className={clsx(
'button hero--button button--md button--primary responsive-button',
styles.button
)}
to={'https://boards.greenhouse.io/supabase'}
style={{ marginTop: 10 }}
>
Join the team →
</Link>
</div>
</div>
<div className="col col--7">
{/* Example */}
</div>
</div>
</div>
</header>
{/* <section
style={{
padding: 30,
}}
className="hero is--dark"
>
<div
className="container "
style={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }}
>
<img src="/img/yc-gray.png" alt="Y Combinator" width="50" />
<p
style={{
fontWeight: 'bold',
padding: '0px 20px',
margin: 0,
display: 'inline-block',
}}
>
Backed by Y Combinator
</p>
</div>
</section> */}
</main>
</Layout>
)
}
-88
View File
@@ -1,88 +0,0 @@
/**
* CSS files with the .module.css suffix will be treated as CSS modules
* and scoped locally.
*/
/* .heroBanner {
padding: 4rem 0;
text-align: center;
position: relative;
overflow: hidden;
} */
.heroBanner {
/* height: calc(100vh - 60px); */
min-height: 80vh;
}
.hero .code-with-header {
box-shadow: 0 0 5px 5px rgba(0, 0, 0, 0.3);
/* box-shadow: var(--ifm-global-shadow-md); */
}
.heroBanner h2 {
font-size: 2rem !important;
}
.heroBanner p {
font-size: 1rem !important;
}
.heroImage {
max-height: 50vh;
}
.features {
display: flex;
margin-top: 5rem;
margin-bottom: 5rem;
align-items: center;
padding: 2rem 0;
width: 100%;
}
.forDevelopers {
display: flex;
margin-top: 5rem;
align-items: center;
padding: 2rem 0;
width: 100%;
}
.forDevelopers .button {
margin-top: 10px;
}
.featureCard {
height: 100%;
margin-bottom: 10px;
}
.featureImage {
height: 50px;
width: 50px;
}
.button {
margin: 25px 10px;
}
.howCard h3 {
font-size: 2.5rem;
font-weight: 800;
}
.pricingCard h3 {
font-size: 1.8rem;
margin-bottom: 20px;
}
.pricingCard p {
margin: 0;
}
.responsiveCentered {
text-align: center;
}
.centered {
text-align: center;
}
@media screen and (max-width: 999px) {
.responsiveCentered {
text-align: left;
}
}
-20
View File
@@ -1,20 +0,0 @@
/*.css
Cache-Control: public, max-age=10800
/*.js
Cache-Control: public, max-age=10800
/*.png
Cache-Control: public, max-age=10800
/*.jpg
Cache-Control: public, max-age=10800
/*.svg
Cache-Control: public, max-age=10800
/*.gif
Cache-Control: public, max-age=10800
/*
X-Frame-Options: DENY
-32
View File
@@ -1,32 +0,0 @@
/* Body Font (Metro) */
@font-face {
font-family: 'Metro';
src: url('/fonts/metro/metro-sans-book.woff2') format('woff2'),
url('/fonts/metro/metro-sans-book.woff') format('woff');
font-weight: 300;
font-style: normal;
}
@font-face {
font-family: 'Metro';
src: url('/fonts/metro/metro-sans-regular.woff2') format('woff2'),
url('/fonts/metro/metro-sans-regular.woff') format('woff');
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: 'Metro';
src: url('/fonts/metro/metro-sans-semi-bold.woff2') format('woff2'),
url('/fonts/metro/metro-sans-semi-bold.woff') format('woff');
font-weight: 600;
font-style: normal;
}
@font-face {
font-family: 'Metro';
src: url('/fonts/metro/metro-sans-bold.woff2') format('woff2'),
url('/fonts/metro/metro-sans-bold.woff') format('woff');
font-weight: 700;
font-style: normal;
}
-23
View File
@@ -1,23 +0,0 @@
@font-face {
font-family: 'TT Norms Pro';
font-style: normal;
font-weight: 400;
src: url('/fonts/tt-norms-pro/tt-pro-regular-webfont.woff2') format('woff2'),
url('/fonts/tt-norms-pro/tt-pro-regular-webfont.woff') format('woff');
}
@font-face {
font-family: 'TT Norms Pro';
font-style: normal;
font-weight: 500;
src: url('/fonts/tt-norms-pro/tt-pro-medium-webfont.woff2') format('woff2'),
url('/fonts/tt-norms-pro/tt-pro-medium-webfont.woff') format('woff');
}
@font-face {
font-family: 'TT Norms Pro';
font-style: normal;
font-weight: 700;
src: url('/fonts/tt-norms-pro/tt-pro-bold-webfont.woff2') format('woff2'),
url('/fonts/tt-norms-pro/tt-pro-bold-webfont.woff') format('woff');
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

@@ -1,23 +0,0 @@
<svg width="2978" height="628" viewBox="0 0 2978 628" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M717 390.353C720.036 418.721 745.841 467.351 820.725 467.351C885.995 467.351 917.366 425.813 917.366 385.288C917.366 348.815 892.573 318.928 843.493 308.796L808.075 301.198C794.414 298.665 785.306 291.067 785.306 278.909C785.306 264.725 799.474 254.088 817.183 254.088C845.517 254.088 856.143 272.83 858.167 287.521L914.33 274.857C911.294 248.009 887.513 202.925 816.677 202.925C763.044 202.925 723.578 239.904 723.578 284.481C723.578 319.434 745.335 348.309 793.402 358.946L826.29 366.545C845.517 370.597 853.107 379.716 853.107 390.86C853.107 404.031 842.482 415.682 820.219 415.682C790.872 415.682 776.199 397.445 774.681 377.689L717 390.353Z" fill="#1F1F1F"/>
<path d="M1132.42 459.753H1196.68C1195.67 451.141 1194.15 433.918 1194.15 414.668V210.523H1126.85V355.4C1126.85 384.275 1109.65 404.537 1079.8 404.537C1048.43 404.537 1034.26 382.248 1034.26 354.387V210.523H966.967V368.065C966.967 422.267 1001.37 466.338 1061.58 466.338C1087.89 466.338 1116.74 456.207 1130.4 432.905C1130.4 443.036 1131.41 454.687 1132.42 459.753Z" fill="#1F1F1F"/>
<path d="M1333.26 556V435.438C1345.4 452.154 1370.7 465.832 1405.11 465.832C1475.44 465.832 1522.49 410.109 1522.49 334.631C1522.49 260.673 1480.5 204.951 1407.64 204.951C1370.2 204.951 1342.37 221.667 1331.24 240.917V210.523H1265.97V556H1333.26ZM1456.21 335.138C1456.21 379.716 1428.89 405.55 1394.48 405.55C1360.08 405.55 1332.25 379.209 1332.25 335.138C1332.25 291.067 1360.08 265.232 1394.48 265.232C1428.89 265.232 1456.21 291.067 1456.21 335.138Z" fill="#1F1F1F"/>
<path d="M1560.6 391.873C1560.6 430.879 1592.98 466.845 1646.11 466.845C1683.04 466.845 1706.82 449.621 1719.47 429.865C1719.47 439.49 1720.48 453.167 1722 459.753H1783.73C1782.21 451.141 1780.7 433.411 1780.7 420.241V297.652C1780.7 247.502 1751.35 202.925 1672.42 202.925C1605.63 202.925 1569.7 245.982 1565.66 284.988L1625.36 297.652C1627.39 275.87 1643.58 257.127 1672.92 257.127C1701.26 257.127 1714.92 271.817 1714.92 289.547C1714.92 298.159 1710.37 305.251 1696.2 307.277L1634.98 316.395C1593.49 322.474 1560.6 347.295 1560.6 391.873ZM1660.27 416.695C1638.52 416.695 1627.89 402.511 1627.89 387.821C1627.89 368.571 1641.55 358.946 1658.76 356.414L1714.92 347.802V358.946C1714.92 403.018 1688.61 416.695 1660.27 416.695Z" fill="#1F1F1F"/>
<path d="M1913.8 459.753V429.359C1926.95 450.635 1953.26 465.832 1987.67 465.832C2058.51 465.832 2105.06 409.603 2105.06 334.125C2105.06 260.166 2063.06 203.938 1990.2 203.938C1953.26 203.938 1925.94 220.148 1914.81 237.877V93H1848.53V459.753H1913.8ZM2037.76 334.631C2037.76 380.222 2010.44 405.55 1976.03 405.55C1942.13 405.55 1913.8 379.716 1913.8 334.631C1913.8 289.04 1942.13 264.219 1976.03 264.219C2010.44 264.219 2037.76 289.04 2037.76 334.631Z" fill="#1F1F1F"/>
<path d="M2143.16 391.873C2143.16 430.879 2175.54 466.845 2228.67 466.845C2265.6 466.845 2289.39 449.621 2302.03 429.865C2302.03 439.49 2303.05 453.167 2304.56 459.753H2366.29C2364.78 451.141 2363.26 433.411 2363.26 420.241V297.652C2363.26 247.502 2333.91 202.925 2254.98 202.925C2188.19 202.925 2152.27 245.982 2148.22 284.988L2207.92 297.652C2209.95 275.87 2226.14 257.127 2255.48 257.127C2283.82 257.127 2297.48 271.817 2297.48 289.547C2297.48 298.159 2292.93 305.251 2278.76 307.277L2217.54 316.395C2176.05 322.474 2143.16 347.295 2143.16 391.873ZM2242.84 416.695C2221.08 416.695 2210.45 402.511 2210.45 387.821C2210.45 368.571 2224.11 358.946 2241.32 356.414L2297.48 347.802V358.946C2297.48 403.018 2271.17 416.695 2242.84 416.695Z" fill="#1F1F1F"/>
<path d="M2409.84 390.353C2412.87 418.721 2438.68 467.351 2513.56 467.351C2578.83 467.351 2610.2 425.813 2610.2 385.288C2610.2 348.815 2585.41 318.928 2536.33 308.796L2500.91 301.198C2487.25 298.665 2478.15 291.067 2478.15 278.909C2478.15 264.725 2492.31 254.088 2510.02 254.088C2538.36 254.088 2548.98 272.83 2551.01 287.521L2607.17 274.857C2604.13 248.009 2580.35 202.925 2509.52 202.925C2455.88 202.925 2416.42 239.904 2416.42 284.481C2416.42 319.434 2438.17 348.309 2486.24 358.946L2519.13 366.545C2538.36 370.597 2545.95 379.716 2545.95 390.86C2545.95 404.031 2535.32 415.682 2513.06 415.682C2483.71 415.682 2469.04 397.445 2467.52 377.689L2409.84 390.353Z" fill="#1F1F1F"/>
<path d="M2712.4 306.77C2713.92 283.975 2733.15 257.633 2768.06 257.633C2806.51 257.633 2822.71 281.949 2823.72 306.77H2712.4ZM2830.3 371.611C2822.2 393.899 2805 409.603 2773.63 409.603C2740.23 409.603 2712.4 385.794 2710.89 352.868H2888.99C2888.99 351.854 2890 341.723 2890 332.098C2890 252.061 2843.96 202.925 2767.05 202.925C2703.3 202.925 2644.6 254.594 2644.6 334.125C2644.6 418.214 2704.81 467.351 2773.12 467.351C2834.34 467.351 2873.81 431.385 2886.46 388.327L2830.3 371.611Z" fill="#1F1F1F"/>
<path d="M60.45 376.395C45.8421 376.395 34 364.556 34 349.953C34 344.056 35.9305 338.611 39.194 334.213L49.3806 319.913L280.276 8.14532C282.108 5.63276 285.075 4 288.424 4C293.989 4 298.5 8.50994 298.5 14.0732V15.2065L298.5 376.395H60.45Z" fill="#3ECF8E"/>
<path d="M536.55 241.854C551.158 241.854 563 253.693 563 268.297C563 274.193 561.07 279.638 557.806 284.036L547.619 298.336L316.724 610.104C314.891 612.616 311.925 614.249 308.576 614.249C303.011 614.249 298.5 609.739 298.5 604.176L298.5 603.043L298.5 241.854L536.55 241.854Z" fill="url(#paint0_linear)"/>
<path d="M536.55 241.854C551.158 241.854 563 253.693 563 268.297C563 274.193 561.07 279.638 557.806 284.036L547.619 298.336L316.724 610.104C314.891 612.616 311.925 614.249 308.576 614.249C303.011 614.249 298.5 609.739 298.5 604.176L298.5 603.043L298.5 241.854L536.55 241.854Z" fill="url(#paint1_linear)" fill-opacity="0.2"/>
<defs>
<linearGradient id="paint0_linear" x1="298.5" y1="318.891" x2="495.646" y2="395.82" gradientUnits="userSpaceOnUse">
<stop stop-color="#249361"/>
<stop offset="1" stop-color="#3ECF8E"/>
</linearGradient>
<linearGradient id="paint1_linear" x1="212.852" y1="192.853" x2="311.265" y2="365.218" gradientUnits="userSpaceOnUse">
<stop/>
<stop offset="1" stop-opacity="0"/>
</linearGradient>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

-2
View File
@@ -1,2 +0,0 @@
User-agent: *
Allow: /
Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

-23
View File
@@ -1,23 +0,0 @@
<svg width="3397" height="1207" viewBox="0 0 3397 1207" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M958 680.353C961.036 708.721 986.841 757.351 1061.72 757.351C1127 757.351 1158.37 715.813 1158.37 675.288C1158.37 638.815 1133.57 608.928 1084.49 598.796L1049.08 591.198C1035.41 588.665 1026.31 581.067 1026.31 568.909C1026.31 554.725 1040.47 544.088 1058.18 544.088C1086.52 544.088 1097.14 562.83 1099.17 577.521L1155.33 564.857C1152.29 538.009 1128.51 492.925 1057.68 492.925C1004.04 492.925 964.578 529.904 964.578 574.481C964.578 609.434 986.335 638.309 1034.4 648.946L1067.29 656.545C1086.52 660.597 1094.11 669.716 1094.11 680.86C1094.11 694.031 1083.48 705.682 1061.22 705.682C1031.87 705.682 1017.2 687.445 1015.68 667.689L958 680.353Z" fill="white"/>
<path d="M1373.42 749.753H1437.68C1436.67 741.141 1435.15 723.918 1435.15 704.668V500.523H1367.85V645.4C1367.85 674.275 1350.65 694.537 1320.8 694.537C1289.43 694.537 1275.26 672.248 1275.26 644.387V500.523H1207.97V658.065C1207.97 712.267 1242.37 756.338 1302.58 756.338C1328.89 756.338 1357.74 746.207 1371.4 722.905C1371.4 733.036 1372.41 744.687 1373.42 749.753Z" fill="white"/>
<path d="M1574.26 846V725.438C1586.4 742.154 1611.7 755.832 1646.11 755.832C1716.44 755.832 1763.49 700.109 1763.49 624.631C1763.49 550.673 1721.5 494.951 1648.64 494.951C1611.2 494.951 1583.37 511.667 1572.24 530.917V500.523H1506.97V846H1574.26ZM1697.21 625.138C1697.21 669.716 1669.89 695.55 1635.48 695.55C1601.08 695.55 1573.25 669.209 1573.25 625.138C1573.25 581.067 1601.08 555.232 1635.48 555.232C1669.89 555.232 1697.21 581.067 1697.21 625.138Z" fill="white"/>
<path d="M1801.6 681.873C1801.6 720.879 1833.98 756.845 1887.11 756.845C1924.04 756.845 1947.82 739.621 1960.47 719.865C1960.47 729.49 1961.48 743.167 1963 749.753H2024.73C2023.21 741.141 2021.7 723.411 2021.7 710.241V587.652C2021.7 537.502 1992.35 492.925 1913.42 492.925C1846.63 492.925 1810.7 535.982 1806.66 574.988L1866.36 587.652C1868.39 565.87 1884.58 547.127 1913.92 547.127C1942.26 547.127 1955.92 561.817 1955.92 579.547C1955.92 588.159 1951.37 595.251 1937.2 597.277L1875.98 606.395C1834.49 612.474 1801.6 637.295 1801.6 681.873ZM1901.27 706.695C1879.52 706.695 1868.89 692.511 1868.89 677.821C1868.89 658.571 1882.55 648.946 1899.76 646.414L1955.92 637.802V648.946C1955.92 693.018 1929.61 706.695 1901.27 706.695Z" fill="white"/>
<path d="M2154.8 749.753V719.359C2167.95 740.635 2194.26 755.832 2228.67 755.832C2299.51 755.832 2346.06 699.603 2346.06 624.125C2346.06 550.166 2304.06 493.938 2231.2 493.938C2194.26 493.938 2166.94 510.148 2155.81 527.877V383H2089.53V749.753H2154.8ZM2278.76 624.631C2278.76 670.222 2251.44 695.55 2217.03 695.55C2183.13 695.55 2154.8 669.716 2154.8 624.631C2154.8 579.04 2183.13 554.219 2217.03 554.219C2251.44 554.219 2278.76 579.04 2278.76 624.631Z" fill="white"/>
<path d="M2384.16 681.873C2384.16 720.879 2416.54 756.845 2469.67 756.845C2506.6 756.845 2530.39 739.621 2543.03 719.865C2543.03 729.49 2544.05 743.167 2545.56 749.753H2607.29C2605.78 741.141 2604.26 723.411 2604.26 710.241V587.652C2604.26 537.502 2574.91 492.925 2495.98 492.925C2429.19 492.925 2393.27 535.982 2389.22 574.988L2448.92 587.652C2450.95 565.87 2467.14 547.127 2496.48 547.127C2524.82 547.127 2538.48 561.817 2538.48 579.547C2538.48 588.159 2533.93 595.251 2519.76 597.277L2458.54 606.395C2417.05 612.474 2384.16 637.295 2384.16 681.873ZM2483.84 706.695C2462.08 706.695 2451.45 692.511 2451.45 677.821C2451.45 658.571 2465.11 648.946 2482.32 646.414L2538.48 637.802V648.946C2538.48 693.018 2512.17 706.695 2483.84 706.695Z" fill="white"/>
<path d="M2650.84 680.353C2653.87 708.721 2679.68 757.351 2754.56 757.351C2819.83 757.351 2851.2 715.813 2851.2 675.288C2851.2 638.815 2826.41 608.928 2777.33 598.796L2741.91 591.198C2728.25 588.665 2719.15 581.067 2719.15 568.909C2719.15 554.725 2733.31 544.088 2751.02 544.088C2779.36 544.088 2789.98 562.83 2792.01 577.521L2848.17 564.857C2845.13 538.009 2821.35 492.925 2750.52 492.925C2696.88 492.925 2657.42 529.904 2657.42 574.481C2657.42 609.434 2679.17 638.309 2727.24 648.946L2760.13 656.545C2779.36 660.597 2786.95 669.716 2786.95 680.86C2786.95 694.031 2776.32 705.682 2754.06 705.682C2724.71 705.682 2710.04 687.445 2708.52 667.689L2650.84 680.353Z" fill="white"/>
<path d="M2953.4 596.77C2954.92 573.975 2974.15 547.633 3009.06 547.633C3047.51 547.633 3063.71 571.949 3064.72 596.77H2953.4ZM3071.3 661.611C3063.2 683.899 3046 699.603 3014.63 699.603C2981.23 699.603 2953.4 675.794 2951.89 642.868H3129.99C3129.99 641.854 3131 631.723 3131 622.098C3131 542.061 3084.96 492.925 3008.05 492.925C2944.3 492.925 2885.6 544.594 2885.6 624.125C2885.6 708.214 2945.81 757.351 3014.12 757.351C3075.34 757.351 3114.81 721.385 3127.46 678.327L3071.3 661.611Z" fill="white"/>
<path d="M285.45 662.395C270.842 662.395 259 650.556 259 635.953C259 630.056 260.93 624.611 264.194 620.213L274.381 605.913L505.276 294.145C507.108 291.633 510.075 290 513.424 290C518.989 290 523.5 294.51 523.5 300.073V301.206L523.5 662.395H285.45Z" fill="#3ECF8E"/>
<path d="M761.55 527.854C776.158 527.854 788 539.693 788 554.297C788 560.193 786.07 565.638 782.806 570.036L772.619 584.336L541.724 896.104C539.891 898.616 536.925 900.249 533.576 900.249C528.011 900.249 523.5 895.739 523.5 890.176L523.5 889.043L523.5 527.854L761.55 527.854Z" fill="url(#paint0_linear)"/>
<path d="M761.55 527.854C776.158 527.854 788 539.693 788 554.297C788 560.193 786.07 565.638 782.806 570.036L772.619 584.336L541.724 896.104C539.891 898.616 536.925 900.249 533.576 900.249C528.011 900.249 523.5 895.739 523.5 890.176L523.5 889.043L523.5 527.854L761.55 527.854Z" fill="url(#paint1_linear)" fill-opacity="0.2"/>
<defs>
<linearGradient id="paint0_linear" x1="523.5" y1="604.891" x2="720.646" y2="681.82" gradientUnits="userSpaceOnUse">
<stop stop-color="#249361"/>
<stop offset="1" stop-color="#3ECF8E"/>
</linearGradient>
<linearGradient id="paint1_linear" x1="437.852" y1="478.853" x2="536.265" y2="651.218" gradientUnits="userSpaceOnUse">
<stop/>
<stop offset="1" stop-opacity="0"/>
</linearGradient>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

-28
View File
@@ -1,28 +0,0 @@
<svg width="565" height="112" viewBox="0 0 565 112" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0)">
<path d="M135.372 66.5501C135.972 72.1514 141.067 81.7535 155.852 81.7535C168.74 81.7535 174.934 73.5517 174.934 65.55C174.934 58.3483 170.039 52.447 160.348 50.4465L153.355 48.9462C150.657 48.4461 148.859 46.9458 148.859 44.5452C148.859 41.7445 151.656 39.6442 155.153 39.6442C160.748 39.6442 162.846 43.3449 163.245 46.2457L174.335 43.7451C173.735 38.4439 169.04 29.542 155.053 29.542C144.463 29.542 136.671 36.8436 136.671 45.6454C136.671 52.5469 140.967 58.2484 150.458 60.3487L156.951 61.8491C160.748 62.6492 162.246 64.4498 162.246 66.6502C162.246 69.2508 160.148 71.5513 155.752 71.5513C149.958 71.5513 147.061 67.9504 146.761 64.0495L135.372 66.5501Z" fill="white"/>
<path d="M217.396 80.253H230.084C229.885 78.5525 229.585 75.1518 229.585 71.3509V31.042H216.296V59.6483C216.296 65.3497 212.9 69.3505 207.006 69.3505C200.813 69.3505 198.015 64.9495 198.015 59.4483V31.042H184.728V62.149C184.728 72.8513 191.521 81.5532 203.409 81.5532C208.604 81.5532 214.3 79.5528 216.997 74.9518C216.997 76.9522 217.197 79.2527 217.396 80.253Z" fill="white"/>
<path d="M257.051 99.2578V75.4526C259.448 78.7532 264.444 81.4539 271.238 81.4539C285.125 81.4539 294.414 70.4513 294.414 55.548C294.414 40.9448 286.124 29.9424 271.738 29.9424C264.345 29.9424 258.85 33.243 256.653 37.044V31.0426H243.765V99.2578H257.051ZM281.328 55.6481C281.328 64.4501 275.933 69.5511 269.139 69.5511C262.347 69.5511 256.852 64.35 256.852 55.6481C256.852 46.9462 262.347 41.845 269.139 41.845C275.933 41.845 281.328 46.9462 281.328 55.6481Z" fill="white"/>
<path d="M301.939 66.8502C301.939 74.552 308.333 81.6536 318.823 81.6536C326.115 81.6536 330.81 78.2527 333.308 74.3518C333.308 76.2523 333.507 78.9528 333.807 80.2533H345.996C345.696 78.5528 345.397 75.052 345.397 72.4515V48.246C345.397 38.3438 339.602 29.542 324.018 29.542C310.83 29.542 303.736 38.0437 302.938 45.7455L314.726 48.246C315.127 43.9451 318.323 40.2443 324.117 40.2443C329.712 40.2443 332.409 43.1449 332.409 46.6457C332.409 48.3462 331.511 49.7465 328.713 50.1465L316.625 51.9469C308.433 53.1472 301.939 58.0482 301.939 66.8502ZM321.619 71.7514C317.324 71.7514 315.225 68.9507 315.225 66.0501C315.225 62.2492 317.923 60.3487 321.321 59.8487L332.409 58.1483V60.3487C332.409 69.0508 327.215 71.7514 321.619 71.7514Z" fill="white"/>
<path d="M371.678 80.2531V74.2518C374.275 78.4528 379.469 81.4534 386.264 81.4534C400.251 81.4534 409.442 70.3509 409.442 55.4476C409.442 40.8442 401.149 29.7419 386.763 29.7419C379.469 29.7419 374.075 32.9426 371.878 36.4432V7.83691H358.791V80.2531H371.678ZM396.154 55.5475C396.154 64.5495 390.76 69.5506 383.965 69.5506C377.272 69.5506 371.678 64.4496 371.678 55.5475C371.678 46.5455 377.272 41.6445 383.965 41.6445C390.76 41.6445 396.154 46.5455 396.154 55.5475Z" fill="white"/>
<path d="M416.965 66.8502C416.965 74.552 423.358 81.6536 433.849 81.6536C441.14 81.6536 445.838 78.2527 448.333 74.3518C448.333 76.2523 448.535 78.9528 448.833 80.2533H461.021C460.723 78.5528 460.423 75.052 460.423 72.4515V48.246C460.423 38.3438 454.628 29.542 439.043 29.542C425.856 29.542 418.764 38.0437 417.964 45.7455L429.752 48.246C430.152 43.9451 433.349 40.2443 439.142 40.2443C444.738 40.2443 447.435 43.1449 447.435 46.6457C447.435 48.3462 446.537 49.7465 443.739 50.1465L431.651 51.9469C423.459 53.1472 416.965 58.0482 416.965 66.8502ZM436.646 71.7514C432.35 71.7514 430.251 68.9507 430.251 66.0501C430.251 62.2492 432.948 60.3487 436.346 59.8487L447.435 58.1483V60.3487C447.435 69.0508 442.24 71.7514 436.646 71.7514Z" fill="white"/>
<path d="M469.62 66.5501C470.218 72.1514 475.315 81.7535 490.099 81.7535C502.987 81.7535 509.181 73.5517 509.181 65.55C509.181 58.3483 504.286 52.447 494.595 50.4465L487.602 48.9462C484.905 48.4461 483.108 46.9458 483.108 44.5452C483.108 41.7445 485.904 39.6442 489.4 39.6442C494.996 39.6442 497.093 43.3449 497.494 46.2457L508.583 43.7451C507.982 38.4439 503.287 29.542 489.302 29.542C478.711 29.542 470.919 36.8436 470.919 45.6454C470.919 52.5469 475.214 58.2484 484.705 60.3487L491.199 61.8491C494.996 62.6492 496.495 64.4498 496.495 66.6502C496.495 69.2508 494.396 71.5513 490.001 71.5513C484.206 71.5513 481.309 67.9504 481.009 64.0495L469.62 66.5501Z" fill="white"/>
<path d="M529.36 50.0464C529.66 45.5455 533.457 40.3442 540.35 40.3442C547.942 40.3442 551.141 45.1455 551.34 50.0464H529.36ZM552.639 62.8494C551.04 67.2502 547.644 70.351 541.45 70.351C534.855 70.351 529.36 65.6499 529.062 59.1486H564.227C564.227 58.9484 564.427 56.948 564.427 55.0475C564.427 39.244 555.336 29.542 540.151 29.542C527.563 29.542 515.973 39.7441 515.973 55.4477C515.973 72.0513 527.861 81.7535 541.349 81.7535C553.437 81.7535 561.23 74.6519 563.728 66.15L552.639 62.8494Z" fill="white"/>
<path d="M63.6831 110.073C60.8236 113.674 55.0256 111.701 54.9567 107.103L53.9492 39.8516H99.169C107.36 39.8516 111.928 49.3117 106.835 55.7263L63.6831 110.073Z" fill="url(#paint0_linear)"/>
<path d="M63.6831 110.073C60.8236 113.674 55.0256 111.701 54.9567 107.103L53.9492 39.8516H99.169C107.36 39.8516 111.928 49.3117 106.835 55.7263L63.6831 110.073Z" fill="url(#paint1_linear)" fill-opacity="0.2"/>
<path d="M45.2924 1.85984C48.1519 -1.74155 53.9498 0.231757 54.0187 4.82982L54.4603 72.081H9.80647C1.61572 72.081 -2.95241 62.6209 2.14084 56.2063L45.2924 1.85984Z" fill="#3ECF8E"/>
</g>
<defs>
<linearGradient id="paint0_linear" x1="53.9492" y1="54.7628" x2="94.1389" y2="71.6184" gradientUnits="userSpaceOnUse">
<stop stop-color="#249361"/>
<stop offset="1" stop-color="#3ECF8E"/>
</linearGradient>
<linearGradient id="paint1_linear" x1="36.1312" y1="30.3669" x2="54.4599" y2="64.8695" gradientUnits="userSpaceOnUse">
<stop/>
<stop offset="1" stop-opacity="0"/>
</linearGradient>
<clipPath id="clip0">
<rect width="565" height="112" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 5.7 KiB

@@ -1,24 +0,0 @@
<svg width="613" height="148" viewBox="0 0 613 148" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="612.427" height="147.933" rx="8" fill="white"/>
<path d="M159.372 84.5501C159.972 90.1514 165.067 99.7535 179.852 99.7535C192.74 99.7535 198.934 91.5517 198.934 83.55C198.934 76.3483 194.039 70.447 184.348 68.4465L177.355 66.9462C174.657 66.4461 172.859 64.9458 172.859 62.5452C172.859 59.7445 175.656 57.6442 179.153 57.6442C184.748 57.6442 186.846 61.3449 187.245 64.2457L198.335 61.7451C197.735 56.4439 193.04 47.542 179.053 47.542C168.463 47.542 160.671 54.8436 160.671 63.6454C160.671 70.5469 164.967 76.2484 174.458 78.3487L180.951 79.8491C184.748 80.6492 186.246 82.4498 186.246 84.6502C186.246 87.2508 184.148 89.5513 179.752 89.5513C173.958 89.5513 171.061 85.9504 170.761 82.0495L159.372 84.5501Z" fill="#0E1218"/>
<path d="M241.396 98.253H254.084C253.885 96.5525 253.585 93.1518 253.585 89.3509V49.042H240.296V77.6483C240.296 83.3497 236.9 87.3505 231.006 87.3505C224.813 87.3505 222.015 82.9495 222.015 77.4483V49.042H208.728V80.149C208.728 90.8513 215.521 99.5532 227.409 99.5532C232.604 99.5532 238.3 97.5528 240.997 92.9518C240.997 94.9522 241.197 97.2527 241.396 98.253Z" fill="#0E1218"/>
<path d="M281.051 117.257V93.4521C283.448 96.7527 288.444 99.4534 295.238 99.4534C309.125 99.4534 318.414 88.4508 318.414 73.5475C318.414 58.9443 310.124 47.9419 295.738 47.9419C288.345 47.9419 282.85 51.2425 280.653 55.0435V49.0421H267.765V117.257H281.051ZM305.328 73.6476C305.328 82.4496 299.933 87.5506 293.139 87.5506C286.347 87.5506 280.852 82.3495 280.852 73.6476C280.852 64.9457 286.347 59.8445 293.139 59.8445C299.933 59.8445 305.328 64.9457 305.328 73.6476Z" fill="#0E1218"/>
<path d="M325.939 84.8502C325.939 92.552 332.333 99.6536 342.823 99.6536C350.115 99.6536 354.81 96.2527 357.308 92.3518C357.308 94.2523 357.507 96.9528 357.807 98.2533H369.996C369.696 96.5528 369.397 93.052 369.397 90.4515V66.246C369.397 56.3438 363.602 47.542 348.018 47.542C334.83 47.542 327.736 56.0437 326.938 63.7455L338.726 66.246C339.127 61.9451 342.323 58.2443 348.117 58.2443C353.712 58.2443 356.409 61.1449 356.409 64.6457C356.409 66.3462 355.511 67.7465 352.713 68.1465L340.625 69.9469C332.433 71.1472 325.939 76.0482 325.939 84.8502ZM345.619 89.7514C341.324 89.7514 339.225 86.9507 339.225 84.0501C339.225 80.2492 341.923 78.3487 345.321 77.8487L356.409 76.1483V78.3487C356.409 87.0508 351.215 89.7514 345.619 89.7514Z" fill="#0E1218"/>
<path d="M395.678 98.2531V92.2518C398.275 96.4528 403.469 99.4534 410.264 99.4534C424.251 99.4534 433.442 88.3509 433.442 73.4476C433.442 58.8442 425.149 47.7419 410.763 47.7419C403.469 47.7419 398.075 50.9426 395.878 54.4432V25.8369H382.791V98.2531H395.678ZM420.154 73.5475C420.154 82.5495 414.76 87.5506 407.965 87.5506C401.272 87.5506 395.678 82.4496 395.678 73.5475C395.678 64.5455 401.272 59.6445 407.965 59.6445C414.76 59.6445 420.154 64.5455 420.154 73.5475Z" fill="#0E1218"/>
<path d="M440.965 84.8502C440.965 92.552 447.358 99.6536 457.849 99.6536C465.14 99.6536 469.838 96.2527 472.333 92.3518C472.333 94.2523 472.535 96.9528 472.833 98.2533H485.021C484.723 96.5528 484.423 93.052 484.423 90.4515V66.246C484.423 56.3438 478.628 47.542 463.043 47.542C449.856 47.542 442.764 56.0437 441.964 63.7455L453.752 66.246C454.152 61.9451 457.349 58.2443 463.142 58.2443C468.738 58.2443 471.435 61.1449 471.435 64.6457C471.435 66.3462 470.537 67.7465 467.739 68.1465L455.651 69.9469C447.459 71.1472 440.965 76.0482 440.965 84.8502ZM460.646 89.7514C456.35 89.7514 454.251 86.9507 454.251 84.0501C454.251 80.2492 456.948 78.3487 460.346 77.8487L471.435 76.1483V78.3487C471.435 87.0508 466.24 89.7514 460.646 89.7514Z" fill="#0E1218"/>
<path d="M493.62 84.5501C494.218 90.1514 499.315 99.7535 514.099 99.7535C526.987 99.7535 533.181 91.5517 533.181 83.55C533.181 76.3483 528.286 70.447 518.595 68.4465L511.602 66.9462C508.905 66.4461 507.108 64.9458 507.108 62.5452C507.108 59.7445 509.904 57.6442 513.4 57.6442C518.996 57.6442 521.093 61.3449 521.494 64.2457L532.583 61.7451C531.982 56.4439 527.287 47.542 513.302 47.542C502.711 47.542 494.919 54.8436 494.919 63.6454C494.919 70.5469 499.214 76.2484 508.705 78.3487L515.199 79.8491C518.996 80.6492 520.495 82.4498 520.495 84.6502C520.495 87.2508 518.396 89.5513 514.001 89.5513C508.206 89.5513 505.309 85.9504 505.009 82.0495L493.62 84.5501Z" fill="#0E1218"/>
<path d="M553.36 68.0464C553.66 63.5455 557.457 58.3442 564.35 58.3442C571.942 58.3442 575.141 63.1455 575.34 68.0464H553.36ZM576.639 80.8494C575.04 85.2502 571.644 88.351 565.45 88.351C558.855 88.351 553.36 83.6499 553.062 77.1486H588.227C588.227 76.9484 588.427 74.948 588.427 73.0475C588.427 57.244 579.336 47.542 564.151 47.542C551.563 47.542 539.973 57.7441 539.973 73.4477C539.973 90.0513 551.861 99.7535 565.349 99.7535C577.437 99.7535 585.23 92.6519 587.728 84.15L576.639 80.8494Z" fill="#0E1218"/>
<path d="M87.683 128.073C84.8235 131.674 79.0255 129.701 78.9566 125.103L77.9491 57.8516H123.169C131.36 57.8516 135.928 67.3117 130.835 73.7263L87.683 128.073Z" fill="url(#paint0_linear)"/>
<path d="M87.683 128.073C84.8235 131.674 79.0255 129.701 78.9566 125.103L77.9491 57.8516H123.169C131.36 57.8516 135.928 67.3117 130.835 73.7263L87.683 128.073Z" fill="url(#paint1_linear)" fill-opacity="0.2"/>
<path d="M69.2924 19.8598C72.1519 16.2585 77.9498 18.2318 78.0187 22.8298L78.4603 90.081H33.8065C25.6157 90.081 21.0476 80.6209 26.1408 74.2063L69.2924 19.8598Z" fill="#3ECF8E"/>
<defs>
<linearGradient id="paint0_linear" x1="77.9491" y1="72.7628" x2="118.139" y2="89.6184" gradientUnits="userSpaceOnUse">
<stop stop-color="#249361"/>
<stop offset="1" stop-color="#3ECF8E"/>
</linearGradient>
<linearGradient id="paint1_linear" x1="60.1311" y1="48.3669" x2="78.4598" y2="82.8695" gradientUnits="userSpaceOnUse">
<stop/>
<stop offset="1" stop-opacity="0"/>
</linearGradient>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 5.7 KiB

@@ -1,31 +0,0 @@
<svg width="867" height="148" viewBox="0 0 867 148" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="867" height="148" fill="white"/>
<g clip-path="url(#clip0)">
<path d="M828.086 30H638.015C630.275 30 624 36.2745 624 44.0145V103.576C624 111.316 630.275 117.59 638.015 117.59H828.086C835.826 117.59 842.1 111.316 842.1 103.576V44.0145C842.1 36.2745 835.826 30 828.086 30Z" fill="#3ECF8E" fill-opacity="0.2"/>
<path d="M669.699 83.801V63.9433H674.144C679.41 63.9433 683.71 67.0355 683.71 73.8963C683.71 80.7571 679.41 83.801 674.144 83.801H669.699ZM674.434 91C684.773 91 691.683 84.4774 691.683 73.8963C691.683 63.3152 684.773 56.7443 674.482 56.7443H662.065V91H674.434ZM706.205 73.848C706.205 66.6973 711.327 63.4601 716.11 63.4601C720.845 63.4601 725.967 66.6973 725.967 73.848C725.967 80.9987 720.845 84.1875 716.11 84.1875C711.327 84.1875 706.205 80.9987 706.205 73.848ZM698.282 73.8963C698.282 84.719 706.447 91.7247 716.11 91.7247C725.725 91.7247 733.89 84.719 733.89 73.8963C733.89 63.0253 725.725 56.0195 716.11 56.0195C706.447 56.0195 698.282 63.0253 698.282 73.8963ZM758.27 91.7247C768.899 91.7247 773.441 84.4774 774.552 79.7425L767.257 77.6649C766.58 80.129 764.213 84.0909 758.27 84.0909C753.149 84.0909 748.414 80.3706 748.414 73.9446C748.414 66.7456 753.583 63.4601 758.173 63.4601C764.213 63.4601 766.387 67.4703 766.919 69.8378L774.118 67.567C773.006 62.6388 768.465 56.0195 758.173 56.0195C748.607 56.0195 740.49 63.2669 740.49 73.9446C740.49 84.6223 748.414 91.7247 758.27 91.7247ZM806.511 65.1512C805.786 61.141 802.549 56.0195 793.997 56.0195C787.427 56.0195 781.725 60.5612 781.725 67.0355C781.725 72.1086 785.252 75.9739 791.05 77.0851L795.737 77.9548C798.008 78.3896 799.409 79.6458 799.409 81.3852C799.409 83.5111 797.573 84.9606 794.577 84.9606C789.891 84.9606 787.765 82.2066 787.475 79.0661L780.469 80.7571C780.952 85.5887 785.011 91.7247 794.481 91.7247C802.646 91.7247 807.139 86.2651 807.139 80.902C807.139 76.0222 803.757 71.8187 797.235 70.6108L792.645 69.7412C790.277 69.3063 789.263 68.0984 789.263 66.4557C789.263 64.5714 791.099 62.7837 793.949 62.7837C798.104 62.7837 799.409 65.4894 799.65 67.0838L806.511 65.1512Z" fill="#3ECF8E"/>
<path d="M159.372 84.5501C159.972 90.1514 165.067 99.7535 179.852 99.7535C192.74 99.7535 198.934 91.5517 198.934 83.55C198.934 76.3483 194.039 70.447 184.348 68.4465L177.355 66.9462C174.657 66.4461 172.859 64.9458 172.859 62.5452C172.859 59.7445 175.656 57.6442 179.153 57.6442C184.748 57.6442 186.846 61.3449 187.245 64.2457L198.335 61.7451C197.735 56.4439 193.04 47.542 179.053 47.542C168.463 47.542 160.671 54.8436 160.671 63.6454C160.671 70.5469 164.967 76.2484 174.458 78.3487L180.951 79.8491C184.748 80.6492 186.246 82.4498 186.246 84.6502C186.246 87.2508 184.148 89.5513 179.752 89.5513C173.958 89.5513 171.061 85.9504 170.761 82.0495L159.372 84.5501Z" fill="#0E1218"/>
<path d="M241.396 98.253H254.084C253.885 96.5525 253.585 93.1518 253.585 89.3509V49.042H240.296V77.6483C240.296 83.3497 236.9 87.3505 231.006 87.3505C224.813 87.3505 222.015 82.9495 222.015 77.4483V49.042H208.728V80.149C208.728 90.8513 215.521 99.5532 227.409 99.5532C232.604 99.5532 238.3 97.5528 240.997 92.9518C240.997 94.9522 241.197 97.2527 241.396 98.253Z" fill="#0E1218"/>
<path d="M281.051 117.257V93.4521C283.448 96.7527 288.444 99.4534 295.238 99.4534C309.125 99.4534 318.414 88.4508 318.414 73.5475C318.414 58.9443 310.124 47.9419 295.738 47.9419C288.345 47.9419 282.85 51.2425 280.653 55.0435V49.0421H267.765V117.257H281.051ZM305.328 73.6476C305.328 82.4496 299.933 87.5506 293.139 87.5506C286.347 87.5506 280.852 82.3495 280.852 73.6476C280.852 64.9457 286.347 59.8445 293.139 59.8445C299.933 59.8445 305.328 64.9457 305.328 73.6476Z" fill="#0E1218"/>
<path d="M325.939 84.8502C325.939 92.552 332.333 99.6536 342.823 99.6536C350.115 99.6536 354.81 96.2527 357.308 92.3518C357.308 94.2523 357.507 96.9528 357.807 98.2533H369.996C369.696 96.5528 369.397 93.052 369.397 90.4515V66.246C369.397 56.3438 363.602 47.542 348.018 47.542C334.83 47.542 327.736 56.0437 326.938 63.7455L338.726 66.246C339.127 61.9451 342.323 58.2443 348.117 58.2443C353.712 58.2443 356.409 61.1449 356.409 64.6457C356.409 66.3462 355.511 67.7465 352.713 68.1465L340.625 69.9469C332.433 71.1472 325.939 76.0482 325.939 84.8502ZM345.619 89.7514C341.324 89.7514 339.225 86.9507 339.225 84.0501C339.225 80.2492 341.923 78.3487 345.321 77.8487L356.409 76.1483V78.3487C356.409 87.0508 351.215 89.7514 345.619 89.7514Z" fill="#0E1218"/>
<path d="M395.678 98.2531V92.2518C398.275 96.4528 403.469 99.4534 410.264 99.4534C424.251 99.4534 433.442 88.3509 433.442 73.4476C433.442 58.8442 425.149 47.7419 410.763 47.7419C403.469 47.7419 398.075 50.9426 395.878 54.4432V25.8369H382.791V98.2531H395.678ZM420.154 73.5475C420.154 82.5495 414.76 87.5506 407.965 87.5506C401.272 87.5506 395.678 82.4496 395.678 73.5475C395.678 64.5455 401.272 59.6445 407.965 59.6445C414.76 59.6445 420.154 64.5455 420.154 73.5475Z" fill="#0E1218"/>
<path d="M440.965 84.8502C440.965 92.552 447.358 99.6536 457.849 99.6536C465.14 99.6536 469.838 96.2527 472.333 92.3518C472.333 94.2523 472.535 96.9528 472.833 98.2533H485.021C484.723 96.5528 484.423 93.052 484.423 90.4515V66.246C484.423 56.3438 478.628 47.542 463.043 47.542C449.856 47.542 442.764 56.0437 441.964 63.7455L453.752 66.246C454.152 61.9451 457.349 58.2443 463.142 58.2443C468.738 58.2443 471.435 61.1449 471.435 64.6457C471.435 66.3462 470.537 67.7465 467.739 68.1465L455.651 69.9469C447.459 71.1472 440.965 76.0482 440.965 84.8502ZM460.646 89.7514C456.35 89.7514 454.251 86.9507 454.251 84.0501C454.251 80.2492 456.948 78.3487 460.346 77.8487L471.435 76.1483V78.3487C471.435 87.0508 466.24 89.7514 460.646 89.7514Z" fill="#0E1218"/>
<path d="M493.62 84.5501C494.218 90.1514 499.315 99.7535 514.099 99.7535C526.987 99.7535 533.181 91.5517 533.181 83.55C533.181 76.3483 528.286 70.447 518.595 68.4465L511.602 66.9462C508.905 66.4461 507.108 64.9458 507.108 62.5452C507.108 59.7445 509.904 57.6442 513.4 57.6442C518.996 57.6442 521.093 61.3449 521.494 64.2457L532.583 61.7451C531.982 56.4439 527.287 47.542 513.302 47.542C502.711 47.542 494.919 54.8436 494.919 63.6454C494.919 70.5469 499.214 76.2484 508.705 78.3487L515.199 79.8491C518.996 80.6492 520.495 82.4498 520.495 84.6502C520.495 87.2508 518.396 89.5513 514.001 89.5513C508.206 89.5513 505.309 85.9504 505.009 82.0495L493.62 84.5501Z" fill="#0E1218"/>
<path d="M553.36 68.0464C553.66 63.5455 557.457 58.3442 564.35 58.3442C571.942 58.3442 575.141 63.1455 575.34 68.0464H553.36ZM576.639 80.8494C575.04 85.2502 571.644 88.351 565.45 88.351C558.855 88.351 553.36 83.6499 553.062 77.1486H588.227C588.227 76.9484 588.427 74.948 588.427 73.0475C588.427 57.244 579.336 47.542 564.151 47.542C551.563 47.542 539.973 57.7441 539.973 73.4477C539.973 90.0513 551.861 99.7535 565.349 99.7535C577.437 99.7535 585.23 92.6519 587.728 84.15L576.639 80.8494Z" fill="#0E1218"/>
<path d="M87.683 128.073C84.8235 131.674 79.0255 129.701 78.9566 125.103L77.9491 57.8516H123.169C131.36 57.8516 135.928 67.3117 130.835 73.7263L87.683 128.073Z" fill="url(#paint0_linear)"/>
<path d="M87.683 128.073C84.8235 131.674 79.0255 129.701 78.9566 125.103L77.9491 57.8516H123.169C131.36 57.8516 135.928 67.3117 130.835 73.7263L87.683 128.073Z" fill="url(#paint1_linear)" fill-opacity="0.2"/>
<path d="M69.2924 19.8598C72.1519 16.2585 77.9498 18.2318 78.0187 22.8298L78.4603 90.081H33.8065C25.6157 90.081 21.0476 80.6209 26.1408 74.2063L69.2924 19.8598Z" fill="#3ECF8E"/>
</g>
<defs>
<linearGradient id="paint0_linear" x1="77.9491" y1="72.7628" x2="118.139" y2="89.6184" gradientUnits="userSpaceOnUse">
<stop stop-color="#249361"/>
<stop offset="1" stop-color="#3ECF8E"/>
</linearGradient>
<linearGradient id="paint1_linear" x1="60.1311" y1="48.3669" x2="78.4598" y2="82.8695" gradientUnits="userSpaceOnUse">
<stop/>
<stop offset="1" stop-opacity="0"/>
</linearGradient>
<clipPath id="clip0">
<rect width="819" height="112" fill="white" transform="translate(24 18)"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 7.8 KiB

-23
View File
@@ -1,23 +0,0 @@
<svg width="565" height="112" viewBox="0 0 565 112" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M135.372 66.5501C135.972 72.1514 141.067 81.7535 155.852 81.7535C168.74 81.7535 174.934 73.5517 174.934 65.55C174.934 58.3483 170.039 52.447 160.348 50.4465L153.355 48.9462C150.657 48.4461 148.859 46.9458 148.859 44.5452C148.859 41.7445 151.656 39.6442 155.153 39.6442C160.748 39.6442 162.846 43.3449 163.245 46.2457L174.335 43.7451C173.735 38.4439 169.04 29.542 155.053 29.542C144.463 29.542 136.671 36.8436 136.671 45.6454C136.671 52.5469 140.967 58.2484 150.458 60.3487L156.951 61.8491C160.748 62.6492 162.246 64.4498 162.246 66.6502C162.246 69.2508 160.148 71.5513 155.752 71.5513C149.958 71.5513 147.061 67.9504 146.761 64.0495L135.372 66.5501Z" fill="#1F1F1F"/>
<path d="M217.396 80.253H230.084C229.885 78.5525 229.585 75.1518 229.585 71.3509V31.042H216.296V59.6483C216.296 65.3497 212.9 69.3505 207.006 69.3505C200.813 69.3505 198.015 64.9495 198.015 59.4483V31.042H184.728V62.149C184.728 72.8513 191.521 81.5532 203.409 81.5532C208.604 81.5532 214.3 79.5528 216.997 74.9518C216.997 76.9522 217.197 79.2527 217.396 80.253Z" fill="#1F1F1F"/>
<path d="M257.051 99.2578V75.4526C259.448 78.7532 264.444 81.4539 271.238 81.4539C285.125 81.4539 294.414 70.4513 294.414 55.548C294.414 40.9448 286.124 29.9424 271.738 29.9424C264.345 29.9424 258.85 33.243 256.653 37.044V31.0426H243.765V99.2578H257.051ZM281.328 55.6481C281.328 64.4501 275.933 69.5511 269.139 69.5511C262.347 69.5511 256.852 64.35 256.852 55.6481C256.852 46.9462 262.347 41.845 269.139 41.845C275.933 41.845 281.328 46.9462 281.328 55.6481Z" fill="#1F1F1F"/>
<path d="M301.939 66.8502C301.939 74.552 308.333 81.6536 318.823 81.6536C326.115 81.6536 330.81 78.2527 333.308 74.3518C333.308 76.2523 333.507 78.9528 333.807 80.2533H345.996C345.696 78.5528 345.397 75.052 345.397 72.4515V48.246C345.397 38.3438 339.602 29.542 324.018 29.542C310.83 29.542 303.736 38.0437 302.938 45.7455L314.726 48.246C315.127 43.9451 318.323 40.2443 324.117 40.2443C329.712 40.2443 332.409 43.1449 332.409 46.6457C332.409 48.3462 331.511 49.7465 328.713 50.1465L316.625 51.9469C308.433 53.1472 301.939 58.0482 301.939 66.8502ZM321.619 71.7514C317.324 71.7514 315.225 68.9507 315.225 66.0501C315.225 62.2492 317.923 60.3487 321.321 59.8487L332.409 58.1483V60.3487C332.409 69.0508 327.215 71.7514 321.619 71.7514Z" fill="#1F1F1F"/>
<path d="M371.678 80.2531V74.2518C374.275 78.4528 379.469 81.4534 386.264 81.4534C400.251 81.4534 409.442 70.3509 409.442 55.4476C409.442 40.8442 401.149 29.7419 386.763 29.7419C379.469 29.7419 374.075 32.9426 371.878 36.4432V7.83691H358.791V80.2531H371.678ZM396.154 55.5475C396.154 64.5495 390.76 69.5506 383.965 69.5506C377.272 69.5506 371.678 64.4496 371.678 55.5475C371.678 46.5455 377.272 41.6445 383.965 41.6445C390.76 41.6445 396.154 46.5455 396.154 55.5475Z" fill="#1F1F1F"/>
<path d="M416.965 66.8502C416.965 74.552 423.358 81.6536 433.849 81.6536C441.14 81.6536 445.838 78.2527 448.333 74.3518C448.333 76.2523 448.535 78.9528 448.833 80.2533H461.021C460.723 78.5528 460.423 75.052 460.423 72.4515V48.246C460.423 38.3438 454.628 29.542 439.043 29.542C425.856 29.542 418.764 38.0437 417.964 45.7455L429.752 48.246C430.152 43.9451 433.349 40.2443 439.142 40.2443C444.738 40.2443 447.435 43.1449 447.435 46.6457C447.435 48.3462 446.537 49.7465 443.739 50.1465L431.651 51.9469C423.459 53.1472 416.965 58.0482 416.965 66.8502ZM436.646 71.7514C432.35 71.7514 430.251 68.9507 430.251 66.0501C430.251 62.2492 432.948 60.3487 436.346 59.8487L447.435 58.1483V60.3487C447.435 69.0508 442.24 71.7514 436.646 71.7514Z" fill="#1F1F1F"/>
<path d="M469.62 66.5501C470.218 72.1514 475.315 81.7535 490.099 81.7535C502.987 81.7535 509.181 73.5517 509.181 65.55C509.181 58.3483 504.286 52.447 494.595 50.4465L487.602 48.9462C484.905 48.4461 483.108 46.9458 483.108 44.5452C483.108 41.7445 485.904 39.6442 489.4 39.6442C494.996 39.6442 497.093 43.3449 497.494 46.2457L508.583 43.7451C507.982 38.4439 503.287 29.542 489.302 29.542C478.711 29.542 470.919 36.8436 470.919 45.6454C470.919 52.5469 475.214 58.2484 484.705 60.3487L491.199 61.8491C494.996 62.6492 496.495 64.4498 496.495 66.6502C496.495 69.2508 494.396 71.5513 490.001 71.5513C484.206 71.5513 481.309 67.9504 481.009 64.0495L469.62 66.5501Z" fill="#1F1F1F"/>
<path d="M529.36 50.0464C529.66 45.5455 533.457 40.3442 540.35 40.3442C547.942 40.3442 551.141 45.1455 551.34 50.0464H529.36ZM552.639 62.8494C551.04 67.2502 547.644 70.351 541.45 70.351C534.855 70.351 529.36 65.6499 529.062 59.1486H564.227C564.227 58.9484 564.427 56.948 564.427 55.0475C564.427 39.244 555.336 29.542 540.151 29.542C527.563 29.542 515.973 39.7441 515.973 55.4477C515.973 72.0513 527.861 81.7535 541.349 81.7535C553.437 81.7535 561.23 74.6519 563.728 66.15L552.639 62.8494Z" fill="#1F1F1F"/>
<path d="M63.6831 110.073C60.8236 113.674 55.0256 111.701 54.9567 107.103L53.9492 39.8516H99.169C107.36 39.8516 111.928 49.3117 106.835 55.7263L63.6831 110.073Z" fill="url(#paint0_linear)"/>
<path d="M63.6831 110.073C60.8236 113.674 55.0256 111.701 54.9567 107.103L53.9492 39.8516H99.169C107.36 39.8516 111.928 49.3117 106.835 55.7263L63.6831 110.073Z" fill="url(#paint1_linear)" fill-opacity="0.2"/>
<path d="M45.2924 1.85984C48.1519 -1.74155 53.9498 0.231757 54.0187 4.82982L54.4603 72.081H9.80647C1.61572 72.081 -2.95241 62.6209 2.14084 56.2063L45.2924 1.85984Z" fill="#3ECF8E"/>
<defs>
<linearGradient id="paint0_linear" x1="53.9492" y1="54.7628" x2="94.1389" y2="71.6184" gradientUnits="userSpaceOnUse">
<stop stop-color="#249361"/>
<stop offset="1" stop-color="#3ECF8E"/>
</linearGradient>
<linearGradient id="paint1_linear" x1="36.1312" y1="30.3669" x2="54.4599" y2="64.8695" gradientUnits="userSpaceOnUse">
<stop/>
<stop offset="1" stop-opacity="0"/>
</linearGradient>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 5.7 KiB

-13
View File
@@ -1,13 +0,0 @@
<svg width="375" height="375" viewBox="0 0 375 375" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M218.909 28.4831C218.909 21.5889 213.322 16 206.431 16C203.004 16 199.9 17.382 197.645 19.6192L195.912 21.548L99.675 151.658H195.18L218.429 32.0055L218.853 29.6682C218.89 29.2781 218.909 28.8828 218.909 28.4831Z" fill="#3ECF8E"/>
<path d="M65 205.336C65 216.366 73.9385 225.308 84.9647 225.308L85.053 225.308H180.87L195.18 151.658H99.675L70.736 190.783L68.8725 193.512C66.4382 196.822 65 200.911 65 205.336Z" fill="#3ECF8E"/>
<path d="M310 171.631C310 160.6 301.061 151.658 290.035 151.658H289.245H195.18L180.87 225.308H275.202L305.604 184.205L306.817 182.455C308.831 179.337 310 175.62 310 171.631Z" fill="#3ECF8E"/>
<path d="M157.533 346.517C157.533 353.411 163.119 359 170.011 359C173.706 359 177.027 357.393 179.311 354.839L179.803 354.285L275.202 225.308H180.87L157.985 343.089L157.924 343.405C157.668 344.4 157.533 345.443 157.533 346.517Z" fill="#3ECF8E"/>
<path d="M157.533 346.517C157.533 353.411 163.119 359 170.011 359C173.706 359 177.027 357.393 179.311 354.839L179.803 354.285L275.202 225.308H180.87L157.985 343.089L157.924 343.405C157.668 344.4 157.533 345.443 157.533 346.517Z" fill="url(#paint0_linear)"/>
<defs>
<linearGradient id="paint0_linear" x1="236" y1="237" x2="167" y2="359" gradientUnits="userSpaceOnUse">
<stop stop-color="#23915F"/>
<stop offset="1" stop-color="#3ECF8E" stop-opacity="0"/>
</linearGradient>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

-8
View File
@@ -1,8 +0,0 @@
{
"redirects": [
{
"source": "/careers",
"destination": "https://boards.greenhouse.io/supabase"
}
]
}
+3 -1
View File
@@ -1,8 +1,10 @@
# PUBLIC
NEXT_PUBLIC_NEW_DOCS=true
NEXT_PUBLIC_SUPABASE_URL=http://localhost:54321
NEXT_PUBLIC_SUPABASE_ANON_KEY=
# PRIVATE
OPENAI_KEY=
SUPABASE_SERVICE_ROLE_KEY=
# Set IS_PLATFORM to true if you have the api keys and urls
NEXT_PUBLIC_IS_PLATFORM=false
+4 -3
View File
@@ -14,9 +14,10 @@ For a complete run-down on how all of our tools work together, see the main DEVE
[supabase.com/docs](https://supabase.com/docs) is a Next.JS site. You can get setup by following the same steps for all of our other Next.JS projects:
1. Follow the steps outlined in the Local Development section of the main [DEVELOPERS.md](https://github.com/supabase/supabase/blob/master/DEVELOPERS.md)
2. Start the local docs site by navigating to `/apps/docs` and running `npm run dev`
3. Visit http://localhost:3001/docs in your browser - don't forget to append the `/docs` to the end
4. Your local site should look exactly like [https://supabase.com/docs](https://supabase.com/docs)
2. If you work at Supabase, run `dev:secrets:pull` to pull down the internal environment variables. If you're a community member, create a `.env` file and add this line to it: `NEXT_PUBLIC_IS_PLATFORM=false`
3. Start the local docs site by navigating to `/apps/docs` and running `npm run dev`
4. Visit http://localhost:3001/docs in your browser - don't forget to append the `/docs` to the end
5. Your local site should look exactly like [https://supabase.com/docs](https://supabase.com/docs)
## Types of documentation
+16 -48
View File
@@ -1,53 +1,21 @@
import providers from '../data/authProviders'
import ButtonCard from './ButtonCard'
import { IconPanel } from 'ui'
import Link from 'next/link'
export default function AuthProviders({ type }: { type: string }) {
const filterProviders = providers.filter((item) => item.authType === type)
export default function AuthProviders() {
return (
<div className="grid md:grid-cols-12 gap-4">
{providers.map((x) => (
<div key={x.name} className="col-span-6">
<ButtonCard to={x.href} title={x.name}>
<div className="px-6 py-4">
<div className="flex justify-between">
<p className="mt-0">{x.name}</p>
<p className="mt-0">
{x.official ? (
<span className={`badge badge--official`}>Official</span>
) : (
<span className={`badge badge--unofficial`}>Unofficial</span>
)}
</p>
</div>
<div style={{ display: 'flex', flexDirection: 'column', gap: 5 }}>
<div
className="code-block"
style={{
width: '100%',
display: 'flex',
justifyContent: 'space-between',
fontSize: '0.7rem',
}}
>
<span>Platform:</span>
<span>{x.platform.toString()}</span>
</div>
<div
className="code-block"
style={{
width: '100%',
display: 'flex',
justifyContent: 'space-between',
fontSize: '0.7rem',
}}
>
<span>Self-Hosted:</span>
<span>{x.selfHosted.toString()}</span>
</div>
</div>
</div>
</ButtonCard>
</div>
))}
</div>
<>
<div className="grid grid-cols-12 gap-10 not-prose py-8">
{filterProviders.map((x) => (
<Link href={`${x.href}`} key={x.name} passHref>
<a className="col-span-6 lg:col-span-4 xl:col-span-3">
<IconPanel title={x.name} icon={x.logo} />
</a>
</Link>
))}
</div>
</>
)
}
+16 -11
View File
@@ -2,6 +2,7 @@ import { useTheme } from 'common/Providers'
import Image from 'next/image'
import { FC } from 'react'
import { createPortal } from 'react-dom'
import { IS_PLATFORM } from '~/lib/constants'
import clippyImageDark from '../../public/img/clippy-dark.png'
import clippyImage from '../../public/img/clippy.png'
import ClippyBubble from './ClippyBubble'
@@ -12,21 +13,25 @@ const Clippy: FC = () => {
const { isDarkMode } = useTheme()
const { isOpen, open, close } = useClippy()
return (
<>
{!isOpen && (
<div className="hidden md:flex flex-col items-end gap-1 md:gap-4">
{/* <>
if (!IS_PLATFORM) {
return null
} else {
return (
<>
{!isOpen && (
<div className="hidden md:flex flex-col items-end gap-1 md:gap-4">
{/* <>
<ClippyBubble onClick={open} />
<div className="w-[80px] lg:w-[120px] p-8 md:p-0">
<Image src={isDarkMode ? clippyImageDark : clippyImage} alt="Clippy" />
<Image src={isDarkMode ? clippyImageDark : clippyImage} alt="Clippy" />
</div>
</> */}
</div>
)}
{isOpen && createPortal(<ClippyModal onClose={close} />, document.body)}
</>
)
</div>
)}
{isOpen && createPortal(<ClippyModal onClose={close} />, document.body)}
</>
)
}
}
export default Clippy
+20 -17
View File
@@ -19,6 +19,7 @@ import {
Modal,
} from 'ui'
import components from '~/components'
import { IS_PLATFORM } from '~/lib/constants'
type Props = {
onClose?: () => void
@@ -34,10 +35,9 @@ const questions = [
]
function getEdgeFunctionUrl() {
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL.replace(/\/$/, '')
const isPlatform = supabaseUrl.match(/(supabase\.co)|(supabase\.in)/)
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL?.replace(/\/$/, '')
if (isPlatform) {
if (IS_PLATFORM) {
const [schemeAndProjectId, domain, tld] = supabaseUrl.split('.')
return `${schemeAndProjectId}.functions.${domain}.${tld}`
} else {
@@ -45,7 +45,7 @@ function getEdgeFunctionUrl() {
}
}
const edgeFunctionUrl = getEdgeFunctionUrl()
const edgeFunctionUrl = IS_PLATFORM ? getEdgeFunctionUrl() : undefined
const ClippyModal: FC<Props> = ({ onClose }) => {
const { isDarkMode } = useTheme()
@@ -165,19 +165,22 @@ const ClippyModal: FC<Props> = ({ onClose }) => {
<h2 className="text-sm text-scale-1100">Not sure where to start?</h2>
<ul className="text-sm mt-4 text-scale-1100 grid md:flex gap-4 flex-wrap max-w-3xl">
{questions.map((question) => (
<li>
<button
className="hover:bg-slate-400 hover:dark:bg-slate-400 px-4 py-2 bg-slate-300 dark:bg-slate-200 rounded-lg transition-colors"
onClick={() => {
setQuery(question)
handleConfirm(question)
}}
>
{question}
</button>
</li>
))}
{questions.map((question) => {
const key = question.replace(/\s+/g, '_')
return (
<li key={key}>
<button
className="hover:bg-slate-400 hover:dark:bg-slate-400 px-4 py-2 bg-slate-300 dark:bg-slate-200 rounded-lg transition-colors"
onClick={() => {
setQuery(question)
handleConfirm(question)
}}
>
{question}
</button>
</li>
)
})}
</ul>
</div>
</div>
@@ -25,9 +25,10 @@ interface Props {
* expected tocList format (text, link,level).
*
* In tsx files, we can generate this tocList directly. For these files, we don't
* need to parse the <a> and generate anchors
* need to parse the <a> and generate anchors. Custom anchors are used in tsx files.
* (see: /pages/reference/cli/config.tsx)
*/
const Heading: React.FC<Props> = ({ tag, parseAnchors = false, customAnchor, children }) => {
const Heading: React.FC<Props> = ({ tag, customAnchor, children }) => {
const HeadingTag = `${tag}` as any
const anchor = customAnchor ? customAnchor : getAnchor(children)
const link = `#${anchor}`
@@ -43,7 +44,7 @@ const Heading: React.FC<Props> = ({ tag, parseAnchors = false, customAnchor, chi
return (
<HeadingTag id={anchor} ref={ref} className="group scroll-mt-24">
{parseAnchors ? removeAnchor(children) : children}
{removeAnchor(children)}
{anchor && (
<a href={link} className="ml-2 opacity-0 group-hover:opacity-100 transition">
#
-35
View File
@@ -1,35 +0,0 @@
import React, { useState } from 'react'
import extensions from '../data/extensions.json'
export default function Extensions() {
const [filter, setFilter] = useState('')
return (
<>
<div className="mb-8 grid">
<label className="text-xs mb-2">Filter extensions</label>
<input
type="text"
className="border text-gray-200"
placeholder="Extension name"
onChange={(e) => setFilter(e.target.value)}
/>
</div>
<div className="grid sm:grid-cols-2 gap-4">
{extensions
.filter((x) => x.name.indexOf(filter) >= 0)
.map((extension) => (
<div className={' my-2 px-2'} key={extension.name}>
<div className="border rounded-sm p-4">
<h3 className="m-0">
<code className="text-sm">{extension.name}</code>
</h3>
<p className=" mt-4">
{extension.comment.charAt(0).toUpperCase() + extension.comment.slice(1)}
</p>
</div>
</div>
))}
</div>
</>
)
}
+134
View File
@@ -0,0 +1,134 @@
import Link from 'next/link'
import React, { useState } from 'react'
import { GlassPanel, IconLink, IconX, Input } from 'ui'
import extensions from '../data/extensions.json'
type extension = {
name: string
comment: string
tags: string[]
link?: string
}
function getUniqueTags(json: extension[]) {
const tags = []
for (const item of json) {
if (item.tags) {
tags.push(...item.tags)
}
}
return [...new Set(tags)]
}
export default function Extensions() {
const [searchTerm, setSearchTerm] = useState('')
const [filters, setFilters] = useState([])
const tags = getUniqueTags(extensions)
function handleChecked(tag) {
if (filters.includes(tag)) {
setFilters(filters.filter((x) => x !== tag))
} else {
setFilters([...filters, tag])
}
}
return (
<>
<div className="mb-8 grid">
<label className="mb-2 text-xs text-scale-1100">Search extensions</label>
<Input
type="text"
placeholder="Extension name"
onChange={(e) => setSearchTerm(e.target.value)}
/>
</div>
<div className="lg:grid lg:grid-cols-12">
<div className="col-span-3 not-prose">
<div className="lg:sticky top-24">
<h3 className="text-sm text-scale-1100">Filter</h3>
<ul className="mt-3 flex flex-wrap lg:grid gap-2 grow">
{tags.sort().map((tag) => (
<li key={tag}>
<label
htmlFor={tag}
className={`text-sm text-scale-1000 py-0.5 px-2 capitalize inline-block rounded-lg hover:bg-slate-400 hover:border-slate-400 cursor-pointer border ${
filters.includes(tag) ? 'bg-slate-400 ' : ''
}`}
>
<span className="flex items-center gap-1">
<input
type="checkbox"
className="sr-only"
id={tag}
name={tag}
value={tag}
onChange={() => handleChecked(tag)}
checked={filters.includes(tag)}
/>
{tag}
<span>{filters.includes(tag) && <IconX size={12} />}</span>
</span>
</label>
</li>
))}
</ul>
<p className="mt-2">
<button
type="reset"
className="text-xs hover:underline"
onClick={() => setFilters([])}
>
Reset
</button>
</p>
</div>
</div>
<div className="col-span-9 mt-4 lg:mt-0">
<div className="grid gap-4">
{extensions
.filter((x) => x.name.indexOf(searchTerm) >= 0)
.filter((x) =>
filters.length === 0 ? x : x.tags.some((item) => filters.includes(item))
)
.map((extension) => (
<Link passHref href={`/guides/database/extensions/${extension.name}`}>
<a target="_blank" className="no-underline">
<GlassPanel title={extension.name} background={false} key={extension.name}>
<p className="mt-4">
{extension.comment.charAt(0).toUpperCase() + extension.comment.slice(1)}
</p>
</GlassPanel>
</a>
</Link>
// <div className="my-2 px-2 relative" key={extension.name}>
// <div className="border rounded-sm p-4">
// <h3 className="m-0">
// <code className="text-sm">{extension.name}</code>
// </h3>
// <p className=" mt-4">
// {extension.comment.charAt(0).toUpperCase() + extension.comment.slice(1)}
// </p>
// {extension.link && (
// <Link href={extension.link}>
// <a
// target="_blank"
// className="text-xs no-underline absolute top-2 right-4 bg-slate-200 hover:bg-slate-400 transition-colors p-2 rounded-md"
// >
// <span>
// <IconLink size={14} className="" />
// </span>
// </a>
// </Link>
// )}
// </div>
// </div>
))}
</div>
</div>
</div>
</>
)
}
+19 -20
View File
@@ -1,34 +1,33 @@
import { FC, useEffect, useState } from 'react'
import createConfigCatClient from 'configcat-js'
// import createConfigCatClient from 'configcat-js'
import FlagContext from './FlagContext'
const FlagProvider: FC = ({ children }) => {
const [store, setStore] = useState({})
const { Provider } = FlagContext
useEffect(() => {
getFlags()
}, [])
// useEffect(() => {
// getFlags()
// }, [])
const getFlags = async () => {
const setFlagValues = async () => {
const flagValues = await client.getAllValuesAsync()
const flagStore: any = {}
// const getFlags = async () => {
// const setFlagValues = async () => {
// const flagValues = await client.getAllValuesAsync()
// const flagStore: any = {}
flagValues.forEach((item: any) => {
flagStore[item.settingKey] = item.settingValue
})
setStore(flagStore)
}
// flagValues.forEach((item: any) => {
// flagStore[item.settingKey] = item.settingValue
// })
// setStore(flagStore)
// }
const client = createConfigCatClient(process.env.NEXT_PUBLIC_CONFIGCAT_SDK_KEY ?? '', {
configChanged: setFlagValues,
pollIntervalSeconds: 600,
})
// const client = createConfigCatClient(process.env.NEXT_PUBLIC_CONFIGCAT_SDK_KEY ?? '', {
// configChanged: setFlagValues,
// pollIntervalSeconds: 600,
// })
await setFlagValues()
}
// await setFlagValues()
// }
return <Provider value={store}>{children}</Provider>
}
@@ -400,15 +400,40 @@ export const database = {
},
{ name: 'http: RESTful Client', url: '/guides/database/extensions/http', items: [] },
{
name: 'PGRoonga: Multilingual Full Text Search',
name: 'PGAudit: Postgres Auditing',
url: '/guides/database/extensions/pgaudit',
items: [],
},
{
name: 'pgjwt: JSON Web Tokens',
url: '/guides/database/extensions/pgjwt',
items: [],
},
{
name: 'PGroonga: Multilingual Full Text Search',
url: '/guides/database/extensions/pgroonga',
items: [],
},
{
name: 'pgRouting: Geospatial Routing',
url: '/guides/database/extensions/pgrouting',
items: [],
},
{
name: 'pg_cron: Job Scheduling',
url: '/guides/database/extensions/pgcron',
items: [],
},
{
name: 'pg_graphql: GraphQL Support',
url: '/guides/database/extensions/pg_graphql',
items: [],
},
{
name: 'pg_hashids: Short UIDs',
url: '/guides/database/extensions/pg_hashids',
items: [],
},
{
name: 'pg_jsonschema: JSON Schema Validation',
url: '/guides/database/extensions/pg_jsonschema',
@@ -419,6 +444,16 @@ export const database = {
url: '/guides/database/extensions/pgnet',
items: [],
},
{
name: 'pg_plan_filter: Restrict Total Cost',
url: '/guides/database/extensions/pg_plan_filter',
items: [],
},
{
name: 'pg_stat_monitor: Extended Query Performance Monitoring',
url: '/guides/database/extensions/pg_stat_monitor',
items: [],
},
{
name: 'pgvector: Embeddings and vector similarity',
url: '/guides/database/extensions/pgvector',
@@ -439,7 +474,27 @@ export const database = {
url: '/guides/database/extensions/postgis',
items: [],
},
{
name: 'pg-safeupdate: Required Where Clauses',
url: '/guides/database/extensions/pg-safeupdate',
items: [],
},
{
name: 'pgsodium: Encryption Features',
url: '/guides/database/extensions/pgsodium',
items: [],
},
{ name: 'pgTAP: Unit Testing', url: '/guides/database/extensions/pgtap', items: [] },
{
name: 'plpgsql_check: PL/pgSQL Linter',
url: '/guides/database/extensions/plpgsql_check',
items: [],
},
{
name: 'timescaledb: Time-series data',
url: '/guides/database/extensions/timescaledb',
items: [],
},
{
name: 'uuid-ossp: Unique Identifiers',
url: '/guides/database/extensions/uuid-ossp',
@@ -450,6 +505,11 @@ export const database = {
url: '/guides/database/extensions/rum',
items: [],
},
{
name: 'wrappers: 3rd Party Integrations',
url: '/guides/database/extensions/wrappers',
items: [],
},
],
},
{
@@ -658,6 +718,11 @@ export const resources = {
url: '/guides/resources/migrating-to-supabase/heroku',
items: [],
},
{
name: 'Render',
url: '/guides/resources/migrating-to-supabase/render',
items: [],
},
],
},
{
@@ -720,6 +785,7 @@ export const migrate = {
{ name: 'Firestore Data', url: '/guides/migrations/firestore-data', items: [] },
{ name: 'Firebase Storage', url: '/guides/migrations/firebase-storage', items: [] },
{ name: 'Heroku', url: '/guides/migrations/heroku', items: [] },
{ name: 'Render', url: '/guides/migrations/render', items: [] },
],
}
@@ -298,7 +298,7 @@ const NavigationMenu = () => {
id={'reference_self_hosting_realtime'}
active={isReference_Self_Hosting_Realtime}
commonSections={realtimeServerCommonSections}
lib="self-hosting-auth"
lib="self-hosting-realtime"
/>
</div>
)
@@ -11,6 +11,7 @@ import clippyImage from '../../../public/img/clippy.png'
import { getPageType } from '~/lib/helpers'
import { useClippy } from '~/components/Clippy/ClippyProvider'
import { IS_PLATFORM } from '~/lib/constants'
const TopNavBarRef: FC = () => {
const { isDarkMode, toggleTheme } = useTheme()
@@ -118,15 +119,17 @@ const TopNavBarRef: FC = () => {
</div>
</SearchButton>
<div className="flex cursor-pointer order-1 lg:order-2">
<Image
onClick={openClippy}
width={26}
height={29}
src={isDarkMode ? clippyImageDark : clippyImage}
alt="Clippy"
/>
</div>
{IS_PLATFORM && (
<div className="flex cursor-pointer order-1 lg:order-2">
<Image
onClick={openClippy}
width={26}
height={29}
src={isDarkMode ? clippyImageDark : clippyImage}
alt="Clippy"
/>
</div>
)}
</div>
<div className="hidden lg:flex grow items-center justify-end gap-3">
<Button
+38 -17
View File
@@ -1,172 +1,193 @@
const authProviders = [
{
name: 'Apple',
// logo: '/img/libraries/dart-icon.svg',
logo: '/docs/img/icons/apple-icon',
href: '/guides/auth/social-login/auth-apple',
official: true,
supporter: 'Supabase',
platform: true,
selfHosted: true,
authType: 'social',
},
{
name: 'Azure',
// logo: '/img/libraries/dart-icon.svg',
logo: '/docs/img/icons/microsoft-icon',
href: '/guides/auth/social-login/auth-azure',
official: false,
supporter: 'TBD',
platform: true,
selfHosted: true,
authType: 'social',
},
{
name: 'Bitbucket',
// logo: '/img/libraries/dart-icon.svg',
logo: '/docs/img/icons/bitbucket-icon',
href: '/guides/auth/social-login/auth-bitbucket',
official: true,
supporter: 'Supabase',
platform: true,
selfHosted: true,
authType: 'social',
},
{
name: 'Discord',
// logo: '/img/libraries/dart-icon.svg',
logo: '/docs/img/icons/discord-icon',
href: '/guides/auth/social-login/auth-discord',
official: true,
supporter: 'Supabase',
platform: true,
selfHosted: true,
authType: 'social',
},
{
name: 'Facebook',
// logo: '/img/libraries/dart-icon.svg',
logo: '/docs/img/icons/facebook-icon',
href: '/guides/auth/social-login/auth-facebook',
official: true,
supporter: 'Supabase',
platform: true,
selfHosted: true,
authType: 'social',
},
{
name: 'GitHub',
// logo: '/img/libraries/dart-icon.svg',
logo: '/docs/img/icons/github-icon',
href: '/guides/auth/social-login/auth-github',
official: true,
supporter: 'Supabase',
platform: true,
selfHosted: true,
authType: 'social',
},
{
name: 'GitLab',
// logo: '/img/libraries/dart-icon.svg',
logo: '/docs/img/icons/gitlab-icon',
href: '/guides/auth/social-login/auth-gitlab',
official: true,
supporter: 'Supabase',
platform: true,
selfHosted: true,
authType: 'social',
},
{
name: 'Google',
// logo: '/img/libraries/dart-icon.svg',
logo: '/docs/img/icons/google-icon',
href: '/guides/auth/social-login/auth-google',
official: true,
supporter: 'Supabase',
platform: true,
selfHosted: true,
authType: 'social',
},
{
name: 'Keycloak',
logo: '/docs/img/icons/keycloak-icon',
href: '/guides/auth/social-login/auth-keycloak',
official: true,
supporter: 'Supabase',
platform: true,
selfHosted: true,
authType: 'social',
},
{
name: 'LinkedIn',
// logo: '/img/libraries/dart-icon.svg',
logo: '/docs/img/icons/linkedin-icon',
href: '/guides/auth/social-login/auth-linkedin',
official: true,
supporter: 'Supabase',
platform: true,
selfHosted: true,
authType: 'social',
},
{
name: 'MessageBird',
// logo: '/img/libraries/dart-icon.svg',
logo: '/docs/img/icons/messagebird-icon',
href: '/guides/auth/phone-login/messagebird',
official: false,
supporter: 'MessageBird',
platform: true,
selfHosted: true,
authType: 'phone',
},
{
name: 'Notion',
// logo: '/img/libraries/notion-icon.svg',
logo: '/docs/img/icons/notion-icon',
href: '/guides/auth/social-login/auth-notion',
official: true,
supporter: 'Supabase',
platform: true,
selfHosted: true,
authType: 'social',
},
{
name: 'Slack',
// logo: '/img/libraries/dart-icon.svg',
logo: '/docs/img/icons/slack-icon',
href: '/guides/auth/social-login/auth-slack',
official: true,
supporter: 'Supabase',
platform: true,
selfHosted: true,
authType: 'social',
},
{
name: 'Spotify',
// logo: '/img/libraries/dart-icon.svg',
logo: '/docs/img/icons/spotify-icon',
href: '/guides/auth/social-login/auth-spotify',
official: true,
supporter: 'Supabase',
platform: true,
selfHosted: true,
authType: 'social',
},
{
name: 'Twitter',
// logo: '/img/libraries/dart-icon.svg',
logo: '/docs/img/icons/twitter-icon',
href: '/guides/auth/social-login/auth-twitter',
official: true,
supporter: 'Supabase',
platform: true,
selfHosted: true,
authType: 'social',
},
{
name: 'Twitch',
// logo: '/img/libraries/dart-icon.svg',
logo: '/docs/img/icons/twitch-icon',
href: '/guides/auth/social-login/auth-twitch',
official: true,
supporter: 'Supabase',
platform: true,
selfHosted: true,
authType: 'social',
},
{
name: 'Zoom',
// logo: '/img/libraries/dart-icon.svg',
logo: '/docs/img/icons/zoom-icon',
href: '/guides/auth/social-login/auth-zoom',
official: true,
supporter: 'Supabase',
platform: true,
selfHosted: true,
authType: 'social',
},
{
name: 'Twilio',
// logo: '/img/libraries/dart-icon.svg',
logo: '/docs/img/icons/twilio-icon',
href: '/guides/auth/phone-login/twilio',
official: true,
supporter: 'Supabase',
platform: true,
selfHosted: true,
authType: 'phone',
},
{
name: 'Vonage',
logo: '/docs/img/icons/vonage-icon',
href: '/guides/auth/phone-login/vonage',
official: false,
supporter: 'Supabase',
platform: true,
selfHosted: true,
authType: 'phone',
},
]
+277 -314
View File
@@ -1,499 +1,462 @@
[
{
"name": "address_standardizer",
"schema": null,
"default_version": "3.1.1",
"installed_version": null,
"comment": "Used to parse an address into constituent elements. Generally used to support geocoding address normalization step."
"comment": "Used to parse an address into constituent elements. Generally used to support geocoding address normalization step.",
"tags": ["Utility"],
"link": "http://supabase.com/docs/guides/extensions/etc/etc/etc"
},
{
"name": "address_standardizer-3",
"schema": null,
"default_version": "3.1.1",
"installed_version": null,
"comment": "Used to parse an address into constituent elements. Generally used to support geocoding address normalization step."
"comment": "Used to parse an address into constituent elements. Generally used to support geocoding address normalization step.",
"tags": ["Utility"]
},
{
"name": "address_standardizer_data_us",
"schema": null,
"default_version": "3.1.1",
"installed_version": null,
"comment": "Address Standardizer US dataset example"
"comment": "Address Standardizer US dataset example",
"tags": ["Dataset"]
},
{
"name": "address_standardizer_data_us-3",
"schema": null,
"default_version": "3.1.1",
"installed_version": null,
"comment": "Address Standardizer US dataset example"
"comment": "Address Standardizer US dataset example",
"tags": ["Dataset"]
},
{
"name": "adminpack",
"schema": null,
"default_version": "2.0",
"installed_version": null,
"comment": "administrative functions for PostgreSQL"
"comment": "administrative functions for PostgreSQL",
"tags": ["Admin", "Utility"]
},
{
"name": "amcheck",
"schema": null,
"default_version": "1.2",
"installed_version": null,
"comment": "functions for verifying relation integrity"
"comment": "functions for verifying relation integrity",
"tags": ["Admin", "Utility"]
},
{
"name": "autoinc",
"schema": null,
"default_version": "1.0",
"installed_version": null,
"comment": "functions for autoincrementing fields"
"comment": "functions for autoincrementing fields",
"tags": ["Utility"]
},
{
"name": "bloom",
"schema": null,
"default_version": "1.0",
"installed_version": null,
"comment": "bloom access method - signature file based index"
"comment": "bloom access method - signature file based index",
"tags": ["Index"]
},
{
"name": "btree_gin",
"schema": null,
"default_version": "1.3",
"installed_version": null,
"comment": "support for indexing common datatypes in GIN"
"comment": "support for indexing common datatypes in GIN",
"tags": ["Index"]
},
{
"name": "btree_gist",
"schema": null,
"default_version": "1.5",
"installed_version": null,
"comment": "support for indexing common datatypes in GiST"
"comment": "support for indexing common datatypes in GiST",
"tags": ["Index"]
},
{
"name": "citext",
"schema": null,
"default_version": "1.6",
"installed_version": null,
"comment": "data type for case-insensitive character strings"
"comment": "data type for case-insensitive character strings",
"tags": ["Data Type"]
},
{
"name": "cube",
"schema": null,
"default_version": "1.4",
"installed_version": null,
"comment": "data type for multidimensional cubes"
"comment": "data type for multidimensional cubes",
"tags": ["Data Type"]
},
{
"name": "dblink",
"schema": null,
"default_version": "1.2",
"installed_version": null,
"comment": "connect to other PostgreSQL databases from within a database"
"comment": "connect to other PostgreSQL databases from within a database",
"tags": ["Admin", "Utility"]
},
{
"name": "dict_int",
"schema": null,
"default_version": "1.0",
"installed_version": null,
"comment": "text search dictionary template for integers"
"comment": "text search dictionary template for integers",
"tags": ["Search"]
},
{
"name": "dict_xsyn",
"schema": null,
"default_version": "1.0",
"installed_version": null,
"comment": "text search dictionary template for extended synonym processing"
"comment": "text search dictionary template for extended synonym processing",
"tags": ["Search"]
},
{
"name": "earthdistance",
"schema": null,
"default_version": "1.1",
"installed_version": null,
"comment": "calculate great-circle distances on the surface of the Earth"
"comment": "calculate great-circle distances on the surface of the Earth",
"tags": ["Geo", "Utility"]
},
{
"name": "file_fdw",
"schema": null,
"default_version": "1.0",
"installed_version": null,
"comment": "foreign-data wrapper for flat file access"
"comment": "foreign-data wrapper for flat file access",
"tags": ["Admin", "Utility"]
},
{
"name": "fuzzystrmatch",
"schema": null,
"default_version": "1.1",
"installed_version": null,
"comment": "determine similarities and distance between strings"
"comment": "determine similarities and distance between strings",
"tags": ["Search"]
},
{
"name": "hstore",
"schema": null,
"default_version": "1.6",
"installed_version": null,
"comment": "data type for storing sets of (key, value) pairs"
"comment": "data type for storing sets of (key, value) pairs",
"tags": ["Data Type"]
},
{
"name": "hypopg",
"comment": "Hypothetical indexes for PostgreSQL",
"link": "https://supabase.com/docs/guides/database/extensions/hypopg",
"tags": ["Admin", "Index"]
},
{
"name": "http",
"schema": "extensions",
"default_version": "1.3",
"installed_version": "1.3",
"comment": "HTTP client for PostgreSQL, allows web page retrieval inside the database."
"comment": "HTTP client for PostgreSQL, allows web page retrieval inside the database.",
"link": "https://supabase.com/docs/guides/database/extensions/http",
"tags": ["Utility"]
},
{
"name": "insert_username",
"schema": null,
"default_version": "1.0",
"installed_version": null,
"comment": "functions for tracking who changed a table"
"comment": "functions for tracking who changed a table",
"tags": ["Audit", "Utility"]
},
{
"name": "old_snapshot",
"comment": "utilities in support of old_snapshot_threshold",
"tags": ["Admin", "Utility"]
},
{
"name": "intagg",
"schema": null,
"default_version": "1.1",
"installed_version": null,
"comment": "integer aggregator and enumerator (obsolete)"
"comment": "integer aggregator and enumerator (obsolete)",
"tags": ["Utility"]
},
{
"name": "intarray",
"schema": null,
"default_version": "1.2",
"installed_version": null,
"comment": "functions, operators, and index support for 1-D arrays of integers"
"comment": "functions, operators, and index support for 1-D arrays of integers",
"tags": ["Utility"]
},
{
"name": "isn",
"schema": null,
"default_version": "1.2",
"installed_version": null,
"comment": "data types for international product numbering standards"
"comment": "data types for international product numbering standards",
"tags": ["Data Type"]
},
{
"name": "lo",
"schema": null,
"default_version": "1.1",
"installed_version": null,
"comment": "Large Object maintenance"
"comment": "Large Object maintenance",
"tags": ["Data Type"]
},
{
"name": "ltree",
"schema": null,
"default_version": "1.1",
"installed_version": null,
"comment": "data type for hierarchical tree-like structures"
"comment": "data type for hierarchical tree-like structures",
"tags": ["Data Type"]
},
{
"name": "moddatetime",
"schema": null,
"default_version": "1.0",
"installed_version": null,
"comment": "functions for tracking last modification time"
"comment": "functions for tracking last modification time",
"tags": ["Audit", "Utility"]
},
{
"name": "pageinspect",
"schema": null,
"default_version": "1.7",
"installed_version": null,
"comment": "inspect the contents of database pages at a low level"
"comment": "inspect the contents of database pages at a low level",
"tags": ["Admin", "Utility"]
},
{
"name": "pg_buffercache",
"schema": null,
"default_version": "1.3",
"installed_version": null,
"comment": "examine the shared buffer cache"
"comment": "examine the shared buffer cache",
"tags": ["Admin", "Utility"]
},
{
"name": "pg_cron",
"schema": "extensions",
"default_version": "1.3",
"installed_version": "1.3",
"comment": "Job scheduler for PostgreSQL"
"comment": "Job scheduler for PostgreSQL",
"link": "https://supabase.com/docs/guides/database/extensions/pgcron",
"tags": ["Utility"]
},
{
"name": "pg_freespacemap",
"schema": null,
"default_version": "1.2",
"installed_version": null,
"comment": "examine the free space map (FSM)"
"comment": "examine the free space map (FSM)",
"tags": ["Admin", "Utility"]
},
{
"name": "pg_graphql",
"comment": "pg_graphql: GraphQL support",
"link": "https://supabase.com/docs/guides/database/extensions/pg_graphql",
"tags": ["Utility"]
},
{
"name": "pg_hashids",
"comment": "pg_hashids",
"link": "https://supabase.com/docs/guides/database/extensions/pg_hashids",
"tags": ["Utility"]
},
{
"name": "pg_jsonschema",
"comment": "pg_jsonschema",
"link": "https://supabase.com/docs/guides/database/extensions/pg_jsonschema",
"tags": ["Utility"]
},
{
"name": "pg_net",
"comment": "Async HTTP",
"link": "https://supabase.com/docs/guides/database/extensions/pgnet",
"tags": ["Utility", "Notifications"]
},
{
"name": "pg_prewarm",
"schema": null,
"default_version": "1.2",
"installed_version": null,
"comment": "prewarm relation data"
"comment": "prewarm relation data",
"tags": ["Admin", "Utility"]
},
{
"name": "pg_stat_monitor",
"comment": "The pg_stat_monitor is a PostgreSQL Query Performance Monitoring tool, based on PostgreSQL contrib module pg_stat_statements. pg_stat_monitor provides aggregated statistics, client information, plan details including plan, and histogram information.",
"link": "https://supabase.com/docs/guides/database/extensions/pg_stat_monitor",
"tags": ["Utility"]
},
{
"name": "pg_stat_statements",
"schema": null,
"default_version": "1.7",
"installed_version": null,
"comment": "track execution statistics of all SQL statements executed"
"comment": "track execution statistics of all SQL statements executed",
"link": "https://supabase.com/docs/guides/database/extensions/pg_stat_statements",
"tags": ["Admin", "Utility"]
},
{
"name": "pg_surgery",
"comment": "extension to perform surgery on a damaged relation",
"tags": ["Admin", "Utility"]
},
{
"name": "pg_trgm",
"schema": null,
"default_version": "1.4",
"installed_version": null,
"comment": "text similarity measurement and index searching based on trigrams"
"comment": "text similarity measurement and index searching based on trigrams",
"tags": ["Search"]
},
{
"name": "pg_visibility",
"schema": null,
"default_version": "1.2",
"installed_version": null,
"comment": "examine the visibility map (VM) and page-level visibility info"
"comment": "examine the visibility map (VM) and page-level visibility info",
"tags": ["Admin", "Utility"]
},
{
"name": "pgaudit",
"schema": null,
"default_version": "1.4",
"installed_version": null,
"comment": "provides auditing functionality"
"comment": "provides auditing functionality",
"link": "https://supabase.com/docs/guides/database/extensions/pgaudit",
"tags": ["Audit", "Utility"]
},
{
"name": "pg_walinspect",
"comment": "functions to inspect contents of PostgreSQL Write-Ahead Log",
"tags": ["Admin", "Utility"]
},
{
"name": "pgcrypto",
"schema": "extensions",
"default_version": "1.3",
"installed_version": "1.3",
"comment": "cryptographic functions"
"comment": "cryptographic functions",
"tags": ["Utility", "Cryptography"]
},
{
"name": "pgjwt",
"schema": "extensions",
"default_version": "0.1.0",
"installed_version": "0.1.0",
"comment": "JSON Web Token API for Postgresql"
"comment": "JSON Web Token API for Postgresql",
"link": "https://supabase.com/docs/guides/database/extensions/pgjwt",
"tags": ["Utility", "Cryptography"]
},
{
"name": "pgroonga",
"comment": "Super fast and all languages supported full text search index based on Groonga",
"link": "https://supabase.com/docs/guides/database/extensions/pgroonga",
"tags": ["Search"]
},
{
"name": "pgroonga_database",
"comment": "PGroonga database management module",
"tags": ["Admin"]
},
{
"name": "pgrouting",
"comment": "pgRouting Extension",
"link": "https://supabase.com/docs/guides/database/extensions/pgrouting",
"tags": ["Geo", "Utility"]
},
{
"name": "pgrowlocks",
"schema": null,
"default_version": "1.2",
"installed_version": null,
"comment": "show row-level locking information"
"comment": "show row-level locking information",
"tags": ["Admin", "Utility"]
},
{
"name": "pgsodium",
"comment": "Postgres extension for libsodium functions",
"link": "https://supabase.com/docs/guides/database/extensions/pgsodium",
"tags": ["Utility", "Cryptography"]
},
{
"name": "pgstattuple",
"schema": null,
"default_version": "1.5",
"installed_version": null,
"comment": "show tuple-level statistics"
"comment": "show tuple-level statistics",
"tags": ["Admin", "Utility"]
},
{
"name": "pgtap",
"schema": null,
"default_version": "1.1.0",
"installed_version": null,
"comment": "Unit testing for PostgreSQL"
"comment": "Unit testing for PostgreSQL",
"link": "https://supabase.com/docs/guides/database/extensions/pgtap",
"tags": ["Utility", "Testing"]
},
{
"name": "plcoffee",
"schema": null,
"default_version": "3.0alpha",
"installed_version": null,
"comment": "PL/CoffeeScript (v8) trusted procedural language"
"comment": "PL/CoffeeScript (v8) trusted procedural language",
"tags": ["Language"]
},
{
"name": "pljava",
"schema": null,
"default_version": "1.6.0",
"installed_version": null,
"comment": "PL/Java procedural language (https://tada.github.io/pljava/)"
"comment": "PL/Java procedural language (https://tada.github.io/pljava/)",
"tags": ["Language"]
},
{
"name": "plls",
"schema": null,
"default_version": "3.0alpha",
"installed_version": null,
"comment": "PL/LiveScript (v8) trusted procedural language"
"comment": "PL/LiveScript (v8) trusted procedural language",
"tags": ["Language"]
},
{
"name": "plpgsql",
"schema": "pg_catalog",
"default_version": "1.0",
"installed_version": "1.0",
"comment": "PL/pgSQL procedural language"
"comment": "PL/pgSQL procedural language",
"tags": ["Language"]
},
{
"name": "plpgsql_check",
"schema": null,
"default_version": "1.11",
"installed_version": null,
"comment": "extended check for plpgsql functions"
"comment": "extended check for plpgsql functions",
"href": "https://supabase.com/docs/guides/database/extensions/plpgsql_check",
"tags": ["Utility", "Testing"]
},
{
"name": "plv8",
"schema": null,
"default_version": "3.0alpha",
"installed_version": null,
"comment": "PL/JavaScript (v8) trusted procedural language"
"comment": "PL/JavaScript (v8) trusted procedural language",
"link": "http://localhost:3001/docs/guides/database/extensions/plv8",
"tags": ["Language"]
},
{
"name": "postgis",
"schema": null,
"default_version": "3.1.1",
"installed_version": null,
"comment": "PostGIS geometry and geography spatial types and functions"
"comment": "PostGIS geometry and geography spatial types and functions",
"link": "https://supabase.com/docs/guides/database/extensions/postgis",
"tags": ["Geo"]
},
{
"name": "postgis-3",
"schema": null,
"default_version": "3.1.1",
"installed_version": null,
"comment": "PostGIS geometry and geography spatial types and functions"
"comment": "PostGIS geometry and geography spatial types and functions",
"tags": ["Geo"]
},
{
"name": "postgis_raster",
"schema": null,
"default_version": "3.1.1",
"installed_version": null,
"comment": "PostGIS raster types and functions"
"comment": "PostGIS raster types and functions",
"tags": ["Geo"]
},
{
"name": "postgis_raster-3",
"schema": null,
"default_version": "3.1.1",
"installed_version": null,
"comment": "PostGIS raster types and functions"
"comment": "PostGIS raster types and functions",
"tags": ["Geo"]
},
{
"name": "postgis_sfcgal",
"schema": null,
"default_version": "3.1.1",
"installed_version": null,
"comment": "PostGIS SFCGAL functions"
"comment": "PostGIS SFCGAL functions",
"tags": ["Geo"]
},
{
"name": "postgis_sfcgal-3",
"schema": null,
"default_version": "3.1.1",
"installed_version": null,
"comment": "PostGIS SFCGAL functions"
"comment": "PostGIS SFCGAL functions",
"tags": ["Geo"]
},
{
"name": "postgis_tiger_geocoder",
"schema": null,
"default_version": "3.1.1",
"installed_version": null,
"comment": "PostGIS tiger geocoder and reverse geocoder"
"comment": "PostGIS tiger geocoder and reverse geocoder",
"tags": ["Geo"]
},
{
"name": "postgis_tiger_geocoder-3",
"schema": null,
"default_version": "3.1.1",
"installed_version": null,
"comment": "PostGIS tiger geocoder and reverse geocoder"
"comment": "PostGIS tiger geocoder and reverse geocoder",
"tags": ["Geo"]
},
{
"name": "postgis_topology",
"schema": null,
"default_version": "3.1.1",
"installed_version": null,
"comment": "PostGIS topology spatial types and functions"
"comment": "PostGIS topology spatial types and functions",
"tags": ["Geo"]
},
{
"name": "postgis_topology-3",
"schema": null,
"default_version": "3.1.1",
"installed_version": null,
"comment": "PostGIS topology spatial types and functions"
"comment": "PostGIS topology spatial types and functions",
"tags": ["Geo"]
},
{
"name": "postgres_fdw",
"schema": null,
"default_version": "1.0",
"installed_version": null,
"comment": "foreign-data wrapper for remote PostgreSQL servers"
"comment": "foreign-data wrapper for remote PostgreSQL servers",
"tags": ["Admin"]
},
{
"name": "refint",
"schema": null,
"default_version": "1.0",
"installed_version": null,
"comment": "functions for implementing referential integrity (obsolete)"
},
{
"name": "seg",
"schema": null,
"default_version": "1.3",
"installed_version": null,
"comment": "data type for representing line segments or floating-point intervals"
},
{
"name": "sslinfo",
"schema": null,
"default_version": "1.2",
"installed_version": null,
"comment": "information about SSL certificates"
},
{
"name": "tablefunc",
"schema": null,
"default_version": "1.0",
"installed_version": null,
"comment": "functions that manipulate whole tables, including crosstab"
},
{
"name": "tcn",
"schema": null,
"default_version": "1.0",
"installed_version": null,
"comment": "Triggered change notifications"
},
{
"name": "tsm_system_rows",
"schema": null,
"default_version": "1.0",
"installed_version": null,
"comment": "TABLESAMPLE method which accepts number of rows as a limit"
},
{
"name": "tsm_system_time",
"schema": null,
"default_version": "1.0",
"installed_version": null,
"comment": "TABLESAMPLE method which accepts time in milliseconds as a limit"
},
{
"name": "unaccent",
"schema": null,
"default_version": "1.1",
"installed_version": null,
"comment": "text search dictionary that removes accents"
},
{
"name": "uuid-ossp",
"schema": "extensions",
"default_version": "1.1",
"installed_version": "1.1",
"comment": "generate universally unique identifiers (UUIDs)"
},
{
"name": "vector",
"schema": "extensions",
"default_version": "0.4.0",
"installed_version": null,
"comment": "vector data type with similarity search"
},
{
"name": "xml2",
"schema": null,
"default_version": "1.1",
"installed_version": null,
"comment": "XPath querying and XSLT"
"comment": "functions for implementing referential integrity (obsolete)",
"tags": ["Utility"]
},
{
"name": "rum",
"schema": "extensions",
"default_version": "1.3.13",
"installed_version": "1.3.13",
"comment": "GIN-like index for text search"
"comment": "GIN-like index for text search",
"link": "https://supabase.com/docs/guides/database/extensions/rum",
"tags": ["Index", "Search"]
},
{
"name": "seg",
"comment": "data type for representing line segments or floating-point intervals",
"tags": ["Utility"]
},
{
"name": "sslinfo",
"comment": "information about SSL certificates",
"tags": ["Admin", "Utility"]
},
{
"name": "supautils",
"comment": "Supabase standard library",
"tags": ["Utility"]
},
{
"name": "tablefunc",
"comment": "functions that manipulate whole tables, including crosstab",
"tags": ["Utility"]
},
{
"name": "tcn",
"comment": "Triggered change notifications",
"tags": ["Utility", "Notifications"]
},
{
"name": "timescaledb",
"comment": "Enables scalable inserts and complex queries for time-series data",
"link": "https://supabase.com/docs/guides/database/extensions/timescaledb",
"tags": ["Time Series", "Data Type", "Utility"]
},
{
"name": "tsm_system_rows",
"comment": "TABLESAMPLE method which accepts number of rows as a limit",
"tags": ["Utility"]
},
{
"name": "tsm_system_time",
"comment": "TABLESAMPLE method which accepts time in milliseconds as a limit",
"tags": ["Utility"]
},
{
"name": "unaccent",
"comment": "text search dictionary that removes accents",
"tags": ["Search"]
},
{
"name": "uuid-ossp",
"comment": "generate universally unique identifiers (UUIDs)",
"link": "https://supabase.com/docs/guides/database/extensions/uuid-ossp",
"tags": ["Utility", "Data Type"]
},
{
"name": "pgvector",
"comment": "vector data type with similarity search",
"link": "https://supabase.com/docs/guides/database/extensions/pgvector",
"tags": ["AI", "Data Type", "Search"]
},
{
"name": "pg_repack",
"schema": "extensions",
"default_version": "1.4.8",
"installed_version": "1.4.8",
"comment": "optimize physical storage and remove bloat from tables and indexes"
"comment": "Optimize physical storage and remove bloat from tables and indexes",
"link": "https://supabase.com/docs/guides/database/extensions/pgrepack",
"tags": ["Admin", "Utility"]
},
{
"name": "wrappers",
"comment": "Foreign data wrappers developed by Supabase",
"link": "https://supabase.com/docs/guides/database/extensions/wrappers",
"tags": ["Admin", "Utility"]
},
{
"name": "xml2",
"comment": "XPath querying and XSLT",
"tags": ["Utility"]
}
]
+35
View File
@@ -0,0 +1,35 @@
// for internal supabase use only
const fs = require('fs/promises')
const AWS = require('aws-sdk')
const secretName = 'local/docs'
const region = 'ap-southeast-2'
const getSecrets = async (name, region) => {
try {
AWS.config.update({ region })
const secretsmanager = new AWS.SecretsManager()
const data = await secretsmanager
.getSecretValue({
SecretId: name,
})
.promise()
if (!data.SecretString) {
throw new Error('Secrets not found')
}
return JSON.parse(data.SecretString)
} catch (err) {
console.log('Error getting secrets', err)
}
}
// gets secrets from secrets manager and writes it to .env.local file
getSecrets(secretName, region).then(async (secrets) => {
let secretContent = ''
for (const [secretKey, secretValue] of Object.entries(secrets)) {
secretContent += `${secretKey}="${secretValue}"\n`
}
await fs.writeFile('.env.local', secretContent.trim())
})
+2 -1
View File
@@ -10,6 +10,7 @@ import { memo, useEffect } from 'react'
import Clippy from '~/components/Clippy/Clippy'
import Footer from '~/components/Navigation/Footer'
import { menuState, useMenuLevelId, useMenuMobileOpen } from '~/hooks/useMenuState'
import { IS_PLATFORM } from '~/lib/constants'
const levelsData = {
home: {
@@ -340,7 +341,7 @@ const SiteLayout = ({ children }) => {
<MobileMenuBackdrop />
</Container>
<div className=" absolute right-4 md:right-12 bottom-8 z-[300]">
<Clippy />
{IS_PLATFORM && <Clippy />}
</div>
</div>
</main>
+1
View File
@@ -0,0 +1 @@
export const IS_PLATFORM = process.env.NEXT_PUBLIC_IS_PLATFORM === 'true'
+1
View File
@@ -53,6 +53,7 @@ const nextConfig = {
'github.com',
'user-images.githubusercontent.com',
'raw.githubusercontent.com',
'weweb-changelog.ghost.io',
],
},
experimental: {
+1
View File
@@ -4,6 +4,7 @@
"private": true,
"scripts": {
"dev": "next dev --port 3001",
"dev:secrets:pull": "AWS_PROFILE=supabase-dev node internals/getSecrets.js",
"build": "npm run generate:all && next build",
"start": "next start",
"lint": "next lint",
+17 -3
View File
@@ -10,6 +10,7 @@ import { SearchProvider } from '~/components/DocSearch'
import Favicons from '~/components/Favicons'
import SiteLayout from '~/layouts/SiteLayout'
import { post } from '~/lib/fetchWrappers'
import { IS_PLATFORM } from '~/lib/constants'
import '../styles/algolia-search.scss'
import '../styles/ch.scss'
import '../styles/docsearch.scss'
@@ -19,7 +20,8 @@ import '../styles/prism-okaidia.scss'
function MyApp({ Component, pageProps }: AppPropsWithLayout) {
const router = useRouter()
const [supabase] = useState(() => createBrowserSupabaseClient())
const [supabase] = useState(() => (IS_PLATFORM ? createBrowserSupabaseClient() : undefined))
function telemetry(route: string) {
return post(`https://api.supabase.io/platform/telemetry/page`, {
@@ -85,7 +87,19 @@ function MyApp({ Component, pageProps }: AppPropsWithLayout) {
cardType: 'summary_large_image',
}}
/>
<SessionContextProvider supabaseClient={supabase}>
{IS_PLATFORM ? (
<SessionContextProvider supabaseClient={supabase}>
<ThemeProvider>
<SearchProvider>
<ClippyProvider>
<SiteLayout>
<Component {...pageProps} />
</SiteLayout>
</ClippyProvider>
</SearchProvider>
</ThemeProvider>
</SessionContextProvider>
) : (
<ThemeProvider>
<SearchProvider>
<ClippyProvider>
@@ -95,7 +109,7 @@ function MyApp({ Component, pageProps }: AppPropsWithLayout) {
</ClippyProvider>
</SearchProvider>
</ThemeProvider>
</SessionContextProvider>
)}
</>
)
}
@@ -257,7 +257,7 @@ Wrap an Action to check that the user has a valid session. If they're not logged
```ts title=src/routes/posts/+page.server.ts
import type { Actions } from './$types'
import { getSupabase } from '@supabase/auth-helpers-sveltekit'
import { error, invalid } from '@sveltejs/kit'
import { error, fail } from '@sveltejs/kit'
export const actions: Actions = {
createPost: async (event) => {
@@ -276,7 +276,7 @@ export const actions: Actions = {
.insert({ content })
if (createPostError) {
return invalid(500, {
return fail(500, {
supabaseErrorMessage: createPostError.message,
})
}
@@ -293,7 +293,7 @@ If you try to submit a form with the action `?/createPost` without a valid sessi
```ts
import type { Actions } from './$types'
import { invalid, redirect } from '@sveltejs/kit'
import { fail, redirect } from '@sveltejs/kit'
import { getSupabase } from '@supabase/auth-helpers-sveltekit'
import { AuthApiError } from '@supabase/supabase-js'
@@ -313,14 +313,14 @@ export const actions: Actions = {
if (error) {
if (error instanceof AuthApiError && error.status === 400) {
return invalid(400, {
return fail(400, {
error: 'Invalid credentials.',
values: {
email,
},
})
}
return invalid(500, {
return fail(500, {
error: 'Server error. Try again later.',
values: {
email,
@@ -87,6 +87,32 @@ If you need to fetch a full list of user profiles, we supply a `service_key` whi
Make sure you _NEVER_ expose this publicly. But it can be used on the server-side to fetch all of the profiles.
## Accessing User Metadata
You can assign metadata to users on sign up:
```js
const { data, error } = await supabase.auth.signUp({
email: 'example@email.com',
password: 'example-password',
options: {
data: {
first_name: 'John',
age: 27,
},
},
})
```
User metadata is stored on the `raw_user_meta_data` column of the `auth.users` table. To view the metadata:
```js
const {
data: { user },
} = await supabase.auth.getUser()
let metadata = user.user_metadata
```
## Advanced techniques
### Using triggers
+10 -2
View File
@@ -44,13 +44,21 @@ You can authenticate your users in several ways:
We provide a suite of Providers and login methods, as well as [Auth helpers](/docs/guides/auth/auth-helpers/).
#### Social Auth
<div className="container" style={{ padding: 0 }}>
<AuthProviders />
<AuthProviders type="social" />
</div>
#### Phone Auth
<div className="container" style={{ padding: 0 }}>
<AuthProviders type="phone" />
</div>
### Configure third-party providers
You can enable third-party providers with the click of a button by navigating to Authentication > Settings > Auth Providers and inputting your `Client ID` and `Secret` for each.
You can enable third-party providers with the click of a button by navigating to Authentication > Providers > Auth Providers and inputting your `Client ID` and `Secret` for each.
![OAuth Logins.](/docs/img/supabase-oauth-logins.png)
+6 -6
View File
@@ -209,12 +209,12 @@ curl '<SUPABASE_URL>/rest/v1/todos' \
</TabPanel>
</Tabs>
JS Reference: [select()](../reference/javascript/select),
[insert()](../reference/javascript/insert),
[update()](../reference/javascript/update),
[upsert()](../reference/javascript/upsert),
[delete()](../reference/javascript/delete),
[rpc()](../reference/javascript/rpc) (call Postgres functions).
JS Reference: [select()](/docs/reference/javascript/select),
[insert()](/docs/reference/javascript/insert),
[update()](/docs/reference/javascript/update),
[upsert()](/docs/reference/javascript/upsert),
[delete()](/docs/reference/javascript/delete),
[rpc()](/docs/reference/javascript/rpc) (call Postgres functions).
### GraphQL API
+6 -12
View File
@@ -23,24 +23,18 @@ Supabase has pre-installed some of the most useful open source extensions.
2. Click **Extensions** in the sidebar.
3. Enable or disable an extension.
<video width="99%" muted playsInline controls={true}>
<source
src="https://xguihxuzqibwxjnimxev.supabase.co/storage/v1/object/public/videos/docs/toggle-extensions.mp4"
type="video/mp4"
muted
playsInline
/>
</video>
</TabPanel>
<TabPanel id="sql" label="SQL">
```sql
-- Example: enable the "pgtap" extension and ensure it is installed
create extension pgtap with schema extensions;
-- Example: enable the "pgtap" extension and ensure it is installed
create extension pgtap
with
schema extensions;
-- Example: disable the "pgtap" extension
drop extension pgtap;
drop
extension pgtap;
```
Even though the SQL code is `create extension`, this is the equivalent of "enabling the extension".
@@ -63,7 +63,7 @@ drop extension if exists http;
Even though the SQL code is `create extension`, this is the equivalent of "enabling the extension".
To disable an extension, call `drop extension`.
It's good practice to create the extension within a separate schema (like `extensions`) to keep your database clean.
It's good practice to create the extension within a separate schema (like `extensions`) to keep the `public` schema clean.
</TabPanel>
</Tabs>
@@ -7,11 +7,10 @@ export const meta = {
}
`HypoPG` is PostgreSQL extension for creating hypothetical/virtual indexes. HypoPG allows users to rapidly create hypothetical/virtual indexes that have no resource cost (CPU, disk, memory) that are visible to the PostgreSQL query planner.
That allows users to quickly search for an index to improve a slow query without waiting for them to build.
## Usage
The motivation for HypoPG is to allow users to quickly search for an index to improve a slow query without consuming server resources or waiting for them to build.
### Enable the extension
## Enable the extension
<Tabs
scrollable
@@ -40,14 +39,14 @@ drop extension if exists hypopg;
Even though the SQL code is `create extension`, this is the equivalent of "enabling the extension".
To disable an extension you can call `drop extension`.
It's good practice to create the extension within a separate schema (like `extensions`) to keep your database clean.
It's good practice to create the extension within a separate schema (like `extensions`) to keep the `public` schema clean.
</TabPanel>
</Tabs>
### Speeding up a query
Given the following table and a simple query to select from the table by id:
Given the following table and a simple query to select from the table by `id`:
{/* prettier-ignore */}
```sql
@@ -0,0 +1,60 @@
import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'pg-safeupdate',
title: 'pg-safeupdate: Required Where Clauses',
description: 'Requires a where clause for update and delete',
}
[pg-safeupdate](https://github.com/eradman/pg-safeupdate) is a PostgreSQL extension designed to prevent users from accidentally updating or deleting too many records in a single statement by requiring a "where" clause in all update and delete statements.
The `pg-safeupdate` extension is a useful tool for protecting data integrity and preventing accidental data loss. Without it, a user could accidentally execute an update or delete statement that affects all records in a table. With `pg-safeupdate`, users are required to be more deliberate in their update and delete statements, which reduces the risk of significant error.
## Enable the extension
`pg-safeupdate` can be enabled on a per connection basis:
{/* prettier-ignore */}
```sql
load 'safeupdate';
```
or for all connections:
{/* prettier-ignore */}
```sql
alter database some_db set session_preload_libraries = 'safeupdate';
```
## Usage
Let's take a look at an example to see how pg-safeupdate works. Suppose we have a table called `employees` with the following columns: `id`, `name`, `department`, and `date_of_birth`. We want to update the `date_of_birth` for a specific employee with the `id` of 12345. Here is what the query would look like if we forgot to add a "where" clause:
{/* prettier-ignore */}
```sql
load 'safeupdate';
update employees set date_of_birth = '1987-01-28';
```
This query updates the `date_of_birth` for all employees to 1987-01-28, which is not what we intended. With `pg-safeupdate` enabled, we receive an error message prompting us to add a "where" clause to the query:
{/* prettier-ignore */}
```sql
ERROR: UPDATE requires a WHERE clause
```
We would then update our query to include a "where" clause specifying the employee with the `id` of 12345:
{/* prettier-ignore */}
```sql
update employees set date_of_birth = '1987-01-28' where id = 12345;
```
## Resources
- Official [pg-safeupdate documentation](https://github.com/eradman/pg-safeupdate)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page
@@ -0,0 +1,116 @@
import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'pg_graphql',
title: 'pg_graphql: GraphQL for PostgreSQL',
description: 'A GraphQL Interface for PostgreSQL',
}
[pg_graphql](https://supabase.github.io/pg_graphql/) is PostgreSQL extension for interacting with the database using [GraphQL](https://graphql.org) instead of SQL.
The extension reflects a GraphQL schema from the existing SQL schema and exposes it through a SQL function, `graphql.resolve(...)`. This enables any programming language that can connect to PostgreSQL to query the database via GraphQL with no additional servers, processes, or libraries.
The `pg_graphql` resolve method is designed to interop with [PostgREST](https://postgrest.org/en/stable/index.html), the tool that underpins the Supabase API, such that the `graphql.resolve` function can be called via RPC to safely and performantly expose the GraphQL API over HTTP/S.
For more information about how the SQL schema is reflected into a GraphQL schema, see the [pg_graphql API docs](https://supabase.github.io/pg_graphql/api/).
## Enable the extension
<Tabs
scrollable
size="small"
type="underlined"
defaultActiveId="dashboard"
>
<TabPanel id="dashboard" label="Dashboard">
1. Go to the [Database](https://app.supabase.com/project/_/database/tables) page in the Dashboard.
2. Click on **Extensions** in the sidebar.
3. Search for "pg_graphql" and enable the extension.
</TabPanel>
<TabPanel id="sql" label="SQL">
{/* prettier-ignore */}
```sql
-- Enable the "pg_graphql" extension
create extension pg_graphql;
-- Disable the "pg_graphql" extension
drop extension if exists pg_graphql;
```
Even though the SQL code is `create extension`, this is the equivalent of "enabling the extension".
To disable an extension you can call `drop extension`.
</TabPanel>
</Tabs>
## Usage
Given a table
{/* prettier-ignore */}
```sql
create table "Blog"(
id serial primary key,
name varchar(255) not null,
description varchar(255),
);
insert into "Blog"(name)
values ('My Blog');
```
The reflected GraphQL schema can be queries immediately as
{/* prettier-ignore */}
```sql
select
graphql.resolve($$
{
blogCollection(first: 1) {
edges {
node {
id,
name
}
}
}
}
$$);
```
returning the JSON
{/* prettier-ignore */}
```json
{
"data": {
"blogCollection": {
"edges": [
{
"node": {
"id": 1
"name": "My Blog"
}
}
]
}
}
}
```
Note that `pg_graphql` fully supports schema introspection so you can connect any GraphQL IDE or schema inspection tool to see the full set of fields and arguments available in the API.
## API
- [`graphql.resolve`](https://supabase.github.io/pg_graphql/sql_interface/): A SQL function for executing GraphQL queries.
## Resources
- Official [`pg_graphql` documentation](https://github.com/supabase/pg_graphql)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page
@@ -0,0 +1,81 @@
import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'pg_hashids',
title: 'pg_hashids: Short UIDs',
description: 'Generate Short UIDs from Numbers',
}
[pg_hashids](https://github.com/iCyberon/pg_hashids) provides a secure way to generate short, unique, non-sequential ids from numbers. The hashes are intended to be small, easy-to-remember identifiers that can be used to obfuscate data (optionally) with a password, alphabet, and salt. For example, you may wish to hide data like user IDs, order numbers, or tracking codes in favor of `pg_hashid`'s unique identifers.
## Enable the Extension
<Tabs
scrollable
size="small"
type="underlined"
defaultActiveId="dashboard"
>
<TabPanel id="dashboard" label="Dashboard">
1. Go to the [Database](https://app.supabase.com/project/_/database/tables) page in the Dashboard.
2. Click on **Extensions** in the sidebar.
3. Search for "pg_hashids" and enable the extension.
</TabPanel>
<TabPanel id="sql" label="SQL">
{/* prettier-ignore */}
```sql
-- Enable the "pg_hashids" extension
create extension pg_hashids with schema extensions;
-- Disable the "pg_hashids" extension
drop extension if exists pg_hashids;
```
Even though the SQL code is `create extension`, this is the equivalent of "enabling the extension".
To disable an extension you can call `drop extension`.
It's good practice to create the extension within a separate schema (like `extensions`) to keep your `public` schema clean.
</TabPanel>
</Tabs>
## Usage
Suppose we have a table that stores order information, and we want to give customers a unique identifer without exposing the sequential `id` column. To do this, we can use `pg_hashid`'s `id_encode` function.
```sql
create table orders (
id serial primary key,
description text,
price_cents bigint
);
insert into orders (description, price_cents)
values ('a book', 9095);
select
id,
id_encode(id) as short_id,
description,
price_cents
from
orders;
id | short_id | description | price_cents
----+----------+-------------+-------------
1 | jR | a book | 9095
(1 row)
```
To reverse the `short_id` back into an `id`, there is an equivalent function named `id_decode`.
## Resources
- Official [pg_hashids documention](https://github.com/iCyberon/pg_hashids)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page
@@ -6,11 +6,9 @@ export const meta = {
description: 'Validate json/jsonb with JSON Schema in PostgreSQL.',
}
[JSON Schema](https://json-schema.org) is a language for annotating and validating JSON documents. [`pg_jsonschema`](https://json-schema.org) is a PostgreSQL extension that adds the ability to validate PostgreSQL's built-in `json` and `jsonb` data types against a JSON Schema document.
[JSON Schema](https://json-schema.org) is a language for annotating and validating JSON documents. [`pg_jsonschema`](https://github.com/supabase/pg_jsonschema) is a PostgreSQL extension that adds the ability to validate PostgreSQL's built-in `json` and `jsonb` data types against JSON Schema documents.
## Usage
### Enable the extension
## Enable the extension
<Tabs
scrollable
@@ -39,7 +37,7 @@ drop extension if exists pg_jsonschema;
Even though the SQL code is `create extension`, this is the equivalent of "enabling the extension".
To disable an extension you can call `drop extension`.
It's good practice to create the extension within a separate schema (like `extensions`) to keep your database clean.
It's good practice to create the extension within a separate schema (like `extensions`) to keep the `public` schema clean.
</TabPanel>
</Tabs>
@@ -49,9 +47,9 @@ It's good practice to create the extension within a separate schema (like `exten
- [`json_matches_schema(schema json, instance json)`](https://github.com/supabase/pg_jsonschema#api): Checks if a `json` _instance_ conforms to a JSON Schema _schema_.
- [`jsonb_matches_schema(schema json, instance jsonb)`](https://github.com/supabase/pg_jsonschema#api): Checks if a `jsonb` _instance_ conforms to a JSON Schema _schema_.
### Validating a document
## Usage
Since `pg_jsonschema` exposes its utilities as functions, we can test it with a simple select statement:
Since `pg_jsonschema` exposes its utilities as functions, we can execute them with a select statement:
{/* prettier-ignore */}
```sql
@@ -62,7 +60,7 @@ select
);
```
`pg_jsonschema` is generally used in tandem with a [check constraint](https://www.postgresql.org/docs/current/ddl-constraints.html) as a way to constrain the contents of a json/b field to match a JSON Schema.
`pg_jsonschema` is generally used in tandem with a [check constraint](https://www.postgresql.org/docs/current/ddl-constraints.html) as a way to constrain the contents of a json/b column to match a JSON Schema.
{/* prettier-ignore */}
```sql
@@ -0,0 +1,97 @@
import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'pg_plan_filter',
title: 'pg_plan_filter: Restrict Total Cost',
description: 'Block queries over a total cost limit',
}
[pg_plan_filter](https://github.com/pgexperts/pg_plan_filter) is PostgreSQL extension to block execution of statements where query planner's estimate of the total cost exceeds a threshold. This is intended to give database administrators a way to restrict the contribution an individual query has on database load.
## Enable the extension
`pg_plan_filter` can be enabled on a per connection basis:
{/* prettier-ignore */}
```sql
load 'plan_filter';
```
or for all connections:
{/* prettier-ignore */}
```sql
alter database some_db set session_preload_libraries = 'plan_filter';
```
## API
`plan_filter.statement_cost_limit`: restricts the maximum total cost for executed statements
`plan_filter.limit_select_only`: restricts to `select` statements
Note that `limit_select_only = true` is not the same as read-only because `select` statements may modfiy data e.g. through a function call.
## Example
To demonstrate total cost filtering, we'll compare how `plan_filter.statement_cost_limit` treats queries that are under and over its cost limit. First, we set up a table with some data:
{/* prettier-ignore */}
```sql
create table book(
id int primary key
);
-- CREATE TABLE
insert into book(id) select * from generate_series(1, 10000);
-- INSERT 0 10000
```
Next, we can review the explain plans for a single record select, and a whole table select.
{/* prettier-ignore */}
```sql
explain select * from book where id =1;
QUERY PLAN
---------------------------------------------------------------------------
Index Only Scan using book_pkey on book (cost=0.28..2.49 rows=1 width=4)
Index Cond: (id = 1)
(2 rows)
explain select * from book;
QUERY PLAN
---------------------------------------------------------
Seq Scan on book (cost=0.00..135.00 rows=10000 width=4)
(1 row)
```
Now we can choose a `statement_cost_filter` value between the total cost for the single select (2.49) and the whole table select (135.0) so one statement will succeed and one will fail.
{/* prettier-ignore */}
```sql
load 'plan_filter';
set plan_filter.statement_cost_limit = 50; -- between 2.49 and 135.0
select * from book where id = 1;
id
----
1
(1 row)
-- SUCCESS
```
{/* prettier-ignore */}
```sql
select * from book;
ERROR: plan cost limit exceeded
HINT: The plan for your query shows that it would probably have an excessive run time. This may be due to a logic error in the SQL, or it maybe just a very costly query. Rewrite your query or increase the configuration parameter "plan_filter.statement_cost_limit".
-- FAILURE
```
## Resources
- Official [pg_plan_filter documentation](https://github.com/pgexperts/pg_plan_filter)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page
@@ -0,0 +1,88 @@
import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'pg_stat_monitor',
title: 'pg_stat_monitor: Query Performance Monitoring',
description: 'Query performance monitoring for PostgreSQL',
}
[pg_stat_monitor](https://github.com/percona/pg_stat_monitor) is query performance monitoring tool that provides query execution statistics in a SQL view named `pg_stat_monitor`. It tracks a superset of statistics available in [`pg_stat_statements`](https://www.postgresql.org/docs/current/pgstatstatements.html). Some of the most useful features are:
- **Time Interval Grouping**: configurable time buckets to track query usage over time
- **Capture Parameters**: optionally track parameters passed into queries instead of generic placeholders e.g. `$1`
- **Query Plan**: store query plans used for execution
For more information on query optimization, check out the [query performance guide](/docs/guides/platform/performance#examining-query-performance).
## Enable the extension
<Tabs
scrollable
size="small"
type="underlined"
defaultActiveId="dashboard"
>
<TabPanel id="dashboard" label="Dashboard">
1. Go to the [Database](https://app.supabase.com/project/_/database/tables) page in the Dashboard.
2. Click on **Extensions** in the sidebar.
3. Search for "pg_stat_monitor" and enable the extension.
</TabPanel>
<TabPanel id="sql" label="SQL">
{/* prettier-ignore */}
```sql
-- Enable the "pg_stat_monitor" extension
create extension pg_stat_monitor with schema extensions;
-- Disable the "pg_stat_monitor" extension
drop extension if exists pg_stat_monitor;
```
Even though the SQL code is `create extension`, this is the equivalent of "enabling the extension".
To disable an extension you can call `drop extension`.
It's good practice to create the extension within a separate schema (like `extensions`) to keep the `public` schema clean.
</TabPanel>
</Tabs>
## Views
{/* prettier-ignore */}
```sql
select * from extensions.pg_stat_monitor;
```
The following table shows a subset of available columns:
| Column Type | Description |
| ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| bucket bigint | Data collection unit. The number shows what bucket in a chain a record belongs to |
| bucket_start_time timestampz | The start time of the bucket |
| userid oid (references pg_authid.oid) | OID of user who executed the statement |
| dbid oid (references pg_database.oid) | OID of database in which the statement was executed |
| toplevel bool | True if the query was executed as a top-level statement (always true if pg_stat_statements.track is set to top) |
| client_ip inet | The IP address of a client that ran the query |
| queryid bigint | Hash code to identify identical normalized queries. |
| planid text | An internally generated ID of a query plan |
| query_plan text | The sequence of steps used to execute a query. This parameter is only available when pgsm_enable_query_plan is enabled |
| query text | Text of a representative statement |
| plans bigint | Number of times the statement was planned (if pg_stat_statements.track_planning is enabled, otherwise zero) |
| total_plan_time double precision | Total time spent planning the statement, in milliseconds (if pg_stat_statements.track_planning is enabled, otherwise zero) |
| min_plan_time double precision | Minimum time spent planning the statement, in milliseconds (if pg_stat_statements.track_planning is enabled, otherwise zero) |
A full list of statistics is available in the [pg_stat_monitor docs](https://docs.percona.com/pg-stat-monitor/reference.html#postgresql-15).
## Functions
- [`pg_stat_monitor_reset()`](https://docs.percona.com/pg-stat-monitor/functions.html): Resets the statistics tracked by the `pg_stat_monitor` view and deletes all previous data.
- [`pg_stat_monitor_version()`](https://docs.percona.com/pg-stat-monitor/functions.html): Displays the version of the `pg_stat_monitor` extension.
## Resources
- Official [`pg_stat_monitor` documentation](https://github.com/percona/pg_stat_monitor)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page
@@ -2,7 +2,7 @@ import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'pg_stat_statements',
title: 'pg_stat_statements: SQL Planning and Execution Statistics',
title: 'pg_stat_statements: Query Performance Monitoring',
description:
'Track planning and execution statistics of all SQL statements executed on the database.',
}
@@ -22,9 +22,9 @@ export const meta = {
A full list of statistics is available in the [pg_stat_statements docs](https://www.postgresql.org/docs/current/pgstatstatements.html).
## Usage
For more information on query optimization, check out the [query performance guide](/docs/guides/platform/performance#examining-query-performance).
### Enable the extension
## Enable the extension
<Tabs
scrollable
@@ -53,12 +53,12 @@ drop extension if exists pg_stat_statements;
Even though the SQL code is `create extension`, this is the equivalent of "enabling the extension".
To disable an extension you can call `drop extension`.
It's good practice to create the extension within a separate schema (like `extensions`) to keep your database clean.
It's good practice to create the extension within a separate schema (like `extensions`) to keep the `public` schema clean.
</TabPanel>
</Tabs>
### Inspecting activity
## Inspecting activity
A common use for `pg_stat_statements` is to track down expensive or slow queries. The `pg_stat_statements` view contains a row for each executed query with statistics inlined. For example, you can leverage the statistics to identify frequently executed and slow queries against a given table.
@@ -74,15 +74,15 @@ select
from
pg_stat_statements
where
calls > 1000 -- at least 50 calls
and mean_exec_time > 2.0 -- averaging at least 2ms/call
and total_exec_time > 60000 -- at least one minute total server time spent
and query ilike '%user_in_organization%' -- filter to queries that touch the user_in_organization table
calls > 50 -- at least 50 calls
and mean_exec_time > 2.0 -- averaging at least 2ms/call
and total_exec_time > 60000 -- at least one minute total server time spent
and query ilike '%user_in_organization%' -- filter to queries that touch the user_in_organization table
order by
calls desc
```
From the results, an informed decision about which queries to optimize, index, or adjust can be made.
From the results, we can make an informed decision about which queries to optimize or index.
## Resources
@@ -0,0 +1,105 @@
import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'pgaudit',
title: 'PGAudit: Postgres Auditing',
description: 'Session and object auditing via PostgreSQL standard logging',
}
[PGAudit](https://www.pgaudit.org) is a PostgreSQL extension for logging session and object auditing over the standard PostgreSQL logging utility.
PGAudit grants fine grain control over which statements and objects are emitted to logs.
## Enable the extension
<Tabs
scrollable
size="small"
type="underlined"
defaultActiveId="dashboard"
>
<TabPanel id="dashboard" label="Dashboard">
1. Go to the [Database](https://app.supabase.com/project/_/database/tables) page in the Dashboard.
2. Click on **Extensions** in the sidebar.
3. Search for "pgaudit" and enable the extension.
</TabPanel>
<TabPanel id="sql" label="SQL">
{/* prettier-ignore */}
```sql
-- Enable the "pgaudit" extension
create extension pgaudit;
-- Disable the "pgaudit" extension
drop extension if exists pgaudit;
```
Even though the SQL code is `create extension`, this is the equivalent of "enabling the extension".
To disable an extension you can call `drop extension`.
</TabPanel>
</Tabs>
## Settings
The `pgaudit.log` setting controls which statements to log. Available values include:
- **read**: `SELECT` and `COPY` when the source is a relation or a query.
- **write**: `INSERT`, `UPDATE`, `DELETE`, `TRUNCATE`, and `COPY` when the destination is a relation.
- **function**: Function calls and `DO` blocks.
- **role**: Statements related to roles and privileges: `GRANT`, `REVOKE`, `CREATE/ALTER/DROP ROLE`.
- **ddl**: All `DDL` that is not included in the `ROLE` class.
- **misc**: Miscellaneous commands, e.g. `DISCARD`, `FETCH`, `CHECKPOINT`, `VACUUM`, `SET`.
- **misc_set**: Miscellaneous `SET` commands, e.g. `SET ROLE`.
- **all**: Include all of the above.
For a full list of available settings see [settings docs](https://github.com/pgaudit/pgaudit/blob/master/README.md#settings). Be aware that the `all` setting will generate a very large volume of logs.
## Example
Given a pgaudit setting
{/* prettier-ignore */}
```sql
set pgaudit.log = 'read, ddl';
```
The following create table, insert and select statements
{/* prettier-ignore */}
```sql
create table account (
id int primary key,
name text,
description text
);
insert into account (id, name, description)
values (1, 'Foo Barsworth', 'Customer account');
select * from account;
```
Results in the log output
```text
AUDIT: SESSION,1,1,DDL,CREATE TABLE,TABLE,public.account,create table account(
id int,
name text,
description text
);,<not logged>
AUDIT: SESSION,2,1,READ,SELECT,,,select * from account,,<not logged>
```
Note that the insert statement is not logged because we did not include the `write` option for `pgaudit.log`.
## Resources
- Official [`PGAudit` documentation](https://www.pgaudit.org)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page
@@ -0,0 +1,113 @@
import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'pgjwt',
title: 'pgjwt: JSON Web Tokens',
description: 'Encode and decode JWTs in PostgreSQL',
}
The [pgjwt](https://github.com/michelp/pgjwt) (PostgreSQL JSON Web Token) extension allows you to create and parse [JSON Web Tokens (JWTs)](https://en.wikipedia.org/wiki/JSON_Web_Token) within a PostgreSQL database. JWTs are commonly used for authentication and authorization in web applications and services.
## Enable the extension
<Tabs
scrollable
size="small"
type="underlined"
defaultActiveId="dashboard"
>
<TabPanel id="dashboard" label="Dashboard">
1. Go to the [Database](https://app.supabase.com/project/_/database/tables) page in the Dashboard.
2. Click on **Extensions** in the sidebar.
3. Search for "pgjwt" and enable the extension.
</TabPanel>
<TabPanel id="sql" label="SQL">
{/* prettier-ignore */}
```sql
-- Enable the "pgjwt" extension
create extension pgjwt schema extensions;
-- Disable the "pgjwt" extension
drop extension if exists pgjwt;
```
Even though the SQL code is `create extension`, this is the equivalent of "enabling the extension".
To disable an extension you can call `drop extension`.
It's good practice to create the extension within a separate schema (like `extensions`) to keep the `public` schema clean.
</TabPanel>
</Tabs>
## API
- [`sign(payload json, secret text, algorithm text default 'HSA256')`](https://github.com/michelp/pgjwt#usage): Signs a JWT containng _payload_ with _secret_ using _algorithm_.
- [`verify(token text, secret text, algorithm text default 'HSA256')`](https://github.com/michelp/pgjwt#usage): Decodes a JWT _token_ that was signed with _secret_ using _algorithm_.
Where:
- `payload` is an encrypted JWT represented as a string.
- `secret` is the private/secret passcode which is used to sign the JWT and verify its integrity.
- `algorithm` is the method used to sign the JWT using the secret.
- `token` is an encrypted JWT represented as a string.
## Usage
Once the extension is installed, you can use its functions to create and parse JWTs. Here's an example of how you can use the `sign` function to create a JWT:
{/* prettier-ignore */}
```sql
select
extensions.sign(
payload := '{"sub":"1234567890","name":"John Doe","iat":1516239022}',
secret := 'secret',
algorithm := 'HS256'
);
```
The pgjwt_encode function returns a string that represents the JWT, which can then be safely transmitted between parties.
{/* prettier-ignore */}
```
sign
---------------------------------
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpX
VCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiw
ibmFtZSI6IkpvaG4gRG9lIiwiaWF0Ijo
xNTE2MjM5MDIyfQ.XbPfbIHMI6arZ3Y9
22BhjWgQzWXcXNrz0ogtVhfEd2o
(1 row)
```
To parse a JWT and extract its claims, you can use the `verify` function. Here's an example:
{/* prettier-ignore */}
```sql
select
extensions.verify(
token := 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiRm9vIn0.Q8hKjuadCEhnCPuqIj9bfLhTh_9QSxshTRsA5Aq4IuM',
secret := 'secret',
algorithm := 'HS256'
);
```
Which returns the decoded contents and some associated metadata.
{/* prettier-ignore */}
```sql
header | payload | valid
-----------------------------+----------------+-------
{"alg":"HS256","typ":"JWT"} | {"name":"Foo"} | t
(1 row)
```
## Resources
- Official [`pgjwt` documentation](https://github.com/michelp/pgjwt)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page
@@ -16,9 +16,8 @@ The pg_net API is in alpha. Functions signatures may change.
It differs from the `http` extension in that it is asynchronous by default. This makes it useful in blocking functions (like triggers).
## Usage
### Enable the extension
## Enable the extension
<Tabs
scrollable
@@ -2,15 +2,14 @@ import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'pgroonga',
title: 'PGRoonga: Multilingual Full Text Search',
title: 'PGroonga: Multilingual Full Text Search',
description: 'Full Text Search for multiple languages in PostgreSQL',
}
`PGroonga` is a PostgreSQL extension adding a full text search indexing method based on [Groonga](https://groonga.org). While native PostgreSQL supports full text indexing, it is limited to alphabet and digit based languages. `PGroonga` offers a wider range of character support making it viable for a superset of languages supported by PostgreSQL including Japanese, Chinese, etc.
## Usage
### Enable the extension
## Enable the extension
<Tabs
scrollable
@@ -39,12 +38,10 @@ drop extension if exists pgroonga;
Even though the SQL code is `create extension`, this is the equivalent of "enabling the extension".
To disable an extension you can call `drop extension`.
It's good practice to create the extension within a separate schema (like `extensions`) to keep your database clean.
</TabPanel>
</Tabs>
### Creating a full text search index
## Creating a full text search index
Given a table with a `text` column:
@@ -0,0 +1,159 @@
import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'pgrouting',
title: 'pgrouting: Geospatial Routing',
description: 'Extends PostGIS with Geospatial Routing',
}
[pgRouting](http://pgrouting.org) is PostgreSQL and [PostGIS](http://postgis.net) extension adding geospatial routing functionality.
The core functionality of `pgRouting` is a set of path finding algorithms including:
- All Pairs Shortest Path, Johnson’s Algorithm
- All Pairs Shortest Path, Floyd-Warshall Algorithm
- Shortest Path A\*
- Bi-directional Dijkstra Shortest Path
- Bi-directional A\* Shortest Path
- Shortest Path Dijkstra
- Driving Distance
- K-Shortest Path, Multiple Alternative Paths
- K-Dijkstra, One to Many Shortest Path
- Traveling Sales Person
- Turn Restriction Shortest Path (TRSP)
## Enable the extension
<Tabs
scrollable
size="small"
type="underlined"
defaultActiveId="dashboard"
>
<TabPanel id="dashboard" label="Dashboard">
1. Go to the [Database](https://app.supabase.com/project/_/database/tables) page in the Dashboard.
2. Click on **Extensions** in the sidebar.
3. Search for "pgrouting" and enable the extension.
</TabPanel>
<TabPanel id="sql" label="SQL">
{/* prettier-ignore */}
```sql
-- Enable the "pgRouting" extension
create extension pgrouting cascade;
-- Disable the "pgRouting" extension
drop extension if exists pgRouting;
```
Even though the SQL code is `create extension`, this is the equivalent of "enabling the extension".
To disable an extension you can call `drop extension`.
</TabPanel>
</Tabs>
## Example
As an example, we'll solve the [traveling salesman probelem](https://en.wikipedia.org/wiki/Travelling_salesman_problem) using the pgRouting's `pgr_TSPeuclidean` function from some PostGIS coodinates.
A summary of the traveling salesman problem is, given a set of city coordinates, solve for a path that goes through each city and minimizes the total distance traveled.
First we populate a table with some X, Y coordinates
{/* prettier-ignore */}
```sql
create table wi29 (
id bigint,
x float,
y float,
geom geometry
);
insert into wi29 (id, x, y)
values
(1,20833.3333,17100.0000),
(2,20900.0000,17066.6667),
(3,21300.0000,13016.6667),
(4,21600.0000,14150.0000),
(5,21600.0000,14966.6667),
(6,21600.0000,16500.0000),
(7,22183.3333,13133.3333),
(8,22583.3333,14300.0000),
(9,22683.3333,12716.6667),
(10,23616.6667,15866.6667),
(11,23700.0000,15933.3333),
(12,23883.3333,14533.3333),
(13,24166.6667,13250.0000),
(14,25149.1667,12365.8333),
(15,26133.3333,14500.0000),
(16,26150.0000,10550.0000),
(17,26283.3333,12766.6667),
(18,26433.3333,13433.3333),
(19,26550.0000,13850.0000),
(20,26733.3333,11683.3333),
(21,27026.1111,13051.9444),
(22,27096.1111,13415.8333),
(23,27153.6111,13203.3333),
(24,27166.6667,9833.3333),
(25,27233.3333,10450.0000),
(26,27233.3333,11783.3333),
(27,27266.6667,10383.3333),
(28,27433.3333,12400.0000),
(29,27462.5000,12992.2222);
```
Next we use the `pgr_TSPeuclidean` function to find the best path.
{/* prettier-ignore */}
```sql
select
*
from
pgr_TSPeuclidean($$select * from wi29$$)
```
{/* prettier-ignore */}
```sql
seq | node | cost | agg_cost
-----+------+------------------+------------------
1 | 1 | 0 | 0
2 | 2 | 74.535614157127 | 74.535614157127
3 | 6 | 900.617093380362 | 975.152707537489
4 | 10 | 2113.77757765045 | 3088.93028518793
5 | 11 | 106.718669615254 | 3195.64895480319
6 | 12 | 1411.95293791574 | 4607.60189271893
7 | 13 | 1314.23824873744 | 5921.84014145637
8 | 14 | 1321.76283931305 | 7243.60298076942
9 | 17 | 1202.91366735569 | 8446.5166481251
10 | 18 | 683.333268292684 | 9129.84991641779
11 | 15 | 1108.05137466134 | 10237.9012910791
12 | 19 | 772.082339448903 | 11009.983630528
13 | 22 | 697.666150054665 | 11707.6497805827
14 | 23 | 220.141999627513 | 11927.7917802102
15 | 21 | 197.926372783442 | 12125.7181529937
16 | 29 | 440.456596290771 | 12566.1747492844
17 | 28 | 592.939989005405 | 13159.1147382898
18 | 26 | 648.288376333318 | 13807.4031146231
19 | 20 | 509.901951359278 | 14317.3050659824
20 | 25 | 1330.83095428717 | 15648.1360202696
21 | 27 | 74.535658878487 | 15722.6716791481
22 | 24 | 559.016994374947 | 16281.688673523
23 | 16 | 1243.87392358622 | 17525.5625971092
24 | 9 | 4088.0585364911 | 21613.6211336004
25 | 7 | 650.85409697993 | 22264.4752305803
26 | 3 | 891.004385199336 | 23155.4796157796
27 | 4 | 1172.36699411442 | 24327.846609894
28 | 8 | 994.708187806297 | 25322.5547977003
29 | 5 | 1188.01888359478 | 26510.5736812951
30 | 1 | 2266.91173136004 | 28777.4854126552
```
## Resources
- Official [`pgRouting` documentation](https://docs.pgrouting.org/latest/en/index.html)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page
@@ -0,0 +1,49 @@
import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'pgsodium',
title: 'pgsodium: Encryption Features',
description: 'Encryption library for PostgreSQL',
}
[pgsodium](https://github.com/michelp/pgsodium) is a PostgreSQL extension which provides SQL access to libsodium's high-level cryptographic algorithms. It also enables some Postgres specific features including:
- [Server Key Management](https://github.com/michelp/pgsodium#server-key-management)
- [Transparent Column Encryption](https://github.com/michelp/pgsodium#transparent-column-encryption)
## Enable the extension
<Tabs
scrollable
size="small"
type="underlined"
defaultActiveId="dashboard"
>
<TabPanel id="dashboard" label="Dashboard">
1. Go to the [Database](https://app.supabase.com/project/_/database/tables) page in the Dashboard.
2. Click on **Extensions** in the sidebar.
3. Search for "pgsodium" and enable the extension.
</TabPanel>
<TabPanel id="sql" label="SQL">
{/* prettier-ignore */}
```sql
-- Enable the "pgsodium" extension
create extension pgsodium;
-- Disable the "pgsodium" extension
drop extension if exists pgsodium;
```
</TabPanel>
</Tabs>
## Resources
- Official [`pgsodium` documentation](https://github.com/michelp/pgsodium)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page
@@ -15,9 +15,7 @@ Let's cover some basic concepts:
- Unit tests: allow you to test small parts of a system (like a database table!).
- TAP: stands for [Test Anything Protocol](http://testanything.org/). It is an framework which aims to simplify the error reporting during testing.
## Usage
### Enable the extension
## Enable the extension
<Tabs
scrollable
@@ -45,12 +43,12 @@ drop extension if exists pgtap;
Even though the SQL code is `create extension`, this is the equivalent of "enabling the extension".
To disable an extension you can call `drop extension`.
It's good practice to create the extension within a separate schema (like `extensions`) to keep your database clean.
It's good practice to create the extension within a separate schema (like `extensions`) to keep the `public` schema clean.
</TabPanel>
</Tabs>
### Testing tables
## Testing tables
```sql
begin;
@@ -68,7 +66,7 @@ API:
- [`has_index()`](https://pgtap.org/documentation.html#has_index): Checks for the existence of a named index associated with the named table.
- [`has_relation()`](https://pgtap.org/documentation.html#has_relation): Tests whether or not a relation exists in the database.
### Testing columns
## Testing columns
```sql
begin;
@@ -86,7 +84,7 @@ API:
- [`has_column()`](https://pgtap.org/documentation.html#has_column): Tests whether or not a column exists in a given table, view, materialized view or composite type.
- [`col_is_pk()`](https://pgtap.org/documentation.html#col_is_pk): Tests whether the specified column or columns in a table is/are the primary key for that table.
### Testing RLS Policies
## Testing RLS Policies
```sql
begin;
@@ -133,7 +131,7 @@ API:
- [`results_eq()`](https://pgtap.org/documentation.html#results_eq)
- [`results_ne()`](https://pgtap.org/documentation.html#results_ne)
### Testing Functions
## Testing Functions
```sql
begin;
@@ -0,0 +1,105 @@
import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'plpgsql_check',
title: 'plpgsql_check: PL/pgSQL Linter',
description: 'Lint PL/pgSQL code',
}
[plpgsql_check](https://github.com/okbob/plpgsql_check) is a PostgreSQL extension that lints plpgsql for syntax, semantic and other related issues. The tool helps developers to identify and correct errors before executing the code. plpgsql_check is most useful for developers who are working with large or complex SQL codebases, as it can help identify and resolve issues early in the development cycle.
## Enable the extension
<Tabs
scrollable
size="small"
type="underlined"
defaultActiveId="dashboard"
>
<TabPanel id="dashboard" label="Dashboard">
1. Go to the [Database](https://app.supabase.com/project/_/database/tables) page in the Dashboard.
2. Click on **Extensions** in the sidebar.
3. Search for "plpgsql_check" and enable the extension.
</TabPanel>
<TabPanel id="sql" label="SQL">
{/* prettier-ignore */}
```sql
-- Enable the "plpgsql_check" extension
create extension plpgsql_check;
-- Disable the "plpgsql_check" extension
drop extension if exists plpgsql_check;
```
Even though the SQL code is `create extension`, this is the equivalent of "enabling the extension".
To disable an extension you can call `drop extension`.
</TabPanel>
</Tabs>
## API
- [`plpgsql_check_function( ... )`](https://github.com/okbob/plpgsql_check#active-mode): Scans a function for errors.
`plpgsql_check_function` is highly customizable. For a complete list of available arguments see [the docs](https://github.com/okbob/plpgsql_check#arguments)
## Usage
To demonstrate `plpgsql_check` we can create a function with a known error. In this case we create a function `some_func`, that references a non-existent column `place.created_at`.
{/* prettier-ignore */}
```sql
create table place(
x float,
y float
);
create or replace function public.some_func()
returns void
language plpgsql
as $$
declare
rec record;
begin
for rec in select * from place
loop
-- Bug: There is no column `created_at` on table `place`
raise notice '%', rec.created_at;
end loop;
end;
$$;
```
Note that executing the function would not catch the invalid reference error because the `loop` does not execute if no rows are present in the table.
{/* prettier-ignore */}
```sql
select public.some_func();
some_func
───────────
(1 row)
```
Now we can use plpgsql_check's `plpgsql_check_function` function to identify the known error.
{/* prettier-ignore */}
```sql
select plpgsql_check_function('public.some_func()');
plpgsql_check_function
------------------------------------------------------------
error:42703:8:RAISE:record "rec" has no field "created_at"
Context: SQL expression "rec.created_at"
```
## Resources
- Official [`plpgsql_check` documentation](https://github.com/okbob/plpgsql_check)
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page
Loaded 100 of 410 files, more files were not shown because too many files have changed in this diff. Show more