Merge branch 'master' into pr/9276

This commit is contained in:
Terry Sutton committed 2023-03-31 09:25:48 -02:30
commit 1a2ac2c027
5967 files changed
+633811 -623441

No files matched your search

+19 -6
View File
@@ -1,7 +1,20 @@
node_modules/
# Root folder of this turbo monorepo
# Doesn't send useless context to Docker daemon
.git
.github
about
apps
docker
examples
i18n
**/node_modules
spec
supabase
tests
**/.next
.vercel
.next
.env.local
.env.production
.env.dev
.env.*
.env.*
.dockerignore
studio/Dockerfile
+2 -1
View File
@@ -1,4 +1,5 @@
/studio/ @supabase/frontend
/apps/www/ @supabase/frontend
/apps/reference/ @supabase/docs
/apps/docs/ @supabase/docs
/spec/ @supabase/docs
/docker/ @supabase/cli
+20
View File
@@ -0,0 +1,20 @@
name: reviewdog
on:
pull_request:
types: [opened, synchronize, reopened, edited]
jobs:
misspell:
name: runner / misspell
runs-on: ubuntu-latest
steps:
- name: Check out code.
uses: actions/checkout@v3
- name: misspell
uses: reviewdog/action-misspell@v1
with:
github_token: ${{ secrets.github_token }}
locale: "US"
reporter: github-pr-review
level: error
exclude: "*.css"
-27
View File
@@ -1,27 +0,0 @@
name: Deploy studio app to production on vercel
on:
push:
branches:
- studio
paths:
- 'studio/**'
jobs:
deploy:
runs-on: ubuntu-18.04
timeout-minutes: 10
steps:
- uses: actions/checkout@v2
# remove ./studio/pages/api folder before deploying to vercel
- uses: JesseTG/rm@v1.0.2
with:
path: ./studio/pages/api
- uses: amondnet/vercel-action@v19
with:
vercel-token: ${{ secrets.VERCEL_TOKEN }} # Required
github-comment: false
vercel-args: '--prod -A .vercel/production.json'
vercel-org-id: team_E6KJ1W561hMTjon1QSwOh0WO #Required
vercel-project-id: Qmd7Mw8yFW8SbtvTWFV9uyRzw9P1rJLmgtHjSezywhtYec #Required
working-directory: ./studio #Your Working Directory, Optional
vercel-project-name: app
@@ -1,27 +0,0 @@
name: Deploy studio app to staging on vercel
on:
push:
branches:
- master
paths:
- 'studio/**'
jobs:
deploy:
runs-on: ubuntu-18.04
timeout-minutes: 10
steps:
- uses: actions/checkout@v2
# remove ./studio/pages/api folder before deploying to vercel
- uses: JesseTG/rm@v1.0.2
with:
path: ./studio/pages/api
- uses: amondnet/vercel-action@v19
with:
vercel-token: ${{ secrets.VERCEL_TOKEN }} # Required
github-comment: false
vercel-args: '--prod -A .vercel/staging.json'
vercel-org-id: team_E6KJ1W561hMTjon1QSwOh0WO #Required
vercel-project-id: QmcmhbiAtCMFTAHCuGgQscNbke4TzgWULECctNcKmxWCoT #Required
working-directory: ./studio #Your Working Directory, Optional
vercel-project-name: staging-app
@@ -1,42 +0,0 @@
# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
name: Docs Compilation Check
on:
pull_request:
branches: [master]
paths:
- 'apps/reference/**'
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [16.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps:
- uses: actions/checkout@v2
# Ref: https://github.com/actions/setup-node/issues/214
- name: Reconfigure git to use HTTP authentication
run: >
git config --global url."https://github.com/".insteadOf
ssh://git@github.com/
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- name: Install Deps
run: npm ci
working-directory: ./apps/reference
- name: Build
run: npm run build
working-directory: ./apps/reference
+19
View File
@@ -0,0 +1,19 @@
name: Automatically fix typos
on:
push:
branches:
- master
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
ref: master
- uses: sobolevn/misspell-fixer-action@master
- uses: peter-evans/create-pull-request@v4
env:
ACTIONS_ALLOW_UNSECURE_COMMANDS: 'true'
with:
token: ${{ secrets.GITHUB_TOKEN }}
-92
View File
@@ -1,92 +0,0 @@
# This is a basic workflow to help you get started with Actions
name: Tests
# Controls when the workflow will run
on:
# Triggers the workflow on push or pull request events but only for the main branch
push:
branches: [master]
pull_request:
branches: [master]
# Allows you to run this workflow manually from the Actions tab
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
- name: Run infrastructure
run: |
cp ../docker/.env.example ../docker/.env
npm run docker:up
- name: Run Test
run: npm run test
- name: Stop infrastructure
if: always()
run: npm run docker:down
- 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: ${{ !github.event.pull_request.head.repo.fork }}
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: ${{ !github.event.pull_request.head.repo.fork }}
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 }}
+42
View File
@@ -0,0 +1,42 @@
name: Mirror Image
on:
workflow_call:
inputs:
version:
required: true
type: string
workflow_dispatch:
inputs:
version:
description: 'Image tag'
required: true
type: string
jobs:
mirror:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
id-token: write
steps:
- name: configure aws credentials
uses: aws-actions/configure-aws-credentials@v1
with:
role-to-assume: ${{ secrets.PROD_AWS_ROLE }}
aws-region: us-east-1
- uses: docker/login-action@v2
with:
registry: public.ecr.aws
- uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: akhilerm/tag-push-action@v2.1.0
with:
src: docker.io/supabase/studio:${{ inputs.version }}
dst: |
public.ecr.aws/supabase/studio:${{ inputs.version }}
ghcr.io/supabase/studio:${{ inputs.version }}
+28
View File
@@ -0,0 +1,28 @@
name: Deploy OG Images
on:
push:
branches:
- master
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: latest
- run: supabase functions deploy og-images --project-ref $PROJECT_ID --no-verify-jwt
+30 -4
View File
@@ -10,11 +10,19 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Check out repo
uses: actions/checkout@v2
# disable this check while we migrate to monorepo
uses: actions/checkout@v3
- name: Run prettier
run: |-
npx prettier -c 'apps/**/*.{js,jsx,ts,tsx,css,md,json}'
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() {
# if $(grep -q '"prettier"' "$1") ; then
@@ -33,7 +41,25 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Check out repo
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Run prettier
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}'
format-sql:
runs-on: ubuntu-latest
steps:
- name: Check out repo
uses: actions/checkout@v3
- name: Install plugin
run: npm ci
- name: Run prettier
run: |-
# Check mdx files which contain sql code blocks
grep -lr '```sql' apps/docs/pages/**/*.mdx | xargs npx prettier -c
+99 -15
View File
@@ -2,6 +2,8 @@ name: Publish to Image Registry
on:
push:
branches:
- 'studio'
tags:
- '*'
workflow_dispatch:
@@ -12,24 +14,39 @@ on:
type: string
jobs:
publish:
settings:
runs-on: ubuntu-latest
outputs:
image_version: ${{ steps.meta.outputs.version }}
steps:
- id: meta
uses: docker/metadata-action@v4
with:
images: |
supabase/studio
public.ecr.aws/t3w2s2c9/studio
flavor: |
latest=false
tags: |
type=ref,event=tag
type=raw,value=${{ inputs.version }},enable=${{ github.event_name != 'push' }}
type=sha,prefix={{date 'YYYYMMDD'}}-,enable=${{ github.event_name == 'push' && github.ref_type == 'branch' }}
type=raw,value=${{ inputs.version }},enable=${{ github.event_name == 'workflow_dispatch' }}
- uses: docker/setup-qemu-action@v2
release_x86:
needs: settings
runs-on: ubuntu-latest
timeout-minutes: 120
env:
arch: amd64
outputs:
image_digest: ${{ steps.build.outputs.digest }}
steps:
- id: meta
uses: docker/metadata-action@v4
with:
platforms: amd64,arm64
images: |
supabase/studio
tags: |
type=raw,value=${{ needs.settings.outputs.image_version }}_${{ env.arch }}
- uses: docker/setup-buildx-action@v2
@@ -39,19 +56,86 @@ jobs:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to ECR
uses: docker/login-action@v2
with:
registry: public.ecr.aws
username: ${{ secrets.PROD_ACCESS_KEY_ID }}
password: ${{ secrets.PROD_SECRET_ACCESS_KEY }}
- uses: docker/build-push-action@v3
- id: build
uses: docker/build-push-action@v3
with:
push: true
context: '{{defaultContext}}:studio'
context: '{{defaultContext}}'
file: studio/Dockerfile
target: production
platforms: linux/amd64,linux/arm64
platforms: linux/${{ env.arch }}
tags: ${{ steps.meta.outputs.tags }}
cache-from: type=gha
cache-to: type=gha,mode=max
release_arm:
needs: settings
runs-on: arm-runner
timeout-minutes: 120
env:
arch: arm64
outputs:
image_digest: ${{ steps.build.outputs.digest }}
steps:
- uses: actions/checkout@v3
- id: meta
uses: docker/metadata-action@v4
with:
images: |
supabase/studio
tags: |
type=raw,value=${{ needs.settings.outputs.image_version }}_${{ env.arch }}
- uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- uses: docker/setup-buildx-action@v2
with:
driver: docker
driver-opts: |
image=moby/buildkit:master
network=host
- id: build
uses: docker/build-push-action@v3
with:
push: true
context: .
file: studio/Dockerfile
target: production
platforms: linux/${{ env.arch }}
tags: ${{ steps.meta.outputs.tags }}
no-cache: true
merge_manifest:
needs:
- settings
- release_x86
- release_arm
runs-on: ubuntu-latest
steps:
- uses: docker/setup-buildx-action@v2
- uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Merge multi-arch manifests
run: |
docker buildx imagetools create -t supabase/studio:${{ needs.settings.outputs.image_version }} \
supabase/studio@${{ needs.release_x86.outputs.image_digest }} \
supabase/studio@${{ needs.release_arm.outputs.image_digest }}
publish:
needs:
- settings
- merge_manifest
# Call workflow explicitly because events from actions cannot trigger more actions
uses: ./.github/workflows/mirror.yml
with:
version: ${{ needs.settings.outputs.image_version }}
secrets: inherit
-32
View File
@@ -1,32 +0,0 @@
name: Studio Build
on:
pull_request:
branches:
- master
- studio
paths:
- 'studio/**'
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [16.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- name: Install deps
run: npm i
working-directory: ./studio
- name: Run build
run: npm run build
working-directory: ./studio
+16 -15
View File
@@ -5,16 +5,17 @@ name: Studio Unit Tests
on:
push:
branches: [ master ]
branches: [master]
paths:
- 'studio/**'
- 'package-lock.json'
pull_request:
branches: [ master ]
branches: [master]
paths:
- 'studio/**'
- 'package-lock.json'
jobs:
build:
runs-on: ubuntu-latest
strategy:
@@ -23,15 +24,15 @@ jobs:
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- name: Install deps
run: npm install
working-directory: ./
- name: Run tests
run: npm test
working-directory: ./studio
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- name: Install deps
run: npm ci
working-directory: ./
- name: Run tests
run: npm run test:studio
working-directory: ./
+3
View File
@@ -4,6 +4,7 @@ node_modules
out
.docz
tmp
.swp
coverage
allure-results
@@ -118,3 +119,5 @@ typings/
# Supabase
**/supabase/.branches
**/supabase/.temp
apps/new-docs/*
+1
View File
@@ -0,0 +1 @@
^./i18n
+8 -1
View File
@@ -3,4 +3,11 @@
node_modules
package-lock.json
docker*
apps/**/out
apps/**/out
# prettier-plugin-sql-cst only supports sqlite syntax
**/supabase/migrations/*.sql
apps/www/schema.sql
examples/slack-clone/nextjs-slack-clone/full-schema.sql
# ignore files with custom js formatting
apps/docs/pages/guides/auth/*.mdx
apps/docs/pages/guides/integrations/*.mdx
+2 -1
View File
@@ -4,5 +4,6 @@
"semi": false,
"singleQuote": true,
"printWidth": 100,
"endOfLine": "lf"
"endOfLine": "lf",
"sqlKeywordCase": "lower"
}
-1
View File
@@ -1 +0,0 @@
cookie
+65 -141
View File
@@ -1,45 +1,46 @@
# Developing Supabase
1. [Development setup](#development-setup)
- [Install dependencies](#install-dependencies)
- [Fork the repository](#fork-the-repository)
1. [Build Supabase](#build-supabase)
- [Choose a directory](#choose-a-directory)
1. [Start a development server](#start-a-development-server)
- [Supabase Website](#supabase-website)
- [Supabase Docs](#supabase-docs)
- [Supabase Studio](#supabase-studio)
1. [Create a pull request](#create-a-pull-request)
1. [Getting started](#getting-started)
- [Install dependencies](#install-dependencies)
2. [Local development](#local-development)
- [Fork the repository](#fork-the-repository)
- [Clone the repo](#clone-the-repo)
- [Running turborepo](#running-turborepo)
- [Shared components](#shared-components)
- [Installing packages](#installing-packages)
- [New Supabase docs](#new-supabase-docs)
3. [Create a pull request](#create-a-pull-request)
- [Common tasks](#common-tasks)
- [Add a redirect](#add-a-redirect)
- [Monorepo](#monorepo)
- [Getting started](#getting-started)
- [Shared components](#shared-components)
- [Installing packages](#installing-packages)
- [Development](#development)
- [Community channels](#community-channels)
## Development setup
## Getting started
Thanks for your interest in Supabase and for wanting to contribute! Before you begin, read the
Thanks for your interest in [Supabase](https://supabase.com) and for wanting to contribute! Before you begin, read the
[code of conduct](https://github.com/supabase/.github/blob/main/CODE_OF_CONDUCT.md) and check out the
[existing issues](https://github.com/supabase/supabase/issues).
This document describes how to set up your development environment to build and test Supabase.
This document describes how to set up your development environment to build and test [Supabase](https://supabase.com).
### Install dependencies
You need to install and configure the following dependencies on your machine to build Supabase:
You need to install and configure the following dependencies on your machine to build [Supabase](https://supabase.com):
- [Git](http://git-scm.com/)
- [Node.js v16.x (LTS)](http://nodejs.org)
- [npm](https://www.npmjs.com/) version 7+ or [Yarn](https://yarnpkg.com/)
## Local development
We are in the process of migrating this repository to monorepo, using [Turborepo](https://turborepo.org/docs).
Eventually, all the apps will be run using [Turborepo](https://turborepo.org/docs), which will significantly improve the developer workflow.
### Fork the repository
To contribute code to Supabase, you must fork the [Supabase Repository](https://github.com/supabase/supabase).
To contribute code to [Supabase](https://supabase.com), you must fork the [Supabase Repository](https://github.com/supabase/supabase).
## Build Supabase
### Clone the repo
1. Clone your GitHub forked repository:
@@ -52,104 +53,69 @@ To contribute code to Supabase, you must fork the [Supabase Repository](https://
cd supabase
```
### Choose a directory
### Running turborepo
Choose if you want to work on the [Supabase Website](https://supabase.com), [Supabase Docs](https://supabase.com/docs), or [Supabase Studio](https://app.supabase.com).
[Supabase](https://supabase.com) uses [Turborepo](https://turborepo.org/docs) to manage and run this monorepo.
1. Go to the [Supabase Website](https://supabase.com) directory
1. Install the dependencies in the root of the repo.
```sh
cd apps/www
npm install # install dependencies
```
Go to the [Supabase Docs](https://supabase.com/docs) directory
2. You can then run the apps simultaneously with the following.
```sh
cd apps/reference
npm run dev # start all the applications
```
Go to the [Supabase Studio](https://app.supabase.com) directory
Then visit, and edit, any of the following sites:
```sh
cd studio
```
| Site | Directory | Scope name | Description | Local development server |
| ---------------------------------------------- | ------------ | ---------- | ------------------------------------ | -------------------------- |
| [supabase.com](https://supabase.com) | `/apps/www` | www | The main website | http://localhost:3000 |
| [app.supabase.com](https://app.supabase.com) | `/studio` | studio | Studio dashboard | http://localhost:8082 |
| [supabase.com/docs](https://supabase.com/docs) | `/apps/docs` | docs | Guides and Reference (Next.js based) | http://localhost:3001/docs |
1. Install npm/yarn dependencies:
#### Running sites individually
npm
You can run any of the sites individually by using the scope name. For example:
```sh
npm install
```
```sh
npm run dev:www
```
or with yarn
#### Shared components
```sh
yarn install
```
The monorepo has a set of shared components under `/packages`:
## Start a development server
- `/packages/common`: Common React code, shared between all sites.
- `/packages/config`: All shared config
- `/packages/spec`: Generates documentation using spec files.
- `/packages/tsconfig`: Shared Typescript settings
To debug code and to see your changes in real time, it is often useful to have a local HTTP server. Click one of the three links below to choose which development server you want to start.
#### Installing packages
- [Supabase Website](#supabase-website)
- [Supabase Docs](#supabase-docs)
- [Supabase Studio](#supabase-studio)
Installing a package with NPM workspaces requires you to add the `-w` flag to tell NPM which workspace you want to install into. Do not install dependencies in their local folder, install them from the route using the `-w` flag.
### Supabase Website
The format is: `npm install <package name> -w=<workspace to install in>`.
The website is moving to a new monorepo setup. See the [Monorepo](#monorepo) section below.
For example:
### Supabase Docs
- `npm install react -w common`: installs into `./packages/common`
- `npm install react -w www`: installs into `./apps/www`
- `npm install react -w studio`: installs into `./studio`
1. Build development server
You do not need to install `devDependencies` in each workspace. These can all be installed in the root package.
npm
#### New Supabase docs
```sh
npm run build
```
Following the changes to the [Supabase docs](https://supabase.com/blog/new-supabase-docs-built-with-nextjs) the following is needed to run the new docs locally:
or with yarn
- Inside of `apps/docs` create a `.env.local` file with the following: `NEXT_PUBLIC_NEW_DOCS=true`
```sh
yarn build
```
Now when you run a local development docs server you will see the new docs site.
1. Start development server
npm
```sh
npm run start
```
or with yarn
```sh
yarn start
```
1. Access the local server in your web browser at http://localhost:3010/docs.
### Supabase Studio
1. Start development server
npm
```sh
npm run dev
```
or with yarn
```sh
yarn dev
```
1. Access the local server in your web browser at http://localhost:8082/.
See the [Supabase Studio readme](./studio/README.md) for more information.
---
## Create a pull request
@@ -163,58 +129,16 @@ Did you have an issue, like a merge conflict, or don't know how to open a pull r
### Add a redirect
Create a new entry in the [`next.config.js`](https://github.com/supabase/supabase/blob/master/apps/www/next.config.js) file in our main site.
## Monorepo
We are in the process of migrating this repository to monorepo, using Turborepo.
Eventually, the docs and the Studio will be run using Turborepo, which will significantly improve the developer workflow.
You must be using NPM 7 or higher.
### Getting started
```sh
npm install # install dependencies
npm run dev # start all the applications
```
Then edit and visit any of the following sites:
Site | Directory | Description | Local development server
---- | --------- | ----------- | ------------------------
[supabase.com](https://supabase.com) | `/apps/www` | The main website | http://localhost:3000
[supabase.com/docs](https://supabase.com/docs) | `apps/reference` | Guides and Reference documentaion | http://localhost:3010/docs
[POC] Community forum | `/apps/temp-community-forum` | GitHub Discussions in a Next.js site | http://localhost:3002
[POC] DEV articles site | `/apps/temp-community-tutorials` | A Next.js site for our DEV articles (which community members can write) | http://localhost:3003
### Shared components
The monorepo has a set of shared components under `/packages`:
- `/packages/common`: Common React code, shared between all sites.
- `/packages/config`: All shared config
- `/packages/spec`: Generates documentation using spec files.
- `/packages/tsconfig`: Shared Typescript settings
### Installing packages
Installing a package with NPM workspaces requires you to add the `-w` flag to tell NPM which workspace you want to install into.
The format is: `npm install <package name> -w=<workspace to install in>`.
For example:
- `npm install @supabase/ui -w common`: installs into `./packages/common`
- `npm install @supabase/ui -w www`: installs into `./apps/www`
You do not need to install `devDependencies` in each workspace. These can all be installed in the root package.
### Development
`npm run dev`
Create a new entry in the [`redirects.js`](https://github.com/supabase/supabase/blob/master/apps/www/lib/redirects.js) file in our main site.
---
## Community channels
Stuck somewhere? Have any questions? Join the [Discord Community Server](https://discord.supabase.com/) or the [Github Discussions](https://github.com/supabase/supabase/discussions). We are here to help!
## Contributors
<a href="https://github.com/supabase/supabase/graphs/contributors">
<img src="https://contributors.deno.dev/supabase/supabase?height=1200&width=1200&count=90" width="1200" height="1200" alt="contributors">
</a>
+1 -1
View File
@@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2022 Supabase
Copyright 2023 Supabase
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
+33 -24
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>
---
@@ -12,9 +12,9 @@
- [x] Hosted Postgres Database. [Docs](https://supabase.com/docs/guides/database)
- [x] Authentication and Authorization. [Docs](https://supabase.com/docs/guides/auth)
- [x] Auto-generated APIs.
- [x] REST. [Docs](https://supabase.com/docs/guides/api#rest-api)
- [x] Realtime subscriptions. [Docs](https://supabase.com/docs/guides/api#realtime-api)
- [x] GraphQL (Beta). [Docs](https://supabase.com/docs/guides/api#graphql-api)
- [x] REST. [Docs](https://supabase.com/docs/guides/database/api#rest-api)
- [x] Realtime subscriptions. [Docs](https://supabase.com/docs/guides/database/api#realtime-api)
- [x] GraphQL (Beta). [Docs](https://supabase.com/docs/guides/database/api#graphql-api)
- [x] Functions.
- [x] Database Functions. [Docs](https://supabase.com/docs/guides/database/functions)
- [x] Edge Functions [Docs](https://supabase.com/docs/guides/functions)
@@ -41,7 +41,7 @@ To see how to Contribute, visit [Getting Started](./DEVELOPERS.md)
- [x] Alpha: We are testing Supabase with a closed set of customers
- [x] Public Alpha: Anyone can sign up over at [app.supabase.com](https://app.supabase.com). But go easy on us, there are a few kinks
- [x] Public Beta: Stable enough for most non-enterprise use-cases
- [ ] Public: Production-ready
- [ ] Public: General Availability [[status](https://supabase.com/docs/guides/getting-started/features#feature-status)]
We are currently in Public Beta. Watch "releases" of this repo to get notified of major updates.
@@ -58,7 +58,7 @@ Supabase is a combination of open source tools. We’re building the features of
Supabase is a [hosted platform](https://app.supabase.com). You can sign up and start using Supabase without installing anything.
You can also [self-host](https://supabase.com/docs/guides/hosting/overview) and [develop locally](https://supabase.com/docs/guides/local-development).
![Architecture](https://user-images.githubusercontent.com/70828596/187547862-ffa9d058-0c3a-4851-a3e7-92ccfca4b596.png)
![Architecture](https://github.com/supabase/supabase/blob/master/apps/docs/public/img/supabase-architecture.png)
- [PostgreSQL](https://www.postgresql.org/) is an object-relational database system with over 30 years of active development that has earned it a strong reputation for reliability, feature robustness, and performance.
- [Realtime](https://github.com/supabase/realtime) is an Elixir server that allows you to listen to PostgreSQL inserts, updates, and deletes using websockets. Realtime polls Postgres' built-in replication functionality for database changes, converts changes to JSON, then broadcasts the JSON over websockets to authorized clients.
@@ -107,6 +107,15 @@ Our approach for client libraries is modular. Each sub-library is a standalone i
<td><a href="https://github.com/supabase/realtime-js" target="_blank" rel="noopener noreferrer">realtime-js</a></td>
<td><a href="https://github.com/supabase/storage-js" target="_blank" rel="noopener noreferrer">storage-js</a></td>
<td><a href="https://github.com/supabase/functions-js" target="_blank" rel="noopener noreferrer">functions-js</a></td>
</tr>
<tr>
<td>Flutter</td>
<td><a href="https://github.com/supabase/supabase-flutter" target="_blank" rel="noopener noreferrer">supabase-flutter</a></td>
<td><a href="https://github.com/supabase/postgrest-dart" target="_blank" rel="noopener noreferrer">postgrest-dart</a></td>
<td><a href="https://github.com/supabase/gotrue-dart" target="_blank" rel="noopener noreferrer">gotrue-dart</a></td>
<td><a href="https://github.com/supabase/realtime-dart" target="_blank" rel="noopener noreferrer">realtime-dart</a></td>
<td><a href="https://github.com/supabase/storage-dart" target="_blank" rel="noopener noreferrer">storage-dart</a></td>
<td><a href="https://github.com/supabase/functions-dart" target="_blank" rel="noopener noreferrer">functions-dart</a></td>
</tr>
<th colspan="7">💚 Community 💚</th>
<tr>
@@ -118,23 +127,14 @@ Our approach for client libraries is modular. Each sub-library is a standalone i
<td><a href="https://github.com/supabase-community/storage-csharp" target="_blank" rel="noopener noreferrer">storage-csharp</a></td>
<td><a href="https://github.com/supabase-community/functions-csharp" target="_blank" rel="noopener noreferrer">functions-csharp</a></td>
</tr>
<tr>
<td>Dart (Flutter)</td>
<td><a href="https://github.com/supabase/supabase-dart" target="_blank" rel="noopener noreferrer">supabase-dart</a></td>
<td><a href="https://github.com/supabase/postgrest-dart" target="_blank" rel="noopener noreferrer">postgrest-dart</a></td>
<td><a href="https://github.com/supabase/gotrue-dart" target="_blank" rel="noopener noreferrer">gotrue-dart</a></td>
<td><a href="https://github.com/supabase/realtime-dart" target="_blank" rel="noopener noreferrer">realtime-dart</a></td>
<td><a href="https://github.com/supabase/storage-dart" target="_blank" rel="noopener noreferrer">storage-dart</a></td>
<td><a href="https://github.com/supabase-community/functions-dart" target="_blank" rel="noopener noreferrer">functions-dart</a></td>
</tr>
<tr>
<td>Go</td>
<td>-</td>
<td><a href="https://github.com/supabase-community/postgrest-go" target="_blank" rel="noopener noreferrer">postgrest-go</a></td>
<td>-</td>
<td><a href="https://github.com/supabase-community/gotrue-go" target="_blank" rel="noopener noreferrer">gotrue-go</a></td>
<td>-</td>
<td><a href="https://github.com/supabase-community/storage-go" target="_blank" rel="noopener noreferrer">storage-go</a></td>
<td>-</td>
<td><a href="https://github.com/supabase-community/functions-go" target="_blank" rel="noopener noreferrer">functions-go</a></td>
</tr>
<tr>
<td>Java</td>
@@ -142,17 +142,17 @@ Our approach for client libraries is modular. Each sub-library is a standalone i
<td>-</td>
<td><a href="https://github.com/supabase-community/gotrue-java" target="_blank" rel="noopener noreferrer">gotrue-java</a></td>
<td>-</td>
<td>-</td>
<td><a href="https://github.com/supabase-community/storage-java" target="_blank" rel="noopener noreferrer">storage-java</a></td>
<td>-</td>
</tr>
<tr>
<td>Kotlin</td>
<td>-</td>
<td><a href="https://github.com/supabase-community/supabase-kt" target="_blank" rel="noopener noreferrer">supabase-kt</a></td>
<td><a href="https://github.com/supabase-community/postgrest-kt" target="_blank" rel="noopener noreferrer">postgrest-kt</a></td>
<td><a href="https://github.com/supabase-community/gotrue-kt" target="_blank" rel="noopener noreferrer">gotrue-kt</a></td>
<td>-</td>
<td>-</td>
<td>-</td>
<td><a href="https://github.com/supabase-community/supabase-kt/tree/master/Realtime" target="_blank" rel="noopener noreferrer">realtime-kt</a></td>
<td><a href="https://github.com/supabase-community/supabase-kt/tree/master/Storage" target="_blank" rel="noopener noreferrer">storage-kt</a></td>
<td><a href="https://github.com/supabase-community/supabase-kt/tree/master/Functions" target="_blank" rel="noopener noreferrer">functions-kt</a></td>
</tr>
<tr>
<td>Python</td>
@@ -188,7 +188,16 @@ Our approach for client libraries is modular. Each sub-library is a standalone i
<td><a href="https://github.com/supabase-community/gotrue-swift" target="_blank" rel="noopener noreferrer">gotrue-swift</a></td>
<td><a href="https://github.com/supabase-community/realtime-swift" target="_blank" rel="noopener noreferrer">realtime-swift</a></td>
<td><a href="https://github.com/supabase-community/storage-swift" target="_blank" rel="noopener noreferrer">storage-swift</a></td>
<td>-</td>
<td><a href="https://github.com/supabase-community/functions-swift" target="_blank" rel="noopener noreferrer">functions-swift</a></td>
</tr>
<tr>
<td>Godot Engine (GDScript)</td>
<td><a href="https://github.com/supabase-community/godot-engine.supabase" target="_blank" rel="noopener noreferrer">supabase-gdscript</a></td>
<td><a href="https://github.com/supabase-community/postgrest-gdscript" target="_blank" rel="noopener noreferrer">postgrest-gdscript</a></td>
<td><a href="https://github.com/supabase-community/gotrue-gdscript" target="_blank" rel="noopener noreferrer">gotrue-gdscript</a></td>
<td><a href="https://github.com/supabase-community/realtime-gdscript" target="_blank" rel="noopener noreferrer">realtime-gdscript</a></td>
<td><a href="https://github.com/supabase-community/storage-gdscript" target="_blank" rel="noopener noreferrer">storage-gdscript</a></td>
<td><a href="https://github.com/supabase-community/functions-gdscript" target="_blank" rel="noopener noreferrer">functions-gdscript</a></td>
</tr>
</table>
+1 -1
View File
@@ -1 +1 @@
apps/reference/static/.well-known/security.txt
apps/docs/public/.well-known/security.txt
-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 collataral 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 MiB

-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"
}
]
}
+11
View File
@@ -0,0 +1,11 @@
# PUBLIC
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
NEXT_PUBLIC_LOCAL_SUPABASE=false
File renamed without changes.
+23
View File
@@ -0,0 +1,23 @@
# Dependencies
/node_modules
# Production
/build
# Generated files
.cache-loader
# Misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
**/*/generated/**/*
!**/*/generated/.gitkeep
!**/*/generated/**/.gitkeep
+99
View File
@@ -0,0 +1,99 @@
# Developing Supabase Docs
## Getting started
Thanks for your interest in [Supabase docs](https://supabase.com/docs) and for wanting to contribute! Before you begin, read the
[code of conduct](https://github.com/supabase/.github/blob/main/CODE_OF_CONDUCT.md) and check out the
[existing issues](https://github.com/supabase/supabase/issues).
This document describes how to set up your development environment to contribute to [Supabase docs](https://supabase.com/docs).
For a complete run-down on how all of our tools work together, see the main DEVELOPERS.md. That readme describes how to get set up locally in lots of detail, including minimum requirements, our Turborepo setup, installing packages, sharing components across projects, and more. This readme deals specifically with the docs site.
## Local setup
[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. 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
[https://supabase.com/docs](https://supabase.com/docs) has several different kinds of documentation, all coming from different sources.
### Guides
The primary, instructional type of content. Basically anything that lives on the `https://supabase.com/docs/guides` route. This includes Guides for Auth, Database, Storage, Realtime, Edge Functions, as well as general resources, self-hosting instructions, and integrations. These are all [`.mdx`](https://mdxjs.com/) files — a combination of Markdown and Javascript.
#### Things to know
Here's a simple [example](https://supabase.com/docs/guides/functions) `.mdx` Guide, and here is [the source on Github](https://raw.githubusercontent.com/supabase/supabase/master/apps/docs/pages/guides/functions.mdx).
Some things to note:
1. The files need to import a Layout at the top
2. The files need to export a `Page` at the bottom with the `<Layout>` component
3. The files frontmatter is stored in `const meta = {}`. You should always include `title` and `description`.
4. You can write Markdown as you normally would, but you can also write regular Javascript and JSX. Note the `examples` array that we iterate over.
5. Any Javascript variables you use in these files need to be exported in order to be used (i.e., `export const examples = []`).
##### Using components
You can use any standard React components in these `.mdx` files without having to explicitly import them in each file. All components get imported in a [common components](https://github.com/supabase/supabase/blob/master/apps/docs/components/index.tsx) file and can be used in any `.mdx` file. Components can also be "intercepted" and modified via this file. Note how we're intercepting the `h2`, `h3` and `code` tags and modifying them before converting the `mdx` to `html`.
### Reference docs for client libraries
We maintain client libraries for [Javascript](https://supabase.com/docs/reference/javascript) and [Flutter/Dart](https://supabase.com/docs/reference/dart) (with more to come). These reference docs document every object and method available for developers to use. The are assembled from different sources and work much differently than the `.mdx` Guides we just looked at.
The client libraries are essentially wrappers around the clients for the various tools we use — GoTrue, PostgREST, Storage, Functions, and Realtime. The easiest way to describe how the things fit together is to look at an example and trace where the various pieces of information are coming from.
#### Example
Let's look at the `updateUser()` function in the `supabase-js` library.
#### Common file
Several pieces of information for this function come from a [common file](https://github.com/supabase/supabase/blob/3d774b3b7bcdcb410e25726d832467584ebea686/spec/common-client-libs-sections.json#L548) where we store information shared by all libraries.
1. id — used to identify this function
2. title - the human-readable title
3. slug — the url slug
4. product - the Supabase tool or product that "owns" this function. Since `updateUser()` is an auth function, its product is `auth`
5. type — `updateUser()` is a function and marked as such, but we can also have sections of markdown interspersed with these function definitions.
When a new function is added, this info would need to be manually added to the common file.
#### Function Parameters
The `updateUser()` function takes one parameter: `attributes`. The details for this parameter live in the GoTrue client library, referenced via a `$ref` property in the `supabase-js` [spec file](https://github.com/supabase/supabase/blob/cb04d85262db6a371539dda7df9b00ba5a901e87/spec/supabase_js_v2.yml#L357). Here, the `$ref` property is pointing to the [actual function definition](https://github.com/supabase/gotrue-js/blob/2d60e79073b96ae8c97a6ce18e2601ed1e2a2712/src/GoTrueClient.ts#L590) in the `gotrue-js` library. The accepted values for the `attributes` parameter come from the [type definition](https://github.com/supabase/gotrue-js/blob/16d3deb822097e8640a3a15b94a5690b3beaf11b/src/lib/types.ts#L233).
These individual library spec files are fetched via this [Makefile](https://github.com/supabase/supabase/blob/master/spec/Makefile), and get [transformed](https://github.com/supabase/supabase/blob/master/spec/enrichments/tsdoc_v2/supabase_dereferenced.json) to combine the information we need (params, types, etc). Unless you're a library maintainer, you shouldn't need to worry about this part of the process.
If you are a library maintainer, the last important note about these library files is that the [Makefile](https://github.com/supabase/supabase/blob/master/spec/Makefile) pulls from the `gh-pages` branch of the client library repo. Here's an example of the [`realtime-js` spec file](https://github.com/supabase/realtime-js/blob/gh-pages/v2/spec.json). Updating something like function params or returns, the process is:
1. Get your changes merged to `master` in your library
2. This will kick off an action that automatically updates the spec file in the library's `gh-pages` branch
3. Run `make` in `/spec` of the `supabase/supabase` repo. This will regenerate all of the `tsdoc` files that the docs site uses
4. You should now see the changes you've made in the docs site locally
#### Function Examples
The `updateUser()` function has three examples listed with it. The examples are stored along with the `$ref` property in the [supabase_js_v2 spec file](https://github.com/supabase/supabase/blob/master/spec/supabase_js_v2.yml).
#### Rendering in Next.JS
These reference docs are rendered by Next.JS via a dynamic route using a [`[...slug.tsx]`](https://github.com/supabase/supabase/blob/master/apps/docs/pages/reference/javascript/%5B...slug%5D.tsx). Here, we use the library [spec file](https://github.com/supabase/supabase/blob/bd0514553c627db8f1e8d0b3ae440ccb6759d228/apps/docs/pages/reference/javascript/%5B...slug%5D.tsx#L4) and the [common file](https://github.com/supabase/supabase/blob/bd0514553c627db8f1e8d0b3ae440ccb6759d228/apps/docs/pages/reference/javascript/%5B...slug%5D.tsx#L1) to output the info you see on the page.
### Other reference docs
The reference docs for the [Supabase Management API](https://supabase.com/docs/reference/api) and the [Supabase CLI](https://supabase.com/docs/reference/cli) are a little more straightforward than the client libraries. Both files also have a [common file](https://github.com/supabase/supabase/blob/master/spec/common-cli-sections.json) which handles things like `title`, `id` and `slug`. Both also have a spec file detailing things like parameters, descriptions, and responses ([Management API](https://github.com/supabase/supabase/blob/master/spec/api_v0_openapi.json) / [CLI](https://github.com/supabase/supabase/blob/master/spec/cli_v1_commands.yaml))
On the Next.JS side of things, these work almost exactly the same as the client libaries with a dynamic [`[...slug.tsx]`](https://github.com/supabase/supabase/blob/master/apps/docs/pages/reference/cli/%5B...slug%5D.tsx).
### Misc
#### Search
Search is handled through Algolia. When the site is built, a [search script](https://github.com/supabase/supabase/blob/master/apps/docs/scripts/build-search.ts) runs through all of the types of content, generating search objects that are sent to Algolia to index.
+45
View File
@@ -0,0 +1,45 @@
# Reference Docs
Supabase Reference Docs
## Maintainers
If you are a maintainer of any tools in the Supabase ecosystem, you can use this site to provide documentation for the tools & libraries that you maintain.
## Types of docs
There are many types of docs:
1. Guides: teach developers how to use a product. "I have XX problem, how do I solve it?"
2. Tutorials: walk-throughs, have a large outcome. "Build a React application with Supabase".
3. Explanations: teach developers about a broad topic. "What is a database?"
4. Reference: technical descriptions of tools and how to use them. "What errors does the API return?"
In these docs, you should focus only on the fourth type: "Reference Docs".
## Versioning
All tools have versioned docs, which are kept in separate folders. For example, the CLI has the following folders and files:
- `cli`: the "next" release.
- `cli_spec`: contains the DocSpec for the "next" release (see below).
- `cli_versioned_docs`: a version of the documentation for every release (including the most current version).
- `cli_versioned_sidebars`: a version of the sidebar for every release (including the most current version).
When you release a new version of a tool, you should also release a new version of the docs. You can do this via the command line. For example, if you just released the CLI version `1.0.1`:
```
npm run cli:version 1.0.1
```
## DocSpec
We use documentation specifications which can be used to generate human-readable docs.
- OpenAPI: for documenting API endpoints.
- SDKSpec (custom to Supabase): for SDKs and client libraries.
- ConfigSpec (custom to Supabase): for configuration options.
- CLISpec (custom to Supabase): for CLI commands and usage.
The benefit of using custom specifications is that we can generate many other types from a strict schema (eg, HTML and manpages).
It also means that we can switch any documentation system we want. On this site we use Next.JS, but in Supabase's official website we use a custom React site and expose only a subset of the available API for each tool.
+372
View File
@@ -0,0 +1,372 @@
module.exports = {
name: 'Stripe Docs Blue',
type: 'dark',
colors: {
'editor.background': '#232323',
'editor.foreground': '#fafafa',
'activityBar.background': 'var(--colors-scale2)',
'sideBar.background': 'yellow',
'editorGroupHeader.tabsBackground': 'var(--colors-scale2)',
'sideBarSectionHeader.background': 'var(--colors-scale2)',
'tab.activeBackground': 'var(--colors-scale3)',
'tab.inactiveBackground': 'var(--colors-scale2)',
'tab.border': 'var(--colors-scale2)',
'input.background': '#ffffff1a',
'panel.background': '#1A2652',
'panel.border': '#1A2652',
'editorWidget.background': '#0d0f2b',
'editorWidget.foreground': '#ffffff4d',
'editorWidget.border': 'var(--colors-scale5)',
'list.hoverBackground': '#ffffff1a',
'list.activeSelectionBackground': '#ffffff1a',
'list.inactiveSelectionBackground': '#ffffff1a',
'editor.hoverHighlightBackground': '#ffffff1a',
'editor.selectionHighlightBackground': '#ffffff1a',
'activityBarBadge.background': 'yellow',
'sideBarTitle.foreground': 'var(--colors-scale2)',
'statusBar.background': 'var(--colors-scale2)',
},
tokenColors: [
{
name: 'Comment',
scope: ['comment', 'punctuation.definition.comment'],
settings: {
foreground: '#a3acb9',
fontStyle: '',
},
},
{
name: 'Variables',
scope: ['source', 'variable', 'variable.other.object', 'string constant.other.placeholder'],
settings: {
foreground: '#f5fbff',
},
},
{
name: 'Colors',
scope: ['variable.other.constant', 'constant.other.color'],
settings: {
foreground: '#ffffff',
fontStyle: 'bold',
},
},
{
name: 'Invalid',
scope: ['invalid', 'invalid.illegal'],
settings: {
foreground: '#FF5370',
},
},
{
name: 'Keyword, Storage',
scope: ['keyword', 'storage.type', 'storage.modifier'],
settings: {
foreground: '#98C1FE',
fontStyle: 'bold',
},
},
{
name: 'Function',
scope: ['entity.name.function'],
settings: {
foreground: '#7fd3ed',
fontStyle: 'bold',
},
},
{
name: 'Tag',
scope: ['entity.name.tag', 'meta.tag.sgml', 'markup.deleted.git_gutter'],
settings: {
foreground: '#98C1FE',
fontStyle: 'bold',
},
},
{
name: 'Parameter, Property',
scope: [
'variable.parameter',
'variable.other.object.property',
'variable.other.property',
'keyword.other.unit',
'keyword.other',
],
settings: {
foreground: '#F2AFE3',
},
},
{
name: 'Number, Constant, Function Argument, Tag Attribute, Embedded',
scope: [
'constant.numeric',
'constant.language',
'support.constant',
'constant.character',
'constant.escape',
],
settings: {
foreground: '#f8b886',
},
},
{
name: 'String, Symbols, Inherited Class, Markup Heading',
scope: [
'string',
'constant.other.symbol',
'constant.other.key',
'entity.other.inherited-class',
'markup.heading',
'markup.inserted.git_gutter',
'meta.group.braces.curly constant.other.object.key.js string.unquoted.label.js',
],
settings: {
foreground: '#85d99e',
},
},
{
name: 'Entity Types',
scope: ['support.type'],
settings: {
foreground: '#B2CCD6',
},
},
{
name: 'CSS Class and Support',
scope: [
'source.css support.type.property-name',
'source.sass support.type.property-name',
'source.scss support.type.property-name',
'source.less support.type.property-name',
'source.stylus support.type.property-name',
'source.postcss support.type.property-name',
],
settings: {
foreground: '#B2CCD6',
},
},
{
name: 'Language methods',
scope: ['variable.language'],
settings: {
fontStyle: 'italic',
foreground: '#FF5370',
},
},
{
name: 'Attributes',
scope: ['entity.other.attribute-name'],
settings: {
foreground: '#98C1FE',
fontStyle: 'italic',
},
},
{
name: 'Inserted',
scope: ['markup.inserted'],
settings: {
foreground: '#C3E88D',
},
},
{
name: 'Deleted',
scope: ['markup.deleted'],
settings: {
foreground: '#FF5370',
},
},
{
name: 'Changed',
scope: ['markup.changed'],
settings: {
foreground: '#C792EA',
},
},
{
name: 'Regular Expressions',
scope: ['string.regexp'],
settings: {
foreground: '#89DDFF',
},
},
{
name: 'Escape Characters',
scope: ['constant.character.escape'],
settings: {
foreground: '#89DDFF',
},
},
{
name: 'URL',
scope: ['*url*', '*link*', '*uri*'],
settings: {
fontStyle: 'underline',
},
},
{
name: 'ES7 Bind Operator',
scope: ['source.js constant.other.object.key.js string.unquoted.label.js'],
settings: {
fontStyle: 'italic',
foreground: '#FF5370',
},
},
{
name: 'Markdown - Plain',
scope: ['text.html', 'punctuation.definition.list_item'],
settings: {
foreground: '#f5fbff',
},
},
{
name: 'Markdown - Markup Raw Inline',
scope: ['text.html.markdown markup.inline.raw.markdown'],
settings: {
foreground: '#C792EA',
},
},
{
name: 'Markdown - Markup Raw Inline Punctuation',
scope: ['text.html.markdown markup.inline.raw.markdown punctuation.definition.raw.markdown'],
settings: {
foreground: '#65737E',
},
},
{
name: 'Markdown - Heading',
scope: [
'markdown.heading',
'markup.heading | markup.heading entity.name',
'markup.heading.markdown punctuation.definition.heading.markdown',
],
settings: {
foreground: '#C3E88D',
},
},
{
name: 'Markup - Italic',
scope: ['markup.italic'],
settings: {
fontStyle: 'italic',
foreground: '#f07178',
},
},
{
name: 'Markup - Bold',
scope: ['markup.bold', 'markup.bold string'],
settings: {
fontStyle: 'bold',
foreground: '#f07178',
},
},
{
name: 'Markup - Bold-Italic',
scope: [
'markup.bold markup.italic',
'markup.italic markup.bold',
'markup.quote markup.bold',
'markup.bold markup.italic string',
'markup.italic markup.bold string',
'markup.quote markup.bold string',
],
settings: {
fontStyle: 'bold',
foreground: '#f07178',
},
},
{
name: 'Markup - Underline',
scope: ['markup.underline'],
settings: {
fontStyle: 'underline',
foreground: '#F78C6C',
},
},
{
name: 'Markdown - Blockquote',
scope: ['markup.quote punctuation.definition.blockquote.markdown'],
settings: {
foreground: '#65737E',
},
},
{
name: 'Markup - Quote',
scope: ['markup.quote'],
settings: {
fontStyle: 'italic',
},
},
{
name: 'Markdown - Link Description',
scope: ['string.other.link.description.title.markdown'],
settings: {
foreground: '#C792EA',
},
},
{
name: 'Markdown - Link Anchor',
scope: ['constant.other.reference.link.markdown'],
settings: {
foreground: '#FFCB6B',
},
},
{
name: 'Markup - Raw Block',
scope: ['markup.raw.block'],
settings: {
foreground: '#C792EA',
},
},
{
name: 'Markdown - Raw Block Fenced',
scope: ['markup.raw.block.fenced.markdown'],
settings: {
foreground: '#00000050',
},
},
{
name: 'Markdown - Fenced Bode Block',
scope: ['punctuation.definition.fenced.markdown'],
settings: {
foreground: '#00000050',
},
},
{
name: 'Markdown - Fenced Bode Block Variable',
scope: [
'markup.raw.block.fenced.markdown',
'variable.language.fenced.markdown',
'punctuation.section.class.end',
],
settings: {
foreground: '#EEFFFF',
},
},
{
name: 'Markdown - Fenced Language',
scope: ['variable.language.fenced.markdown'],
settings: {
foreground: '#65737E',
},
},
{
name: 'Markdown - Separator',
scope: ['meta.separator'],
settings: {
fontStyle: 'bold',
foreground: '#65737E',
},
},
{
name: 'Markup - Table',
scope: ['markup.table'],
settings: {
foreground: '#EEFFFF',
},
},
],
}
+51
View File
@@ -0,0 +1,51 @@
import { FC } from 'react'
import { IconInfo, IconHelpCircle, IconAlertTriangle } from 'ui'
interface Props {
type: 'note' | 'tip' | 'info' | 'caution' | 'danger'
label?: string
children: any
}
const Admonition: FC<Props> = ({ type = 'note', label, children }) => {
return (
<div
className={[
'shadow p-4 rounded border-l-[5px] space-y-2 my-4',
`${
type === 'note'
? 'bg-scale-400 border-scale-800'
: type === 'info'
? 'bg-scale-500 border-scale-800'
: type === 'tip'
? 'bg-brand-300 border-brand-800'
: type === 'caution'
? 'bg-yellow-400 border-yellow-800'
: type === 'danger'
? 'bg-red-500 border-red-800'
: 'bg-scale-500 border-scale-800'
}`,
].join(' ')}
>
<div className="flex items-center space-x-2">
{type === 'note' ? (
<IconInfo className="text-scale-1200" size={18} strokeWidth={1.5} />
) : type === 'info' ? (
<IconInfo className="text-scale-1200" size={18} strokeWidth={1.5} />
) : type === 'tip' ? (
<IconHelpCircle className="text-scale-1200" size={18} strokeWidth={1.5} />
) : type === 'caution' ? (
<IconAlertTriangle className="text-scale-1200" size={18} strokeWidth={1.5} />
) : type === 'danger' ? (
<IconAlertTriangle className="text-scale-1200" size={18} strokeWidth={1.5} />
) : (
<IconInfo className="text-scale-1200" size={18} strokeWidth={1.5} />
)}
<p className="text-sm text-scale-1200 uppercase my-0 font-bold">{label || type}</p>
</div>
<div className="admonition-content text-scale-1200 text-base space-y-1">{children}</div>
</div>
)
}
export default Admonition
+21
View File
@@ -0,0 +1,21 @@
import providers from '../data/authProviders'
import { IconPanel } from 'ui'
import Link from 'next/link'
export default function AuthProviders({ type }: { type: string }) {
const filterProviders = providers.filter((item) => item.authType === type)
return (
<>
<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>
</>
)
}
+55
View File
@@ -0,0 +1,55 @@
import React, { FC, ReactNode } from 'react'
import Link from 'next/link'
import Image from 'next/image'
interface Props {
title: string
description?: string
to: string
icon?: string | any
children?: any
layout?: 'vertical' | 'horizontal'
}
const ButtonCard: FC<Props> = ({
children = undefined,
icon = undefined,
title,
description = '',
to,
layout = 'vertical',
}) => {
return (
<Link href={to}>
<a
className={[
'h-full block shadow-none bg-scale-300 rounded transition',
'border border-transparent hover:border-scale-600',
].join(' ')}
>
{children ? (
children
) : (
<div
className={[
'px-6 py-4 gap-x-4 gap-y-2 flex',
`${layout === 'vertical' ? 'flex-col' : 'items-center'}`,
].join(' ')}
>
{icon && typeof icon == 'string' ? (
<div className="w-[24px] h-[24px]">
<Image className="m-0" src={icon} width={24} height={24} alt={title} />
</div>
) : (
icon
)}
<h3 className="my-0 text-base text-scale-1200">{title}</h3>
<p className="my-0 text-sm">{description}</p>
</div>
)}
</a>
</Link>
)
}
export default ButtonCard
+22
View File
@@ -0,0 +1,22 @@
import { FC } from 'react'
import { IconSearch } from '~/../../packages/ui'
// [Terry] — delete this after development
// just for making it easy to see where things are coming from
interface Props {
link: string
text: string
className?: string
}
export const ComesFrom: FC<Props> = ({ link, text, className }) => {
return (
<div className={`comes-from text-xs flex items-center gap-2 -mb-6 ${className}`}>
<span className="uppercase bg-slate-100 p-1 text-slate-600 flex gap-2 items-center">
<IconSearch size={14} />
Comes from:
</span>
<a className="text-slate-600 no-underline hover:underline" href={link}>
{text}
</a>
</div>
)
}
@@ -0,0 +1,95 @@
// Check if heading has custom anchor first, before forming the anchor based on the title
export const getAnchor = (text: any): string | undefined => {
if (typeof text === 'object') {
if (Array.isArray(text)) {
const customAnchor = text.find(
(x) => typeof x === 'string' && x.includes('[#') && x.endsWith(']')
)
if (customAnchor !== undefined) return customAnchor.slice(2, customAnchor.indexOf(']'))
const formattedText = text
.map((x) => {
if (typeof x !== 'string') return x.props.children
else return x.trim()
})
.map((x) => {
if (typeof x !== 'string') return x
else
return x
.toLowerCase()
.replace(/[^a-z0-9- ]/g, '')
.replace(/[ ]/g, '-')
})
return formattedText.join('-').toLowerCase()
} else {
const anchor = text.props.children
if (typeof anchor === 'string') {
return anchor
.toLowerCase()
.replace(/[^a-z0-9- ]/g, '')
.replace(/[ ]/g, '-')
}
return anchor
}
} else if (typeof text === 'string') {
if (text.includes('[#') && text.endsWith(']')) {
return text.slice(text.indexOf('[#') + 2, text.indexOf(']'))
} else {
return text
.toLowerCase()
.replace(/[^a-z0-9- ]/g, '')
.replace(/[ ]/g, '-')
}
} else {
return undefined
}
}
export const removeAnchor = (text: any) => {
if (typeof text === 'object' && Array.isArray(text)) {
return text.filter((x) => !(typeof x === 'string' && x.includes('[#') && x.endsWith(']')))
} else if (typeof text === 'string') {
if (text.indexOf('[#') > 0) return text.slice(0, text.indexOf('[#'))
else return text
}
return text
}
export const highlightSelectedTocItem = (id: string) => {
const tocMenuItems = document.querySelectorAll('.toc-menu a')
// find any currently active items and remove them
const currentActiveItem = document.querySelector('.toc-menu .toc__menu-item--active')
currentActiveItem?.classList.remove('toc__menu-item--active')
// Add active class to the current item
tocMenuItems.forEach((item) => {
// @ts-ignore
if (item.href.split('#')[1] === id) {
item.classList.add('toc__menu-item--active')
}
})
}
// find any currently active items and remove them on route change
export const unHighlightSelectedTocItems = () => {
const currentActiveItem = document.querySelector('.toc-menu .toc__menu-item--active')
currentActiveItem?.classList.remove('toc__menu-item--active')
}
export const highlightSelectedNavItem = (id: string) => {
const navMenuItems = document.querySelectorAll('.function-link-item a')
// find any currently active items and remove them
const currentActiveItems = document.querySelectorAll('.function-link-list .text-brand-900')
currentActiveItems.forEach((item) => item.classList.remove('text-brand-900'))
// Add active class to the current item
navMenuItems.forEach((item) => {
// @ts-ignore
if (item.href.split('/').at(-1) === id) {
item.classList.add('text-brand-900')
}
})
}
@@ -0,0 +1,56 @@
import {
getAnchor,
removeAnchor,
highlightSelectedTocItem,
unHighlightSelectedTocItems,
} from './CustomHTMLElements.utils'
import { useInView } from 'react-intersection-observer'
/**
* [Joshen] The trick with rootMargin
* We are shrinking the top of the root element by 20 percent, which is currently our entire page,
* and the bottom by 35 percent. Therefore, when a header is at the top 20 percent and bottom 35 percent
* of our page, it will not be counted as visible.
*/
interface Props {
tag?: string
parseAnchors?: boolean
customAnchor?: string
}
/**
* This TOC is used in .mdx files and in .tsx files.
* In mdx files, we need to parse the content and format them to match the
* 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. Custom anchors are used in tsx files.
* (see: /pages/reference/cli/config.tsx)
*/
const Heading: React.FC<Props> = ({ tag, customAnchor, children }) => {
const HeadingTag = `${tag}` as any
const anchor = customAnchor ? customAnchor : getAnchor(children)
const link = `#${anchor}`
const { ref } = useInView({
threshold: 1,
rootMargin: '-20% 0% -35% 0px',
onChange: (inView, entry) => {
if (window.scrollY === 0) unHighlightSelectedTocItems()
if (inView) highlightSelectedTocItem(entry.target.id)
},
})
return (
<HeadingTag id={anchor} ref={ref} className="group scroll-mt-24">
{removeAnchor(children)}
{anchor && (
<a href={link} className="ml-2 opacity-0 group-hover:opacity-100 transition">
#
</a>
)}
</HeadingTag>
)
}
export default Heading
@@ -0,0 +1,13 @@
import { FC } from 'react'
const InlineCodeTag = ({ children }: any) => {
// If children isn't a string, just return it as is, just in case
if (typeof children !== 'string') return children
// check the length of the string inside the <code> tag
// if it's fewer than 70 characters, add a white-space: pre so it doesn't wrap
const className = children.length < 70 ? 'short-inline-codeblock' : ''
return <code className={className}> HELLO WORLD {children}</code>
}
export default InlineCodeTag
@@ -0,0 +1,3 @@
import Heading from './Heading'
export { Heading }
+141
View File
@@ -0,0 +1,141 @@
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={`${
extension.link
? `/guides/database/extensions/${extension.name}`
: '/guides/database/extensions#full-list-of-extensions'
}`}
>
<a target={`${extension.link ? '_blank' : '_self'}`} 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>
</>
)
}
+38
View File
@@ -0,0 +1,38 @@
import Head from 'next/head'
import { useRouter } from 'next/router'
const Favicons = () => {
const { basePath } = useRouter()
return (
<Head>
<link
rel="apple-touch-icon"
sizes="180x180"
href={`${basePath}/favicon/apple-touch-icon.png`}
/>
<link
rel="icon"
type="image/png"
sizes="32x32"
href={`${basePath}/favicon/favicon-32x32.png`}
/>
<link
rel="icon"
type="image/png"
sizes="16x16"
href={`${basePath}/favicon/favicon-16x16.png`}
/>
<link rel="manifest" href={`${basePath}/favicon/site.webmanifest`} />
{/* <link rel="mask-icon" href={`${basePath}/favicon/safari-pinned-tab.svg`} color="#333333" /> */}
<link rel="shortcut icon" href={`${basePath}/favicon/favicon.ico`} />
<meta name="msapplication-TileColor" content="#1E1E1E" />
<meta name="msapplication-config" content={`${basePath}/favicon/browserconfig.xml`} />
<meta name="theme-color" content="#1E1E1E" />
<link rel="alternate" type="application/rss+xml" href={`${basePath}/feed.xml`} />
<link rel="icon" type="image/png" href={`${basePath}/favicon/favicon.ico`} />
<link rel="apple-touch-icon" href={`${basePath}/favicon/favicon.ico`} />
</Head>
)
}
export default Favicons
+17
View File
@@ -0,0 +1,17 @@
import React, { ReactNode } from 'react'
import { useFlag } from '~/hooks/useFlag'
interface Props {
children: ReactNode
name: string
}
function Flag({ children, name }: Props) {
const flagValue = useFlag(name)
if (!flagValue) {
return null
}
return <>{children}</>
}
export default Flag
+5
View File
@@ -0,0 +1,5 @@
import { createContext } from 'react'
const FlagContext = createContext({})
export default FlagContext
@@ -0,0 +1,35 @@
import { FC, useEffect, useState } from 'react'
// import createConfigCatClient from 'configcat-js'
import FlagContext from './FlagContext'
const FlagProvider: FC = ({ children }) => {
const [store, setStore] = useState({})
const { Provider } = FlagContext
// useEffect(() => {
// getFlags()
// }, [])
// 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)
// }
// const client = createConfigCatClient(process.env.NEXT_PUBLIC_CONFIGCAT_SDK_KEY ?? '', {
// configChanged: setFlagValues,
// pollIntervalSeconds: 600,
// })
// await setFlagValues()
// }
return <Provider value={store}>{children}</Provider>
}
export default FlagProvider
@@ -0,0 +1,41 @@
import { ReactMarkdown } from 'react-markdown/lib/react-markdown'
export type FooterHelpCalloutType = 'default' | 'postgres'
const content = {
default: {
title: 'Need some help?',
description: `Not to worry, our specialist engineers are here to help. Submit a support ticket through the [Dashboard](https://app.supabase.com/support/new).`,
},
postgres: {
title: 'Looking for Serverless Postgres?',
description: `Supabase is the fastest way to get started with Postgres in a serverless environment. [Learn more](https://supabase.com/database?utm=postgres-helpers).`,
},
}
const FooterHelpCallout = ({
footerHelpType = 'default',
title,
}: {
footerHelpType: FooterHelpCalloutType
title: any
}) => {
return (
<div className="mt-32 prose prose--remove-p-margin max-w-none">
<div
className="
min-w-full
px-8 py-6
bg-scale-300 dark:bg-whiteA-200
rounded
text-sm text-scale-900
"
>
<h5 className="text-sm text-scale-1100 m-0">{content[footerHelpType].title}</h5>
<ReactMarkdown>{content[footerHelpType].description}</ReactMarkdown>
</div>
</div>
)
}
export default FooterHelpCallout
+106
View File
@@ -0,0 +1,106 @@
import ButtonCard from './ButtonCard'
import { useTheme } from 'common/Providers'
const Frameworks = () => {
const { isDarkMode } = useTheme()
const frameworks = [
{
name: 'Angular',
logo: {
light: '/docs/img/icons/angular-icon.svg',
dark: '/docs/img/icons/angular-icon.svg',
},
href: '/guides/with-angular',
},
{
name: 'Expo',
logo: {
light: '/docs/img/icons/expo-icon.svg',
dark: '/docs/img/icons/expo-icon-dark.svg',
},
href: '/guides/with-expo',
},
{
name: 'Flutter',
logo: {
light: '/docs/img/icons/flutter-icon.svg',
dark: '/docs/img/icons/flutter-icon.svg',
},
href: '/guides/with-flutter',
},
{
name: 'JavaScript',
logo: {
light: '/docs/img/icons/javascript-icon.svg',
dark: '/docs/img/icons/javascript-icon.svg',
},
href: '/reference/javascript/installing#javascript',
},
{
name: 'Next.js',
logo: {
light: '/docs/img/icons/nextjs-light-icon.svg',
dark: '/docs/img/icons/nextjs-dark-icon.svg',
},
href: '/guides/with-nextjs',
},
{
name: 'React',
logo: {
light: '/docs/img/icons/react-icon.svg',
dark: '/docs/img/icons/react-icon.svg',
},
href: '/guides/with-react',
},
{
name: 'RedwoodJS',
logo: {
light: '/docs/img/icons/redwoodjs-icon.svg',
dark: '/docs/img/icons/redwoodjs-icon.svg',
},
href: '/guides/with-redwoodjs',
},
{
name: 'SolidJS',
logo: {
light: '/docs/img/icons/solidjs-icon.svg',
dark: '/docs/img/icons/solidjs-icon.svg',
},
href: '/guides/with-solidjs',
},
{
name: 'Svelte',
logo: {
light: '/docs/img/icons/svelte-icon.svg',
dark: '/docs/img/icons/svelte-icon.svg',
},
href: '/guides/with-svelte',
},
{
name: 'Vue',
logo: {
light: '/docs/img/icons/vuejs-icon.svg',
dark: '/docs/img/icons/vuejs-icon.svg',
},
href: '/guides/with-vue-3',
},
]
return (
<div className="grid md:grid-cols-12 gap-4 not-prose">
{frameworks.map((x) => (
<div key={x.name} className="col-span-3">
<ButtonCard
layout="horizontal"
to={x.href}
title={x.name}
// [Joshen] Nice to have: theming
icon={isDarkMode ? x.logo.dark : x.logo.light}
/>
</div>
))}
</div>
)
}
export default Frameworks
@@ -0,0 +1,64 @@
import ButtonCard from 'components/ButtonCard'
const examples = [
{
name: 'With supabase-js',
description: 'Use the Supabase client inside your Edge Function.',
href: 'https://github.com/supabase/supabase/blob/master/examples/edge-functions/supabase/functions/select-from-table-with-auth-rls/index.ts',
},
{
name: 'With CORS headers',
description: 'Send CORS headers for invoking from the browser.',
href: 'https://github.com/supabase/supabase/blob/master/examples/edge-functions/supabase/functions/browser-with-cors/index.ts',
},
{
name: 'React Native with Stripe',
description: 'Full example for using Supabase and Stripe, with Expo.',
href: 'https://github.com/supabase-community/expo-stripe-payments-with-supabase-functions',
},
{
name: 'Flutter with Stripe',
description: 'Full example for using Supabase and Stripe, with Flutter.',
href: 'https://github.com/supabase-community/flutter-stripe-payments-with-supabase-functions',
},
{
name: 'Building a RESTful Service API',
description:
'Learn how to use HTTP methods and paths to build a RESTful service for managing tasks.',
href: 'https://github.com/supabase/supabase/blob/master/examples/edge-functions/supabase/functions/restful-tasks/index.ts',
},
{
name: 'Working with Supabase Storage',
description: 'An example on reading a file from Supabase Storage.',
href: 'https://github.com/supabase/supabase/blob/master/examples/edge-functions/supabase/functions/read-storage/index.ts',
},
{
name: 'Open Graph Image Generation',
description: 'Generate Open Graph images with Deno and Supabase Edge Functions.',
href: '/guides/functions/examples/og-image',
},
{
name: 'OG Image Generation & Storage CDN Caching',
description: 'Cache generated images with Supabase Storage CDN.',
href: 'https://github.com/supabase/supabase/tree/master/examples/edge-functions/supabase/functions/og-image-with-storage-cdn',
},
{
name: 'Get User Location',
description: `Get user location data from user's IP address.`,
href: 'https://github.com/supabase/supabase/tree/master/examples/edge-functions/supabase/functions/location',
},
]
const FunctionsExamples = () => {
return (
<div className="grid md:grid-cols-12 gap-4">
{examples.map((x) => (
<div className="col-span-6">
<ButtonCard to={x.href} title={x.name} description={x.description} />
</div>
))}
</div>
)
}
export default FunctionsExamples
+17
View File
@@ -0,0 +1,17 @@
import React from 'react'
export default function GithubCard({ title, description, href, stars, handle }) {
return (
<a className="h-full" href={href}>
<div className="card__body">
<h4 className="uppercase my-2 font-semibold">{title}</h4>
<span className="text-sm">{description}</span>
</div>
<hr className="my-2" />
<div className="flex justify-between py-2 text-xs">
<div>@{handle}</div>
<div>{stars} ★</div>
</div>
</a>
)
}
@@ -0,0 +1,58 @@
import { FC } from 'react'
import { removeAnchor } from './CustomHTMLElements/CustomHTMLElements.utils'
const formatSlug = (slug: string) => {
// [Joshen] We will still provide support for headers declared like this:
// ## REST API {#rest-api-overview}
// At least for now, this was a docusaurus thing.
if (slug.includes('#')) return slug.split('#')[1]
return slug
}
const formatTOCHeader = (content: string) => {
let begin = false
const res = []
for (const x of content) {
if (x === '`') {
if (!begin) {
begin = true
res.push(`<code class="text-xs border rounded bg-scale-400 border-scale-500">`)
} else {
begin = false
res.push(`</code>`)
}
} else {
res.push(x)
}
}
return res.join('')
}
interface TOCHeader {
id: number
level: number
text: string
link: string
}
interface Props {
list: TOCHeader[]
}
const GuidesTableOfContents: FC<Props> = ({ list }) => {
return (
<ul className="toc-menu list-none pl-5 text-[0.8rem] grid gap-2">
{list.map((item, i) => (
<li key={`${item.level}-${i}`} className={item.level === 3 ? 'ml-4' : ''}>
<a
href={`#${formatSlug(item.link)}`}
className="text-scale-1000 hover:text-brand-900 transition-colors"
dangerouslySetInnerHTML={{ __html: formatTOCHeader(removeAnchor(item.text)) }}
/>
</li>
))}
</ul>
)
}
export default GuidesTableOfContents
+90
View File
@@ -0,0 +1,90 @@
import React, { useState } from 'react'
import KJUR from 'jsrsasign'
import { Button, Select, Input, CodeBlock } from 'ui'
const JWT_HEADER = { alg: 'HS256', typ: 'JWT' }
const now = new Date()
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate())
const fiveYears = new Date(now.getFullYear() + 5, now.getMonth(), now.getDate())
const anonToken = `
{
"role": "anon",
"iss": "supabase",
"iat": ${Math.floor(today / 1000)},
"exp": ${Math.floor(fiveYears / 1000)}
}
`.trim()
const serviceToken = `
{
"role": "service_role",
"iss": "supabase",
"iat": ${Math.floor(today / 1000)},
"exp": ${Math.floor(fiveYears / 1000)}
}
`.trim()
export default function JwtGenerator({}) {
const secret = [...Array(40)].map(() => Math.random().toString(36)[2]).join('')
const [jwtSecret, setJwtSecret] = useState(secret)
const [token, setToken] = useState(anonToken)
const [signedToken, setSignedToken] = useState('')
const handleKeySelection = (e) => {
const val = e.target.value
if (val == 'service') setToken(serviceToken)
else setToken(anonToken)
}
const generate = () => {
const signedJWT = KJUR.jws.JWS.sign(null, JWT_HEADER, token, jwtSecret)
setSignedToken(signedJWT)
}
return (
<div>
<div className="grid mb-8">
<label for="secret">JWT Secret:</label>
<Input
id="secret"
type="text"
placeholder="JWT Secret (at least 32 characters)"
value={jwtSecret}
onChange={(e) => setJwtSecret(e.target.value)}
/>
</div>
<div className="grid mb-8">
<label for="service">Preconfigured Payload:</label>
<Select id="service" onChange={handleKeySelection}>
<Select.Option value="anon">ANON_KEY</Select.Option>
<Select.Option value="service">SERVICE_KEY</Select.Option>
</Select>
</div>
<div className="grid mb-8">
<label for="token">Payload:</label>
<Input.TextArea
id="token"
type="text"
rows="5"
placeholder="A valid JWT Token"
value={token}
onChange={(e) => setToken(e.target.value)}
/>
</div>
<Button type="primary" onClick={generate}>
Generate JWT
</Button>
{signedToken && (
<div className="mt-8">
<h4>Generated Token:</h4>
<CodeBlock language="bash" className="relative">
{signedToken}
</CodeBlock>
</div>
)}
</div>
)
}
@@ -9,7 +9,7 @@ export default function LinkCard({
}: {
title: string
description: string
icon: ReactElement
icon: any
link: string
}) {
return (
@@ -1,5 +1,5 @@
import { ReactElement } from 'react'
export default function LinkCardsWrapper({ children }: { children: ReactElement }) {
export default function LinkCardsWrapper({ children }: { children: any }) {
return <div className="flex w-full flex-col lg:flex-row lg:flex-wrap">{children}</div>
}
@@ -0,0 +1,45 @@
import UserManagementSQLTemplate from './user_management_quickstart_sql_template.mdx'
import { Tabs } from 'ui'
export const TabPanel = Tabs.Panel
## Project setup
Before we start building we're going to set up our Database and API. This is as simple as starting a new Project in Supabase and then creating a "schema" inside the database.
### Create a project
1. [Create a new project](https://app.supabase.com) in the Supabase Dashboard.
1. Enter your project details.
1. Wait for the new database to launch.
### Set up the database schema
Now we are going to set up the database schema. We can use the "User Management Starter" quickstart in the SQL Editor, or you can just copy/paste the SQL from below and run it yourself.
<Tabs
scrollable
size="small"
type="underlined"
defaultActiveId="dashboard"
>
<TabPanel id="dashboard" label="Dashboard">
1. Go to the [SQL Editor](https://app.supabase.com/project/_/sql) page in the Dashboard.
2. Click **User Management Starter**.
3. Click **Run**.
</TabPanel>
<TabPanel id="sql" label="SQL">
<UserManagementSQLTemplate />
</TabPanel>
</Tabs>
### Get the API Keys
Now that you've created some database tables, you are ready to insert data using the auto-generated API.
We just need to get the Project URL and `anon` key from the API settings.
1. Go to the [API Settings](https://app.supabase.com/project/_/settings/api) page in the Dashboard.
1. Find your Project `URL`, `anon`, and `service_role` keys on this page.
@@ -0,0 +1,5 @@
This tutorial demonstrates how to build a basic user management app. The app authenticates and identifies the user, stores their profile information in the database, and allows the user to log in, update their profile details, and upload a profile photo. The app uses:
- [Supabase Database](/docs/guides/database) - a Postgres database for storing your user data and [Row Level Security](/docs/guides/auth#row-level-security) so data is protected and users can only access their own information.
- [Supabase Auth](/docs/guides/auth) - users log in through magic links sent to their email (without having to set up passwords).
- [Supabase Storage](/docs/guides/storage) - users can upload a profile photo.
@@ -0,0 +1,6 @@
- Go to your [Supabase Project Dashboard](https://app.supabase.com)
- In the left sidebar, click the `Authentication` icon (near the top)
- Click on [`Providers`](https://app.supabase.com/project/_/auth/providers) under the Configuration section
- Click on **{props.provider}** from the accordion list to expand and turn **{props.provider} Enabled** to ON
- Enter your **{props.provider} Client ID** and **{props.provider} Client Secret** saved in the previous step
- Click `Save`
Loaded 100 of 5967 files, more files were not shown because too many files have changed in this diff. Show more