mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
Merge branch 'master' into fix-hard-coded-error
This commit is contained in:
38 files changed
+1525
-609
No files matched your search
@@ -4,6 +4,7 @@
|
||||
* [Installing Dependencies](#Installing-Dependencies)
|
||||
* [Building Supabase](#Building-Supabase)
|
||||
* [Start a Development Server](#Start-a-Development-Server)
|
||||
* [Build in Public](#Build-in-Public)
|
||||
|
||||
## Development Setup
|
||||
|
||||
@@ -148,3 +149,9 @@ To debug code, and to see changes in real time, it is often useful to have a loc
|
||||
```
|
||||
|
||||
For more information on Supabase Studio, see the [Supabase Studio readme](./studio/README.md).
|
||||
|
||||
## Build in Public
|
||||
|
||||
Videos of building supabase made in public.
|
||||
|
||||
- [Contributing to open source as a beginner - Supabase](https://youtu.be/OAqhsylUuWg) - [@imskr](https://github.com/imskr)
|
||||
@@ -0,0 +1,61 @@
|
||||
---
|
||||
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 NodeJS/Javascript.
|
||||
- Have PostgreSQL experience.
|
||||
|
||||
|
||||
## About Supabase
|
||||
|
||||
<About />{' '}
|
||||
|
||||
## About the team
|
||||
|
||||
<Team />{' '}
|
||||
|
||||
## Apply
|
||||
|
||||
<Apply />{' '}
|
||||
|
||||
## Process
|
||||
|
||||
<Process />{' '}
|
||||
|
||||
## All roles
|
||||
|
||||
<Roles />{' '}
|
||||
@@ -0,0 +1,67 @@
|
||||
---
|
||||
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 />{' '}
|
||||
@@ -13,6 +13,13 @@
|
||||
</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>
|
||||
@@ -60,4 +67,18 @@
|
||||
<h3>Full-stack Engineers</h3>
|
||||
<p>Build our Dashboard, tools, and tests.</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>
|
||||
|
||||
<a className="card" href="/careers/developer-success" style={{marginBottom: 10}}>
|
||||
<div className="card__body">
|
||||
<h3>Developer Success Engineer</h3>
|
||||
<p>Build the easiest database platform in the world.</p>
|
||||
</div>
|
||||
</a>
|
||||
@@ -0,0 +1,60 @@
|
||||
---
|
||||
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 />{' '}
|
||||
Generated
+484
-302
File diff suppressed because it is too large.
Load diff
+1
-1
@@ -10,7 +10,7 @@
|
||||
"@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.6.4",
|
||||
"mermaid": "^8.13.8",
|
||||
"react": "^16.8.4",
|
||||
"react-dom": "^16.8.4",
|
||||
"react-inlinesvg": "^2.0.1"
|
||||
|
||||
+2
-2
@@ -3,8 +3,8 @@
|
||||
|
||||
POSTGRES_PASSWORD=your-super-secret-and-long-postgres-password
|
||||
JWT_SECRET=your-super-secret-jwt-token-with-at-least-32-characters-long
|
||||
ANON_KEY=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyb2xlIjoiYW5vbiIsImlhdCI6MTYyNzIwODU0MCwiZXhwIjoxOTc0MzYzNzQwfQ.zcaQfHd3VA7XgJmdGfmV86OLVJT9s2MTmSy-e69BpUY
|
||||
SERVICE_ROLE_KEY=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyb2xlIjoic2VydmljZV9yb2xlIiwiaWF0IjoxNjI3MjA4NTQwLCJleHAiOjE5NzQzNjM3NDB9.pkT3PNpO4DtO45Ac5HK_TKCx8sGLgNtV__pr_ZrRSAU
|
||||
ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE
|
||||
SERVICE_ROLE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q
|
||||
|
||||
# Auth
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ services:
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
PGRST_DB_URI: postgres://postgres:${POSTGRES_PASSWORD}@db:5432/postgres
|
||||
PGRST_DB_SCHEMA: public,storage
|
||||
PGRST_DB_SCHEMAS: public,storage
|
||||
PGRST_DB_ANON_ROLE: anon
|
||||
PGRST_JWT_SECRET: ${JWT_SECRET}
|
||||
PGRST_DB_USE_LEGACY_GUCS: "false"
|
||||
|
||||
@@ -6,10 +6,10 @@ _format_version: "1.1"
|
||||
consumers:
|
||||
- username: anon
|
||||
keyauth_credentials:
|
||||
- key: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyb2xlIjoiYW5vbiIsImlhdCI6MTYyNzIwODU0MCwiZXhwIjoxOTc0MzYzNzQwfQ.zcaQfHd3VA7XgJmdGfmV86OLVJT9s2MTmSy-e69BpUY
|
||||
- key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE
|
||||
- username: service_role
|
||||
keyauth_credentials:
|
||||
- key: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyb2xlIjoic2VydmljZV9yb2xlIiwiaWF0IjoxNjI3MjA4NTQwLCJleHAiOjE5NzQzNjM3NDB9.pkT3PNpO4DtO45Ac5HK_TKCx8sGLgNtV__pr_ZrRSAU
|
||||
- key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q
|
||||
|
||||
###
|
||||
### Access Control List
|
||||
|
||||
+3
-2
@@ -3,5 +3,6 @@ POSTGRES_PASSWORD=your-super-secret-and-long-postgres-password
|
||||
|
||||
SUPABASE_URL=http://localhost:8000
|
||||
SUPABASE_REST_URL=http://localhost:8000/rest/v1/
|
||||
SUPABASE_ANON_KEY=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyb2xlIjoiYW5vbiIsImlhdCI6MTYyNzIwODU0MCwiZXhwIjoxOTc0MzYzNzQwfQ.zcaQfHd3VA7XgJmdGfmV86OLVJT9s2MTmSy-e69BpUY
|
||||
SUPABASE_SERVICE_KEY=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyb2xlIjoic2VydmljZV9yb2xlIiwiaWF0IjoxNjI3MjA4NTQwLCJleHAiOjE5NzQzNjM3NDB9.pkT3PNpO4DtO45Ac5HK_TKCx8sGLgNtV__pr_ZrRSAU
|
||||
SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE
|
||||
SUPABASE_SERVICE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q
|
||||
|
||||
@@ -100,42 +100,44 @@ const LogPanel: FC<Props> = ({
|
||||
</div>
|
||||
<div className="flex items-center gap-x-4">
|
||||
{/* wrap with form so that if user presses enter, the search value will submit automatically */}
|
||||
<form
|
||||
id="log-panel-search"
|
||||
onSubmit={(e) => {
|
||||
// prevent redirection
|
||||
e.preventDefault()
|
||||
onSearch(search)
|
||||
}}
|
||||
>
|
||||
<Input
|
||||
size="tiny"
|
||||
icon={<IconSearch size={16} />}
|
||||
placeholder="Search events"
|
||||
onChange={(e) => setSearch(e.target.value)}
|
||||
value={search}
|
||||
actions={[
|
||||
search && (
|
||||
<IconX
|
||||
key="clear-search"
|
||||
{!isCustomQuery && (
|
||||
<form
|
||||
id="log-panel-search"
|
||||
onSubmit={(e) => {
|
||||
// prevent redirection
|
||||
e.preventDefault()
|
||||
onSearch(search)
|
||||
}}
|
||||
>
|
||||
<Input
|
||||
size="tiny"
|
||||
icon={<IconSearch size={16} />}
|
||||
placeholder="Search events"
|
||||
onChange={(e) => setSearch(e.target.value)}
|
||||
value={search}
|
||||
actions={[
|
||||
search && (
|
||||
<IconX
|
||||
key="clear-search"
|
||||
size="tiny"
|
||||
className="cursor-pointer mx-1"
|
||||
title="Clear search"
|
||||
onClick={() => setSearch('')}
|
||||
/>
|
||||
),
|
||||
<Button
|
||||
key="go"
|
||||
size="tiny"
|
||||
className="cursor-pointer mx-1"
|
||||
title="Clear search"
|
||||
onClick={() => setSearch('')}
|
||||
/>
|
||||
),
|
||||
<Button
|
||||
key="go"
|
||||
size="tiny"
|
||||
title="Go"
|
||||
type="secondary"
|
||||
onClick={() => onSearch(search)}
|
||||
>
|
||||
Go
|
||||
</Button>,
|
||||
]}
|
||||
/>
|
||||
</form>
|
||||
title="Go"
|
||||
type="secondary"
|
||||
onClick={() => onSearch(search)}
|
||||
>
|
||||
Go
|
||||
</Button>,
|
||||
]}
|
||||
/>
|
||||
</form>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
Popover,
|
||||
Typography,
|
||||
} from '@supabase/ui'
|
||||
import { useRouter } from 'next/router'
|
||||
import { FC } from 'react'
|
||||
import Link from 'next/link'
|
||||
import Image from 'next/image'
|
||||
@@ -16,6 +17,10 @@ import SVG from 'react-inlinesvg'
|
||||
interface Props {}
|
||||
|
||||
const HelpPopover: FC<Props> = () => {
|
||||
const router = useRouter()
|
||||
const projectRef = router.query.ref
|
||||
const supportUrl = `/support/new${projectRef ? `?ref=${projectRef}` : ''}`
|
||||
|
||||
return (
|
||||
<Popover
|
||||
className="w-80"
|
||||
@@ -34,7 +39,7 @@ const HelpPopover: FC<Props> = () => {
|
||||
hosted services.
|
||||
</p>
|
||||
</Typography.Text>
|
||||
<Link href="/support/new">
|
||||
<Link href={supportUrl}>
|
||||
<Button className="sbui-default-button--dark-white" icon={<IconMail />}>
|
||||
Contact support team
|
||||
</Button>
|
||||
|
||||
@@ -16,7 +16,7 @@ export async function fetchVercelProjects({
|
||||
url = `${url}?${query}`
|
||||
}
|
||||
const response = await get(url, {
|
||||
headers: { Authorization: `Bearer ${vercelToken}` },
|
||||
headers: { vercel_authorization: `Bearer ${vercelToken}` },
|
||||
})
|
||||
if (response.error != null) {
|
||||
return { error: `Retrieve vercel projects failed. ${response.error?.message}` }
|
||||
@@ -48,7 +48,7 @@ export async function fetchVercelProject({
|
||||
url = `${url}?${query}`
|
||||
}
|
||||
const data = await get(url, {
|
||||
headers: { Authorization: `Bearer ${vercelToken}` },
|
||||
headers: { vercel_authorization: `Bearer ${vercelToken}` },
|
||||
})
|
||||
if (data.error != null) {
|
||||
return { error: `Retrieve vercel project failed. ${data.error.message}` }
|
||||
@@ -74,7 +74,7 @@ export async function fetchVercelProjectEnvs({
|
||||
url = `${url}?${query}`
|
||||
}
|
||||
const response = await get(url, {
|
||||
headers: { Authorization: `Bearer ${vercelToken}` },
|
||||
headers: { vercel_authorization: `Bearer ${vercelToken}` },
|
||||
})
|
||||
if (response.error != null) {
|
||||
return { error: `Retrieve vercel project envs failed. ${response.error?.message}` }
|
||||
@@ -114,7 +114,7 @@ export async function createVercelEnv({
|
||||
url,
|
||||
{ key, value, type, target },
|
||||
{
|
||||
headers: { Authorization: `Bearer ${vercelToken}` },
|
||||
headers: { vercel_authorization: `Bearer ${vercelToken}` },
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ function checkRedirectTo(
|
||||
redirectIfFound?: boolean
|
||||
) {
|
||||
if (loading) return false
|
||||
if (router.asPath == redirectTo) return false
|
||||
if (router.pathname == redirectTo) return false
|
||||
|
||||
// If redirectTo is set, redirect if the user was not found.
|
||||
if (redirectTo && !redirectIfFound && !profile) return true
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { IconMoon, IconSun, Select, Typography } from '@supabase/ui'
|
||||
import { IconMoon, IconSun, Select, Typography, Input } from '@supabase/ui'
|
||||
|
||||
import { useProfile, useStore, withAuth } from 'hooks'
|
||||
import { post } from 'lib/common/fetch'
|
||||
@@ -32,8 +32,10 @@ export default withAuth(User)
|
||||
const ProfileCard = observer(() => {
|
||||
const { ui } = useStore()
|
||||
const { mutateProfile } = useProfile()
|
||||
|
||||
const user = ui.profile
|
||||
|
||||
console.log('User', user?.username, user?.primary_email)
|
||||
|
||||
const updateUser = async (model: any) => {
|
||||
try {
|
||||
const updatedUser = await post(`${API_URL}/profile/update`, model)
|
||||
@@ -51,6 +53,9 @@ const ProfileCard = observer(() => {
|
||||
|
||||
return (
|
||||
<article className="p-4 max-w-4xl">
|
||||
<section>
|
||||
<GithubProfile />
|
||||
</section>
|
||||
<section className="">
|
||||
{/* @ts-ignore */}
|
||||
<SchemaFormPanel
|
||||
@@ -77,6 +82,41 @@ const ProfileCard = observer(() => {
|
||||
)
|
||||
})
|
||||
|
||||
const GithubProfile = observer(() => {
|
||||
const { ui } = useStore()
|
||||
|
||||
return (
|
||||
<Panel
|
||||
title={[
|
||||
<Typography.Title key="panel-title" level={5} className="mb-0">
|
||||
Account Information
|
||||
</Typography.Title>,
|
||||
]}
|
||||
>
|
||||
<Panel.Content>
|
||||
<div className="space-y-2">
|
||||
<Input
|
||||
readOnly
|
||||
disabled
|
||||
label="Username"
|
||||
layout="horizontal"
|
||||
value=""
|
||||
placeholder={ui.profile?.username ?? ''}
|
||||
/>
|
||||
<Input
|
||||
readOnly
|
||||
disabled
|
||||
label="Email"
|
||||
layout="horizontal"
|
||||
value=""
|
||||
placeholder={ui.profile?.primary_email ?? ''}
|
||||
/>
|
||||
</div>
|
||||
</Panel.Content>
|
||||
</Panel>
|
||||
)
|
||||
})
|
||||
|
||||
const ThemeSettings = observer(() => {
|
||||
const { ui } = useStore()
|
||||
|
||||
|
||||
+48
-4
@@ -1,19 +1,21 @@
|
||||
import { NextPage } from 'next'
|
||||
import { useState } from 'react'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { useRouter } from 'next/router'
|
||||
import { NextRouter, useRouter } from 'next/router'
|
||||
import { isUndefined } from 'lodash'
|
||||
import { Typography } from '@supabase/ui'
|
||||
|
||||
import { Project } from 'types'
|
||||
import { useProfile, useStore, withAuth } from 'hooks'
|
||||
import { post, delete_ } from 'lib/common/fetch'
|
||||
import { API_URL, IS_PLATFORM, PROJECT_STATUS, STRIPE_PRODUCT_IDS } from 'lib/constants'
|
||||
import { API_URL, IS_PLATFORM, PROJECT_STATUS } from 'lib/constants'
|
||||
import { AccountLayout } from 'components/layouts'
|
||||
import { auth } from 'lib/gotrue'
|
||||
import Landing from 'components/interfaces/Home/Landing'
|
||||
import ProjectList from 'components/interfaces/Home/ProjectList'
|
||||
import OrganizationDropdown from 'components/to-be-cleaned/Dropdown/OrganizationDropdown'
|
||||
import TextConfirmModal from 'components/to-be-cleaned/ModalsDeprecated/TextConfirmModal'
|
||||
import Connecting from 'components/ui/Loading'
|
||||
|
||||
const Home: NextPage = () => {
|
||||
const { app, ui } = useStore()
|
||||
@@ -26,7 +28,23 @@ const Home: NextPage = () => {
|
||||
const [selectedProjectToDelete, setSelectedProjectToDelete] = useState<Project>()
|
||||
|
||||
if (!profile) {
|
||||
return <Landing />
|
||||
return <UnauthorizedLanding />
|
||||
} else {
|
||||
const isRedirect = isRedirectFromThirdPartyService(router)
|
||||
if (isRedirect) {
|
||||
const queryParams = (router.query as any) || {}
|
||||
const params = new URLSearchParams(queryParams)
|
||||
if (router.query?.next?.includes('https://vercel.com')) {
|
||||
router.push(`/vercel/integrate?${params.toString()}`)
|
||||
}
|
||||
if (router.query?.next?.includes('new-project')) {
|
||||
router.push('/new/project')
|
||||
}
|
||||
if (router.query['x-amzn-marketplace-token'] != undefined) {
|
||||
router.push(`/account/associate?${params.toString()}`)
|
||||
}
|
||||
return <Connecting />
|
||||
}
|
||||
}
|
||||
|
||||
const onSelectDeleteProject = async (project: Project) => {
|
||||
@@ -103,3 +121,29 @@ const Home: NextPage = () => {
|
||||
)
|
||||
}
|
||||
export default withAuth(observer(Home))
|
||||
|
||||
// detect for redirect from 3rd party service like vercel, aws...
|
||||
function isRedirectFromThirdPartyService(router: NextRouter) {
|
||||
return router.query.next !== undefined || router.query['x-amzn-marketplace-token'] !== undefined
|
||||
}
|
||||
|
||||
const UnauthorizedLanding = () => {
|
||||
const router = useRouter()
|
||||
const autoLogin = isRedirectFromThirdPartyService(router)
|
||||
|
||||
useEffect(() => {
|
||||
if (autoLogin) {
|
||||
const queryParams = (router.query as any) || {}
|
||||
const params = new URLSearchParams(queryParams)
|
||||
// trigger github signIn
|
||||
auth.signIn(
|
||||
{ provider: 'github' },
|
||||
{
|
||||
redirectTo: `${process.env.NEXT_PUBLIC_SITE_URL}?${params.toString()}`,
|
||||
}
|
||||
)
|
||||
}
|
||||
}, [])
|
||||
|
||||
return autoLogin ? <Connecting /> : <Landing />
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useState } from 'react'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { Button, Typography } from '@supabase/ui'
|
||||
import Router from 'next/router'
|
||||
import { useRouter } from 'next/router'
|
||||
|
||||
import { API_URL } from 'lib/constants'
|
||||
import { useStore, withAuth } from 'hooks'
|
||||
@@ -15,6 +15,8 @@ import Panel from 'components/to-be-cleaned/Panel'
|
||||
*/
|
||||
const Wizard = () => {
|
||||
const { ui, app } = useStore()
|
||||
const router = useRouter()
|
||||
|
||||
const [orgName, setOrgName] = useState('')
|
||||
const [newOrgLoading, setNewOrgLoading] = useState(false)
|
||||
|
||||
@@ -49,11 +51,7 @@ const Wizard = () => {
|
||||
} else {
|
||||
const org = response
|
||||
app.onOrgAdded(org)
|
||||
|
||||
// Router.push('/new/[slug]', `/new/${org.slug}`)
|
||||
// Using window.location.href for now as organization metadata needs to refresh
|
||||
// We do not get is_owner nor stripe_customer_id from the response here
|
||||
window.location.href = `/new/${org.slug}`
|
||||
router.push(`/new/${org.slug}`)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,7 +68,7 @@ const Wizard = () => {
|
||||
]}
|
||||
footer={[
|
||||
<div key="panel-footer" className="flex items-center w-full justify-between">
|
||||
<Button type="default" onClick={() => Router.push('/')}>
|
||||
<Button type="default" onClick={() => router.push('/')}>
|
||||
Cancel
|
||||
</Button>
|
||||
<div className="space-x-3">
|
||||
|
||||
@@ -198,6 +198,8 @@ const Settings = () => {
|
||||
className="mb-4"
|
||||
label={authConfig.properties.MAILER_AUTOCONFIRM.title}
|
||||
onChange={(value) => {
|
||||
// If MAILER_AUTOCONFIRM is set to true, it means we are disabling email confirmations.
|
||||
// "Enable email confirmations" should be toggled off.
|
||||
handleToggle('MAILER_AUTOCONFIRM', !value)
|
||||
}}
|
||||
checked={!model.MAILER_AUTOCONFIRM}
|
||||
@@ -335,10 +337,13 @@ const Settings = () => {
|
||||
<UIToggle
|
||||
layout="horizontal"
|
||||
label={authConfig.properties.SMS_AUTOCONFIRM.title}
|
||||
onChange={() => {
|
||||
handleToggle('SMS_AUTOCONFIRM')
|
||||
onChange={(value) => {
|
||||
// If SMS_AUTOCONFIRM is set to true, it means we are disabling phone confirmations.
|
||||
// "Enable phone confirmations" should be toggled off.
|
||||
handleToggle('SMS_AUTOCONFIRM', !value)
|
||||
}}
|
||||
checked={model.SMS_AUTOCONFIRM}
|
||||
//
|
||||
checked={!model.SMS_AUTOCONFIRM}
|
||||
descriptionText={authConfig.properties.SMS_AUTOCONFIRM.help}
|
||||
/>
|
||||
</>
|
||||
|
||||
@@ -188,6 +188,7 @@ const ResetDbPassword: FC<any> = () => {
|
||||
} else {
|
||||
ui.setNotification({ category: 'error', message: 'Failed to reset password' })
|
||||
}
|
||||
setIsUpdatingPassword(false)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,9 +280,6 @@ const DownloadCertificate: FC<any> = ({ createdAt }) => {
|
||||
}
|
||||
|
||||
const GeneralSettings: FC<any> = ({ projectRef }) => {
|
||||
const { ui } = useStore()
|
||||
const isOwner = ui.selectedOrganization?.is_owner
|
||||
|
||||
const { data, error }: any = useSWR(`${API_URL}/props/project/${projectRef}/settings`, get)
|
||||
|
||||
if (data?.error || error) {
|
||||
@@ -378,7 +376,7 @@ const GeneralSettings: FC<any> = ({ projectRef }) => {
|
||||
</Panel.Content>
|
||||
</Panel>
|
||||
</section>
|
||||
{isOwner && <ResetDbPassword />}
|
||||
<ResetDbPassword />
|
||||
<DownloadCertificate createdAt={connectionInfo.inserted_at} />
|
||||
</div>
|
||||
<div>
|
||||
|
||||
@@ -3,7 +3,15 @@ import React, { useEffect, useRef, useState } from 'react'
|
||||
import { NextPage } from 'next'
|
||||
import { useRouter } from 'next/router'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { Typography, IconLoader, IconAlertCircle, IconRewind, Button, IconInfo } from '@supabase/ui'
|
||||
import {
|
||||
Typography,
|
||||
IconLoader,
|
||||
IconAlertCircle,
|
||||
IconRewind,
|
||||
Button,
|
||||
IconInfo,
|
||||
Card,
|
||||
} from '@supabase/ui'
|
||||
|
||||
import { withAuth } from 'hooks'
|
||||
import { get } from 'lib/common/fetch'
|
||||
@@ -72,6 +80,9 @@ export const LogPage: NextPage = () => {
|
||||
if (prevPageData === null) {
|
||||
// reduce interval window limit by using the timestamp of the last log
|
||||
queryParams = genQueryParams(params)
|
||||
} else if (prevPageData.data.length === 0) {
|
||||
// no rows returned, indicates that no more data to retrieve and append.
|
||||
return null
|
||||
} else {
|
||||
const len = prevPageData.data.length
|
||||
const { timestamp: tsLimit }: LogData = prevPageData.data[len - 1]
|
||||
@@ -84,18 +95,16 @@ export const LogPage: NextPage = () => {
|
||||
}
|
||||
const {
|
||||
data = [],
|
||||
error: swrError,
|
||||
isValidating,
|
||||
mutate,
|
||||
size,
|
||||
setSize,
|
||||
} = useSWRInfinite<Logs>(getKeyLogs, get, { revalidateOnFocus: false })
|
||||
|
||||
// const { data, isValidating, mutate } = useSWR<Logs>(logUrl, get, { revalidateOnFocus: false })
|
||||
let logData: LogData[] = []
|
||||
let error: null | string = null
|
||||
|
||||
let error: null | string = swrError ? swrError.message : null
|
||||
data.forEach((response: Logs) => {
|
||||
if (response && response.data) {
|
||||
if (!error && response && response.data) {
|
||||
logData = [...logData, ...response.data]
|
||||
}
|
||||
if (!error && response && response.error) {
|
||||
@@ -145,10 +154,12 @@ export const LogPage: NextPage = () => {
|
||||
...prev,
|
||||
where: isSelectQuery ? '' : editorValue,
|
||||
sql: isSelectQuery ? editorValue : '',
|
||||
search_query: ''
|
||||
}))
|
||||
}
|
||||
const handleSearch = (v: string) => {
|
||||
setParams((prev) => ({ ...prev, search_query: v || '' }))
|
||||
setParams((prev) => ({ ...prev, search_query: v || '', where: '', sql: '' }))
|
||||
setEditorValue('')
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -220,9 +231,16 @@ export const LogPage: NextPage = () => {
|
||||
</div>
|
||||
)}
|
||||
{error && (
|
||||
<div className="flex w-full h-full justify-center items-center space-x-2 mx-auto">
|
||||
<IconAlertCircle size={16} />
|
||||
<Typography.Text type="secondary">Sorry! Could not fetch data</Typography.Text>
|
||||
<div className="flex w-full h-full justify-center items-center mx-auto">
|
||||
<Card className="flex flex-col gap-y-2">
|
||||
<div className="flex flex-row gap-x-2 py-2">
|
||||
<IconAlertCircle size={16} />
|
||||
<Typography.Text type="secondary">
|
||||
Sorry! An error occured when fetching data.
|
||||
</Typography.Text>
|
||||
</div>
|
||||
<Typography.Text type="warning">{error}</Typography.Text>
|
||||
</Card>
|
||||
</div>
|
||||
)}
|
||||
<LogTable data={logData} isCustomQuery={mode === 'custom'} />
|
||||
|
||||
@@ -12,11 +12,13 @@ import {
|
||||
} from '@supabase/ui'
|
||||
import SVG from 'react-inlinesvg'
|
||||
import Link from 'next/link'
|
||||
import { useRouter } from 'next/router'
|
||||
|
||||
import { API_URL } from 'lib/constants'
|
||||
import { useStore, withAuth } from 'hooks'
|
||||
import { post } from 'lib/common/fetch'
|
||||
import { Project } from 'types'
|
||||
import { isUndefined } from 'lodash'
|
||||
|
||||
const DEFAULT = {
|
||||
category: {
|
||||
@@ -49,6 +51,9 @@ function formReducer(state: any, action: any) {
|
||||
|
||||
const SupportNew = () => {
|
||||
const { ui, app } = useStore()
|
||||
const router = useRouter()
|
||||
const projectRef = router.query.ref
|
||||
|
||||
const [formState, formDispatch] = useReducer(formReducer, DEFAULT)
|
||||
const [errors, setErrors] = useState<any>([])
|
||||
const [loading, setLoading] = useState<boolean>(false)
|
||||
@@ -72,7 +77,12 @@ const SupportNew = () => {
|
||||
useEffect(() => {
|
||||
// set project default
|
||||
if (sortedProjects.length > 1) {
|
||||
handleOnChange({ name: 'project', value: sortedProjects[0].ref })
|
||||
const selectedProject = sortedProjects.find((project: Project) => project.ref === projectRef)
|
||||
if (!isUndefined(selectedProject)) {
|
||||
handleOnChange({ name: 'project', value: selectedProject.ref })
|
||||
} else {
|
||||
handleOnChange({ name: 'project', value: sortedProjects[0].ref })
|
||||
}
|
||||
} else {
|
||||
// set as 'No specific project'
|
||||
handleOnChange({ name: 'project', value: projectDefaults[0].ref })
|
||||
|
||||
@@ -226,7 +226,7 @@ const Connecting = () => (
|
||||
const ProjectLinksEmptyState = () => (
|
||||
<div className="flex flex-col space-y-4">
|
||||
<Typography.Text>
|
||||
You haven’t created a Supabase project yet. Get started by creating a new Supabase project,
|
||||
You haven't created a Supabase project yet. Get started by creating a new Supabase project,
|
||||
then close this window and retry adding integration.
|
||||
</Typography.Text>
|
||||
<Typography.Link href="https://app.supabase.io">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { cloneDeep } from 'lodash'
|
||||
import { values } from 'mobx'
|
||||
import { Project } from 'types'
|
||||
import { Organization, Project } from 'types'
|
||||
|
||||
import { API_URL, STRIPE_PRODUCT_IDS } from 'lib/constants'
|
||||
import { IRootStore } from '../RootStore'
|
||||
@@ -71,19 +71,23 @@ export default class AppStore implements IAppStore {
|
||||
}
|
||||
}
|
||||
|
||||
onOrgUpdated(org: any) {
|
||||
if (org && org.id) {
|
||||
this.organizations.data[org.id] = { ...org }
|
||||
onOrgUpdated(updatedOrg: Organization) {
|
||||
if (updatedOrg && updatedOrg.id) {
|
||||
const originalOrg = this.organizations.data[updatedOrg.id]
|
||||
this.organizations.data[updatedOrg.id] = {
|
||||
...originalOrg,
|
||||
...updatedOrg,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onOrgAdded(org: any) {
|
||||
onOrgAdded(org: Organization) {
|
||||
if (org && org.id) {
|
||||
this.organizations.data[org.id] = { ...org }
|
||||
this.organizations.data[org.id] = org
|
||||
}
|
||||
}
|
||||
|
||||
onOrgDeleted(org: any) {
|
||||
onOrgDeleted(org: Organization) {
|
||||
if (org && org.id) {
|
||||
const projects = values(this.projects.data)
|
||||
// cleanup projects saved queries
|
||||
|
||||
@@ -17,7 +17,12 @@ test('templates', async () => {
|
||||
// userEvent.click(screen.getByText("Some option"))
|
||||
// expect(mockFn).toBeCalled()
|
||||
})
|
||||
|
||||
test('custom mode', async () => {
|
||||
render(<LogPanel isCustomQuery />)
|
||||
await waitFor(() => {
|
||||
expect(() => screen.getByPlaceholderText(/Search/)).toThrow()
|
||||
})
|
||||
})
|
||||
test('filter input change and submit', async () => {
|
||||
const mockFn = jest.fn()
|
||||
render(<LogPanel onSearch={mockFn} />)
|
||||
|
||||
@@ -42,15 +42,21 @@ LogPage.mockImplementation((props) => {
|
||||
const Page = jest.requireActual('pages/project/[ref]/settings/logs/[type]').LogPage
|
||||
// wrap with SWR to reset the cache each time
|
||||
return (
|
||||
<SWRConfig value={{ provider: () => new Map() }}>
|
||||
<SWRConfig
|
||||
value={{
|
||||
provider: () => new Map(),
|
||||
shouldRetryOnError: false,
|
||||
}}
|
||||
>
|
||||
<Page {...props} />
|
||||
</SWRConfig>
|
||||
)
|
||||
})
|
||||
|
||||
import { render, fireEvent, waitFor, screen } from '@testing-library/react'
|
||||
import { render, fireEvent, waitFor, screen, act } from '@testing-library/react'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
import { getToggleByText } from '../../helpers'
|
||||
import { wait } from '@testing-library/user-event/dist/utils'
|
||||
|
||||
beforeEach(() => {
|
||||
// reset mocks between tests
|
||||
@@ -181,6 +187,12 @@ test('where clause will trigger a log refresh', async () => {
|
||||
return { data: [] }
|
||||
})
|
||||
const { container } = render(<LogPage />)
|
||||
// fill search bar with some value, should be ignored when in custom mode
|
||||
userEvent.type(screen.getByPlaceholderText(/Search/), 'search_value')
|
||||
userEvent.click(screen.getByText('Go'))
|
||||
// clear mock calls, for clean assertions
|
||||
get.mockClear()
|
||||
|
||||
let editor = container.querySelector('.monaco-editor')
|
||||
expect(editor).toBeFalsy()
|
||||
// TODO: abstract this out into a toggle selection helper
|
||||
@@ -198,6 +210,8 @@ test('where clause will trigger a log refresh', async () => {
|
||||
() => {
|
||||
expect(get).toHaveBeenCalledWith(expect.stringContaining('where'))
|
||||
expect(get).toHaveBeenCalledWith(expect.stringContaining('metadata.field'))
|
||||
// should ignore search bar value
|
||||
expect(get).not.toHaveBeenCalledWith(expect.stringContaining('search_value'))
|
||||
},
|
||||
{ timeout: 1000 }
|
||||
)
|
||||
@@ -298,3 +312,27 @@ test('load older btn will fetch older logs', async () => {
|
||||
})
|
||||
await waitFor(() => screen.getByText('second event'))
|
||||
})
|
||||
|
||||
test('bug: load older btn does not error out when previous page is empty', async () => {
|
||||
// bugfix for https://sentry.io/organizations/supabase/issues/2903331460/?project=5459134&referrer=slack
|
||||
get.mockImplementation((url) => {
|
||||
if (url.includes('count')) {
|
||||
return {}
|
||||
}
|
||||
return { data: [] }
|
||||
})
|
||||
render(<LogPage />)
|
||||
|
||||
userEvent.click(screen.getByText('Load older'))
|
||||
// NOTE: potential race condition, since we are asserting that something DOES NOT EXIST
|
||||
// wait for 500s to make sure all ui logic is complete
|
||||
// need to wrap in act because internal react state is changing during this time.
|
||||
await act(async () => await wait(100))
|
||||
|
||||
// clicking load older multiple times should not give error
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByText(/Sorry/)).toBeNull()
|
||||
expect(screen.queryByText(/An error occured/)).toBeNull()
|
||||
expect(screen.queryByText(/undefined/)).toBeNull()
|
||||
})
|
||||
})
|
||||
@@ -4,9 +4,13 @@ export interface Organization {
|
||||
name: string
|
||||
billing_email: string
|
||||
project_limit: number
|
||||
stripe_customer_id?: string
|
||||
total_free_projects?: number
|
||||
members: any[]
|
||||
projects: any[]
|
||||
is_owner?: boolean
|
||||
stripe_customer_id?: string
|
||||
stripe_customer_object?: any
|
||||
total_free_projects?: number
|
||||
total_paid_projects?: number
|
||||
}
|
||||
|
||||
export interface Project {
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
process.env.SUPABASE_URL = 'http://localhost:8000'
|
||||
process.env.SUPABASE_KEY_ANON =
|
||||
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyb2xlIjoiYW5vbiIsImlhdCI6MTYyNzIwODU0MCwiZXhwIjoxOTc0MzYzNzQwfQ.zcaQfHd3VA7XgJmdGfmV86OLVJT9s2MTmSy-e69BpUY'
|
||||
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE'
|
||||
process.env.SUPABASE_KEY_ADMIN =
|
||||
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyb2xlIjoic2VydmljZV9yb2xlIiwiaWF0IjoxNjI3MjA4NTQwLCJleHAiOjE5NzQzNjM3NDB9.pkT3PNpO4DtO45Ac5HK_TKCx8sGLgNtV__pr_ZrRSAU'
|
||||
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q'
|
||||
@@ -133,9 +133,7 @@ Migrating projects can be achieved using standard PostgreSQL tooling. This is pa
|
||||
|
||||
When you create a new project in Supabase we ask for a password. You can use this password to connect directly to your Postgres database.
|
||||
|
||||
If you forget your password, you can reset it from the Dashboard SQL editor:
|
||||
|
||||
For example:
|
||||
If you forget your password, you can reset it from the Dashboard under the database settings page, or through the SQL editor as such:
|
||||
|
||||
```sql
|
||||
alter user postgres
|
||||
|
||||
@@ -133,7 +133,7 @@ Restart your Next.js development server to read in the new values from `.env.loc
|
||||
npm run dev
|
||||
```
|
||||
|
||||
## Step 5: Install Auth0 Next.js library
|
||||
## Step 6: Install Auth0 Next.js library
|
||||
|
||||
Install the `@auth0/nextjs-auth0` library.
|
||||
|
||||
@@ -211,7 +211,7 @@ You should now be able to view the landing page.
|
||||
|
||||

|
||||
|
||||
## Step 6: Sign Auth0 token for Supabase
|
||||
## Step 7: Sign Auth0 token for Supabase
|
||||
|
||||
Currently, neither Supabase or Auth0 allow for a custom signing secret to be set for their JWT. They also use different [signing algorithms](https://auth0.com/docs/configure/applications/signing-algorithms).
|
||||
|
||||
@@ -263,7 +263,7 @@ We are signing this JWT using Supabase's signing secret, so Supabase will be abl
|
||||
|
||||
Now we just need to send the token along with the request to Supabase.
|
||||
|
||||
## Step 7: Requesting data from Supabase
|
||||
## Step 8: Requesting data from Supabase
|
||||
|
||||
Create a new file called `utils/supabase.js` and add the following:
|
||||
|
||||
@@ -391,7 +391,7 @@ Either way, when we reload our application, we are still getting the empty state
|
||||
|
||||
This is because we enabled Row Level Security, which blocks all requests by default. To enable our user to select their `todos` we need to write a policy.
|
||||
|
||||
## Step 8: Write a policy to allow select
|
||||
## Step 9: Write a policy to allow select
|
||||
|
||||
Our policy will need to know who our currently logged in user is to determine whether or not they should have access. Let's create a PostgreSQL function to extract the current user from our new JWT.
|
||||
|
||||
|
||||
Generated
+471
-175
@@ -3929,72 +3929,73 @@
|
||||
}
|
||||
},
|
||||
"d3": {
|
||||
"version": "5.16.0",
|
||||
"resolved": "https://registry.npmjs.org/d3/-/d3-5.16.0.tgz",
|
||||
"integrity": "sha512-4PL5hHaHwX4m7Zr1UapXW23apo6pexCgdetdJ5kTmADpG/7T9Gkxw0M0tf/pjoB63ezCCm0u5UaFYy2aMt0Mcw==",
|
||||
"version": "7.2.1",
|
||||
"resolved": "https://registry.npmjs.org/d3/-/d3-7.2.1.tgz",
|
||||
"integrity": "sha512-E/5sP0aeK6YPXI/+4QlefvBFgmcyR2jYftId0PrYWv4Y/gW3c3thp1XG4rQzF0eUwV9tR1x05X5eWuJ6rQXvew==",
|
||||
"requires": {
|
||||
"d3-array": "1",
|
||||
"d3-axis": "1",
|
||||
"d3-brush": "1",
|
||||
"d3-chord": "1",
|
||||
"d3-collection": "1",
|
||||
"d3-color": "1",
|
||||
"d3-contour": "1",
|
||||
"d3-dispatch": "1",
|
||||
"d3-drag": "1",
|
||||
"d3-dsv": "1",
|
||||
"d3-ease": "1",
|
||||
"d3-fetch": "1",
|
||||
"d3-force": "1",
|
||||
"d3-format": "1",
|
||||
"d3-geo": "1",
|
||||
"d3-hierarchy": "1",
|
||||
"d3-interpolate": "1",
|
||||
"d3-path": "1",
|
||||
"d3-polygon": "1",
|
||||
"d3-quadtree": "1",
|
||||
"d3-random": "1",
|
||||
"d3-scale": "2",
|
||||
"d3-scale-chromatic": "1",
|
||||
"d3-selection": "1",
|
||||
"d3-shape": "1",
|
||||
"d3-time": "1",
|
||||
"d3-time-format": "2",
|
||||
"d3-timer": "1",
|
||||
"d3-transition": "1",
|
||||
"d3-voronoi": "1",
|
||||
"d3-zoom": "1"
|
||||
"d3-array": "3",
|
||||
"d3-axis": "3",
|
||||
"d3-brush": "3",
|
||||
"d3-chord": "3",
|
||||
"d3-color": "3",
|
||||
"d3-contour": "3",
|
||||
"d3-delaunay": "6",
|
||||
"d3-dispatch": "3",
|
||||
"d3-drag": "3",
|
||||
"d3-dsv": "3",
|
||||
"d3-ease": "3",
|
||||
"d3-fetch": "3",
|
||||
"d3-force": "3",
|
||||
"d3-format": "3",
|
||||
"d3-geo": "3",
|
||||
"d3-hierarchy": "3",
|
||||
"d3-interpolate": "3",
|
||||
"d3-path": "3",
|
||||
"d3-polygon": "3",
|
||||
"d3-quadtree": "3",
|
||||
"d3-random": "3",
|
||||
"d3-scale": "4",
|
||||
"d3-scale-chromatic": "3",
|
||||
"d3-selection": "3",
|
||||
"d3-shape": "3",
|
||||
"d3-time": "3",
|
||||
"d3-time-format": "4",
|
||||
"d3-timer": "3",
|
||||
"d3-transition": "3",
|
||||
"d3-zoom": "3"
|
||||
}
|
||||
},
|
||||
"d3-array": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/d3-array/-/d3-array-1.2.4.tgz",
|
||||
"integrity": "sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw=="
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.1.1.tgz",
|
||||
"integrity": "sha512-33qQ+ZoZlli19IFiQx4QEpf2CBEayMRzhlisJHSCsSUbDXv6ZishqS1x7uFVClKG4Wr7rZVHvaAttoLow6GqdQ==",
|
||||
"requires": {
|
||||
"internmap": "1 - 2"
|
||||
}
|
||||
},
|
||||
"d3-axis": {
|
||||
"version": "1.0.12",
|
||||
"resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-1.0.12.tgz",
|
||||
"integrity": "sha512-ejINPfPSNdGFKEOAtnBtdkpr24c4d4jsei6Lg98mxf424ivoDP2956/5HDpIAtmHo85lqT4pruy+zEgvRUBqaQ=="
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz",
|
||||
"integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw=="
|
||||
},
|
||||
"d3-brush": {
|
||||
"version": "1.1.6",
|
||||
"resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-1.1.6.tgz",
|
||||
"integrity": "sha512-7RW+w7HfMCPyZLifTz/UnJmI5kdkXtpCbombUSs8xniAyo0vIbrDzDwUJB6eJOgl9u5DQOt2TQlYumxzD1SvYA==",
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz",
|
||||
"integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==",
|
||||
"requires": {
|
||||
"d3-dispatch": "1",
|
||||
"d3-drag": "1",
|
||||
"d3-interpolate": "1",
|
||||
"d3-selection": "1",
|
||||
"d3-transition": "1"
|
||||
"d3-dispatch": "1 - 3",
|
||||
"d3-drag": "2 - 3",
|
||||
"d3-interpolate": "1 - 3",
|
||||
"d3-selection": "3",
|
||||
"d3-transition": "3"
|
||||
}
|
||||
},
|
||||
"d3-chord": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-1.0.6.tgz",
|
||||
"integrity": "sha512-JXA2Dro1Fxw9rJe33Uv+Ckr5IrAa74TlfDEhE/jfLOaXegMQFQTAgAw9WnZL8+HxVBRXaRGCkrNU7pJeylRIuA==",
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz",
|
||||
"integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==",
|
||||
"requires": {
|
||||
"d3-array": "1",
|
||||
"d3-path": "1"
|
||||
"d3-path": "1 - 3"
|
||||
}
|
||||
},
|
||||
"d3-collection": {
|
||||
@@ -4003,183 +4004,199 @@
|
||||
"integrity": "sha512-ii0/r5f4sjKNTfh84Di+DpztYwqKhEyUlKoPrzUFfeSkWxjW49xU2QzO9qrPrNkpdI0XJkfzvmTu8V2Zylln6A=="
|
||||
},
|
||||
"d3-color": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.4.1.tgz",
|
||||
"integrity": "sha512-p2sTHSLCJI2QKunbGb7ocOh7DgTAn8IrLx21QRc/BSnodXM4sv6aLQlnfpvehFMLZEfBc6g9pH9SWQccFYfJ9Q=="
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.0.1.tgz",
|
||||
"integrity": "sha512-6/SlHkDOBLyQSJ1j1Ghs82OIUXpKWlR0hCsw0XrLSQhuUPuCSmLQ1QPH98vpnQxMUQM2/gfAkUEWsupVpd9JGw=="
|
||||
},
|
||||
"d3-contour": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-1.3.2.tgz",
|
||||
"integrity": "sha512-hoPp4K/rJCu0ladiH6zmJUEz6+u3lgR+GSm/QdM2BBvDraU39Vr7YdDCicJcxP1z8i9B/2dJLgDC1NcvlF8WCg==",
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-3.0.1.tgz",
|
||||
"integrity": "sha512-0Oc4D0KyhwhM7ZL0RMnfGycLN7hxHB8CMmwZ3+H26PWAG0ozNuYG5hXSDNgmP1SgJkQMrlG6cP20HoaSbvcJTQ==",
|
||||
"requires": {
|
||||
"d3-array": "^1.1.1"
|
||||
"d3-array": "2 - 3"
|
||||
}
|
||||
},
|
||||
"d3-delaunay": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.2.tgz",
|
||||
"integrity": "sha512-IMLNldruDQScrcfT+MWnazhHbDJhcRJyOEBAJfwQnHle1RPh6WDuLvxNArUju2VSMSUuKlY5BGHRJ2cYyoFLQQ==",
|
||||
"requires": {
|
||||
"delaunator": "5"
|
||||
}
|
||||
},
|
||||
"d3-dispatch": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-1.0.6.tgz",
|
||||
"integrity": "sha512-fVjoElzjhCEy+Hbn8KygnmMS7Or0a9sI2UzGwoB7cCtvI1XpVN9GpoYlnb3xt2YV66oXYb1fLJ8GMvP4hdU1RA=="
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz",
|
||||
"integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg=="
|
||||
},
|
||||
"d3-drag": {
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-1.2.5.tgz",
|
||||
"integrity": "sha512-rD1ohlkKQwMZYkQlYVCrSFxsWPzI97+W+PaEIBNTMxRuxz9RF0Hi5nJWHGVJ3Om9d2fRTe1yOBINJyy/ahV95w==",
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz",
|
||||
"integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==",
|
||||
"requires": {
|
||||
"d3-dispatch": "1",
|
||||
"d3-selection": "1"
|
||||
"d3-dispatch": "1 - 3",
|
||||
"d3-selection": "3"
|
||||
}
|
||||
},
|
||||
"d3-dsv": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-1.2.0.tgz",
|
||||
"integrity": "sha512-9yVlqvZcSOMhCYzniHE7EVUws7Fa1zgw+/EAV2BxJoG3ME19V6BQFBwI855XQDsxyOuG7NibqRMTtiF/Qup46g==",
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz",
|
||||
"integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==",
|
||||
"requires": {
|
||||
"commander": "2",
|
||||
"iconv-lite": "0.4",
|
||||
"commander": "7",
|
||||
"iconv-lite": "0.6",
|
||||
"rw": "1"
|
||||
},
|
||||
"dependencies": {
|
||||
"commander": {
|
||||
"version": "2.20.3",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
||||
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
|
||||
"integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="
|
||||
},
|
||||
"iconv-lite": {
|
||||
"version": "0.6.3",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
|
||||
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
|
||||
"requires": {
|
||||
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"d3-ease": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-1.0.7.tgz",
|
||||
"integrity": "sha512-lx14ZPYkhNx0s/2HX5sLFUI3mbasHjSSpwO/KaaNACweVwxUruKyWVcb293wMv1RqTPZyZ8kSZ2NogUZNcLOFQ=="
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz",
|
||||
"integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w=="
|
||||
},
|
||||
"d3-fetch": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-1.2.0.tgz",
|
||||
"integrity": "sha512-yC78NBVcd2zFAyR/HnUiBS7Lf6inSCoWcSxFfw8FYL7ydiqe80SazNwoffcqOfs95XaLo7yebsmQqDKSsXUtvA==",
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz",
|
||||
"integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==",
|
||||
"requires": {
|
||||
"d3-dsv": "1"
|
||||
"d3-dsv": "1 - 3"
|
||||
}
|
||||
},
|
||||
"d3-force": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-force/-/d3-force-1.2.1.tgz",
|
||||
"integrity": "sha512-HHvehyaiUlVo5CxBJ0yF/xny4xoaxFxDnBXNvNcfW9adORGZfyNF1dj6DGLKyk4Yh3brP/1h3rnDzdIAwL08zg==",
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz",
|
||||
"integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==",
|
||||
"requires": {
|
||||
"d3-collection": "1",
|
||||
"d3-dispatch": "1",
|
||||
"d3-quadtree": "1",
|
||||
"d3-timer": "1"
|
||||
"d3-dispatch": "1 - 3",
|
||||
"d3-quadtree": "1 - 3",
|
||||
"d3-timer": "1 - 3"
|
||||
}
|
||||
},
|
||||
"d3-format": {
|
||||
"version": "1.4.5",
|
||||
"resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.4.5.tgz",
|
||||
"integrity": "sha512-J0piedu6Z8iB6TbIGfZgDzfXxUFN3qQRMofy2oPdXzQibYGqPB/9iMcxr/TGalU+2RsyDO+U4f33id8tbnSRMQ=="
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz",
|
||||
"integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA=="
|
||||
},
|
||||
"d3-geo": {
|
||||
"version": "1.12.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-1.12.1.tgz",
|
||||
"integrity": "sha512-XG4d1c/UJSEX9NfU02KwBL6BYPj8YKHxgBEw5om2ZnTRSbIcego6dhHwcxuSR3clxh0EpE38os1DVPOmnYtTPg==",
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.0.1.tgz",
|
||||
"integrity": "sha512-Wt23xBych5tSy9IYAM1FR2rWIBFWa52B/oF/GYe5zbdHrg08FU8+BuI6X4PvTwPDdqdAdq04fuWJpELtsaEjeA==",
|
||||
"requires": {
|
||||
"d3-array": "1"
|
||||
"d3-array": "2.5.0 - 3"
|
||||
}
|
||||
},
|
||||
"d3-hierarchy": {
|
||||
"version": "1.1.9",
|
||||
"resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-1.1.9.tgz",
|
||||
"integrity": "sha512-j8tPxlqh1srJHAtxfvOUwKNYJkQuBFdM1+JAUfq6xqH5eAqf93L7oG1NVqDa4CpFZNvnNKtCYEUC8KY9yEn9lQ=="
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.1.tgz",
|
||||
"integrity": "sha512-LtAIu54UctRmhGKllleflmHalttH3zkfSi4NlKrTAoFKjC+AFBJohsCAdgCBYQwH0F8hIOGY89X1pPqAchlMkA=="
|
||||
},
|
||||
"d3-interpolate": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-1.4.0.tgz",
|
||||
"integrity": "sha512-V9znK0zc3jOPV4VD2zZn0sDhZU3WAE2bmlxdIwwQPPzPjvyLkd8B3JUVdS1IDUFDkWZ72c9qnv1GK2ZagTZ8EA==",
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz",
|
||||
"integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==",
|
||||
"requires": {
|
||||
"d3-color": "1"
|
||||
"d3-color": "1 - 3"
|
||||
}
|
||||
},
|
||||
"d3-path": {
|
||||
"version": "1.0.9",
|
||||
"resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz",
|
||||
"integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg=="
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.0.1.tgz",
|
||||
"integrity": "sha512-gq6gZom9AFZby0YLduxT1qmrp4xpBA1YZr19OI717WIdKE2OM5ETq5qrHLb301IgxhLwcuxvGZVLeeWc/k1I6w=="
|
||||
},
|
||||
"d3-polygon": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-1.0.6.tgz",
|
||||
"integrity": "sha512-k+RF7WvI08PC8reEoXa/w2nSg5AUMTi+peBD9cmFc+0ixHfbs4QmxxkarVal1IkVkgxVuk9JSHhJURHiyHKAuQ=="
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz",
|
||||
"integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg=="
|
||||
},
|
||||
"d3-quadtree": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-1.0.7.tgz",
|
||||
"integrity": "sha512-RKPAeXnkC59IDGD0Wu5mANy0Q2V28L+fNe65pOCXVdVuTJS3WPKaJlFHer32Rbh9gIo9qMuJXio8ra4+YmIymA=="
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz",
|
||||
"integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw=="
|
||||
},
|
||||
"d3-random": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/d3-random/-/d3-random-1.1.2.tgz",
|
||||
"integrity": "sha512-6AK5BNpIFqP+cx/sreKzNjWbwZQCSUatxq+pPRmFIQaWuoD+NrbVWw7YWpHiXpCQ/NanKdtGDuB+VQcZDaEmYQ=="
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz",
|
||||
"integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ=="
|
||||
},
|
||||
"d3-scale": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-2.2.2.tgz",
|
||||
"integrity": "sha512-LbeEvGgIb8UMcAa0EATLNX0lelKWGYDQiPdHj+gLblGVhGLyNbaCn3EvrJf0A3Y/uOOU5aD6MTh5ZFCdEwGiCw==",
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz",
|
||||
"integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==",
|
||||
"requires": {
|
||||
"d3-array": "^1.2.0",
|
||||
"d3-collection": "1",
|
||||
"d3-format": "1",
|
||||
"d3-interpolate": "1",
|
||||
"d3-time": "1",
|
||||
"d3-time-format": "2"
|
||||
"d3-array": "2.10.0 - 3",
|
||||
"d3-format": "1 - 3",
|
||||
"d3-interpolate": "1.2.0 - 3",
|
||||
"d3-time": "2.1.1 - 3",
|
||||
"d3-time-format": "2 - 4"
|
||||
}
|
||||
},
|
||||
"d3-scale-chromatic": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-1.5.0.tgz",
|
||||
"integrity": "sha512-ACcL46DYImpRFMBcpk9HhtIyC7bTBR4fNOPxwVSl0LfulDAwyiHyPOTqcDG1+t5d4P9W7t/2NAuWu59aKko/cg==",
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz",
|
||||
"integrity": "sha512-Lx9thtxAKrO2Pq6OO2Ua474opeziKr279P/TKZsMAhYyNDD3EnCffdbgeSYN5O7m2ByQsxtuP2CSDczNUIZ22g==",
|
||||
"requires": {
|
||||
"d3-color": "1",
|
||||
"d3-interpolate": "1"
|
||||
"d3-color": "1 - 3",
|
||||
"d3-interpolate": "1 - 3"
|
||||
}
|
||||
},
|
||||
"d3-selection": {
|
||||
"version": "1.4.2",
|
||||
"resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-1.4.2.tgz",
|
||||
"integrity": "sha512-SJ0BqYihzOjDnnlfyeHT0e30k0K1+5sR3d5fNueCNeuhZTnGw4M4o8mqJchSwgKMXCNFo+e2VTChiSJ0vYtXkg=="
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz",
|
||||
"integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ=="
|
||||
},
|
||||
"d3-shape": {
|
||||
"version": "1.3.7",
|
||||
"resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz",
|
||||
"integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==",
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.0.1.tgz",
|
||||
"integrity": "sha512-HNZNEQoDhuCrDWEc/BMbF/hKtzMZVoe64TvisFLDp2Iyj0UShB/E6/lBsLlJTfBMbYgftHj90cXJ0SEitlE6Xw==",
|
||||
"requires": {
|
||||
"d3-path": "1"
|
||||
"d3-path": "1 - 3"
|
||||
}
|
||||
},
|
||||
"d3-time": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-time/-/d3-time-1.1.0.tgz",
|
||||
"integrity": "sha512-Xh0isrZ5rPYYdqhAVk8VLnMEidhz5aP7htAADH6MfzgmmicPkTo8LhkLxci61/lCB7n7UmE3bN0leRt+qvkLxA=="
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.0.0.tgz",
|
||||
"integrity": "sha512-zmV3lRnlaLI08y9IMRXSDshQb5Nj77smnfpnd2LrBa/2K281Jijactokeak14QacHs/kKq0AQ121nidNYlarbQ==",
|
||||
"requires": {
|
||||
"d3-array": "2 - 3"
|
||||
}
|
||||
},
|
||||
"d3-time-format": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-2.3.0.tgz",
|
||||
"integrity": "sha512-guv6b2H37s2Uq/GefleCDtbe0XZAuy7Wa49VGkPVPMfLL9qObgBST3lEHJBMUp8S7NdLQAGIvr2KXk8Hc98iKQ==",
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz",
|
||||
"integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==",
|
||||
"requires": {
|
||||
"d3-time": "1"
|
||||
"d3-time": "1 - 3"
|
||||
}
|
||||
},
|
||||
"d3-timer": {
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-1.0.10.tgz",
|
||||
"integrity": "sha512-B1JDm0XDaQC+uvo4DT79H0XmBskgS3l6Ve+1SBCfxgmtIb1AVrPIoqd+nPSv+loMX8szQ0sVUhGngL7D5QPiXw=="
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz",
|
||||
"integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA=="
|
||||
},
|
||||
"d3-transition": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-1.3.2.tgz",
|
||||
"integrity": "sha512-sc0gRU4PFqZ47lPVHloMn9tlPcv8jxgOQg+0zjhfZXMQuvppjG6YuwdMBE0TuqCZjeJkLecku/l9R0JPcRhaDA==",
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz",
|
||||
"integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==",
|
||||
"requires": {
|
||||
"d3-color": "1",
|
||||
"d3-dispatch": "1",
|
||||
"d3-ease": "1",
|
||||
"d3-interpolate": "1",
|
||||
"d3-selection": "^1.1.0",
|
||||
"d3-timer": "1"
|
||||
"d3-color": "1 - 3",
|
||||
"d3-dispatch": "1 - 3",
|
||||
"d3-ease": "1 - 3",
|
||||
"d3-interpolate": "1 - 3",
|
||||
"d3-timer": "1 - 3"
|
||||
}
|
||||
},
|
||||
"d3-voronoi": {
|
||||
@@ -4188,15 +4205,15 @@
|
||||
"integrity": "sha512-dArJ32hchFsrQ8uMiTBLq256MpnZjeuBtdHpaDlYuQyjU0CVzCJl/BVW+SkszaAeH95D/8gxqAhgx0ouAWAfRg=="
|
||||
},
|
||||
"d3-zoom": {
|
||||
"version": "1.8.3",
|
||||
"resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-1.8.3.tgz",
|
||||
"integrity": "sha512-VoLXTK4wvy1a0JpH2Il+F2CiOhVu7VRXWF5M/LroMIh3/zBAC3WAt7QoIvPibOavVo20hN6/37vwAsdBejLyKQ==",
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz",
|
||||
"integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==",
|
||||
"requires": {
|
||||
"d3-dispatch": "1",
|
||||
"d3-drag": "1",
|
||||
"d3-interpolate": "1",
|
||||
"d3-selection": "1",
|
||||
"d3-transition": "1"
|
||||
"d3-dispatch": "1 - 3",
|
||||
"d3-drag": "2 - 3",
|
||||
"d3-interpolate": "1 - 3",
|
||||
"d3-selection": "2 - 3",
|
||||
"d3-transition": "2 - 3"
|
||||
}
|
||||
},
|
||||
"dagre": {
|
||||
@@ -4217,6 +4234,267 @@
|
||||
"dagre": "^0.8.5",
|
||||
"graphlib": "^2.1.8",
|
||||
"lodash": "^4.17.15"
|
||||
},
|
||||
"dependencies": {
|
||||
"commander": {
|
||||
"version": "2.20.3",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
||||
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
|
||||
},
|
||||
"d3": {
|
||||
"version": "5.16.0",
|
||||
"resolved": "https://registry.npmjs.org/d3/-/d3-5.16.0.tgz",
|
||||
"integrity": "sha512-4PL5hHaHwX4m7Zr1UapXW23apo6pexCgdetdJ5kTmADpG/7T9Gkxw0M0tf/pjoB63ezCCm0u5UaFYy2aMt0Mcw==",
|
||||
"requires": {
|
||||
"d3-array": "1",
|
||||
"d3-axis": "1",
|
||||
"d3-brush": "1",
|
||||
"d3-chord": "1",
|
||||
"d3-collection": "1",
|
||||
"d3-color": "1",
|
||||
"d3-contour": "1",
|
||||
"d3-dispatch": "1",
|
||||
"d3-drag": "1",
|
||||
"d3-dsv": "1",
|
||||
"d3-ease": "1",
|
||||
"d3-fetch": "1",
|
||||
"d3-force": "1",
|
||||
"d3-format": "1",
|
||||
"d3-geo": "1",
|
||||
"d3-hierarchy": "1",
|
||||
"d3-interpolate": "1",
|
||||
"d3-path": "1",
|
||||
"d3-polygon": "1",
|
||||
"d3-quadtree": "1",
|
||||
"d3-random": "1",
|
||||
"d3-scale": "2",
|
||||
"d3-scale-chromatic": "1",
|
||||
"d3-selection": "1",
|
||||
"d3-shape": "1",
|
||||
"d3-time": "1",
|
||||
"d3-time-format": "2",
|
||||
"d3-timer": "1",
|
||||
"d3-transition": "1",
|
||||
"d3-voronoi": "1",
|
||||
"d3-zoom": "1"
|
||||
}
|
||||
},
|
||||
"d3-array": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/d3-array/-/d3-array-1.2.4.tgz",
|
||||
"integrity": "sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw=="
|
||||
},
|
||||
"d3-axis": {
|
||||
"version": "1.0.12",
|
||||
"resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-1.0.12.tgz",
|
||||
"integrity": "sha512-ejINPfPSNdGFKEOAtnBtdkpr24c4d4jsei6Lg98mxf424ivoDP2956/5HDpIAtmHo85lqT4pruy+zEgvRUBqaQ=="
|
||||
},
|
||||
"d3-brush": {
|
||||
"version": "1.1.6",
|
||||
"resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-1.1.6.tgz",
|
||||
"integrity": "sha512-7RW+w7HfMCPyZLifTz/UnJmI5kdkXtpCbombUSs8xniAyo0vIbrDzDwUJB6eJOgl9u5DQOt2TQlYumxzD1SvYA==",
|
||||
"requires": {
|
||||
"d3-dispatch": "1",
|
||||
"d3-drag": "1",
|
||||
"d3-interpolate": "1",
|
||||
"d3-selection": "1",
|
||||
"d3-transition": "1"
|
||||
}
|
||||
},
|
||||
"d3-chord": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-1.0.6.tgz",
|
||||
"integrity": "sha512-JXA2Dro1Fxw9rJe33Uv+Ckr5IrAa74TlfDEhE/jfLOaXegMQFQTAgAw9WnZL8+HxVBRXaRGCkrNU7pJeylRIuA==",
|
||||
"requires": {
|
||||
"d3-array": "1",
|
||||
"d3-path": "1"
|
||||
}
|
||||
},
|
||||
"d3-color": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.4.1.tgz",
|
||||
"integrity": "sha512-p2sTHSLCJI2QKunbGb7ocOh7DgTAn8IrLx21QRc/BSnodXM4sv6aLQlnfpvehFMLZEfBc6g9pH9SWQccFYfJ9Q=="
|
||||
},
|
||||
"d3-contour": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-1.3.2.tgz",
|
||||
"integrity": "sha512-hoPp4K/rJCu0ladiH6zmJUEz6+u3lgR+GSm/QdM2BBvDraU39Vr7YdDCicJcxP1z8i9B/2dJLgDC1NcvlF8WCg==",
|
||||
"requires": {
|
||||
"d3-array": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"d3-dispatch": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-1.0.6.tgz",
|
||||
"integrity": "sha512-fVjoElzjhCEy+Hbn8KygnmMS7Or0a9sI2UzGwoB7cCtvI1XpVN9GpoYlnb3xt2YV66oXYb1fLJ8GMvP4hdU1RA=="
|
||||
},
|
||||
"d3-drag": {
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-1.2.5.tgz",
|
||||
"integrity": "sha512-rD1ohlkKQwMZYkQlYVCrSFxsWPzI97+W+PaEIBNTMxRuxz9RF0Hi5nJWHGVJ3Om9d2fRTe1yOBINJyy/ahV95w==",
|
||||
"requires": {
|
||||
"d3-dispatch": "1",
|
||||
"d3-selection": "1"
|
||||
}
|
||||
},
|
||||
"d3-dsv": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-1.2.0.tgz",
|
||||
"integrity": "sha512-9yVlqvZcSOMhCYzniHE7EVUws7Fa1zgw+/EAV2BxJoG3ME19V6BQFBwI855XQDsxyOuG7NibqRMTtiF/Qup46g==",
|
||||
"requires": {
|
||||
"commander": "2",
|
||||
"iconv-lite": "0.4",
|
||||
"rw": "1"
|
||||
}
|
||||
},
|
||||
"d3-ease": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-1.0.7.tgz",
|
||||
"integrity": "sha512-lx14ZPYkhNx0s/2HX5sLFUI3mbasHjSSpwO/KaaNACweVwxUruKyWVcb293wMv1RqTPZyZ8kSZ2NogUZNcLOFQ=="
|
||||
},
|
||||
"d3-fetch": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-1.2.0.tgz",
|
||||
"integrity": "sha512-yC78NBVcd2zFAyR/HnUiBS7Lf6inSCoWcSxFfw8FYL7ydiqe80SazNwoffcqOfs95XaLo7yebsmQqDKSsXUtvA==",
|
||||
"requires": {
|
||||
"d3-dsv": "1"
|
||||
}
|
||||
},
|
||||
"d3-force": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-force/-/d3-force-1.2.1.tgz",
|
||||
"integrity": "sha512-HHvehyaiUlVo5CxBJ0yF/xny4xoaxFxDnBXNvNcfW9adORGZfyNF1dj6DGLKyk4Yh3brP/1h3rnDzdIAwL08zg==",
|
||||
"requires": {
|
||||
"d3-collection": "1",
|
||||
"d3-dispatch": "1",
|
||||
"d3-quadtree": "1",
|
||||
"d3-timer": "1"
|
||||
}
|
||||
},
|
||||
"d3-format": {
|
||||
"version": "1.4.5",
|
||||
"resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.4.5.tgz",
|
||||
"integrity": "sha512-J0piedu6Z8iB6TbIGfZgDzfXxUFN3qQRMofy2oPdXzQibYGqPB/9iMcxr/TGalU+2RsyDO+U4f33id8tbnSRMQ=="
|
||||
},
|
||||
"d3-geo": {
|
||||
"version": "1.12.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-1.12.1.tgz",
|
||||
"integrity": "sha512-XG4d1c/UJSEX9NfU02KwBL6BYPj8YKHxgBEw5om2ZnTRSbIcego6dhHwcxuSR3clxh0EpE38os1DVPOmnYtTPg==",
|
||||
"requires": {
|
||||
"d3-array": "1"
|
||||
}
|
||||
},
|
||||
"d3-hierarchy": {
|
||||
"version": "1.1.9",
|
||||
"resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-1.1.9.tgz",
|
||||
"integrity": "sha512-j8tPxlqh1srJHAtxfvOUwKNYJkQuBFdM1+JAUfq6xqH5eAqf93L7oG1NVqDa4CpFZNvnNKtCYEUC8KY9yEn9lQ=="
|
||||
},
|
||||
"d3-interpolate": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-1.4.0.tgz",
|
||||
"integrity": "sha512-V9znK0zc3jOPV4VD2zZn0sDhZU3WAE2bmlxdIwwQPPzPjvyLkd8B3JUVdS1IDUFDkWZ72c9qnv1GK2ZagTZ8EA==",
|
||||
"requires": {
|
||||
"d3-color": "1"
|
||||
}
|
||||
},
|
||||
"d3-path": {
|
||||
"version": "1.0.9",
|
||||
"resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz",
|
||||
"integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg=="
|
||||
},
|
||||
"d3-polygon": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-1.0.6.tgz",
|
||||
"integrity": "sha512-k+RF7WvI08PC8reEoXa/w2nSg5AUMTi+peBD9cmFc+0ixHfbs4QmxxkarVal1IkVkgxVuk9JSHhJURHiyHKAuQ=="
|
||||
},
|
||||
"d3-quadtree": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-1.0.7.tgz",
|
||||
"integrity": "sha512-RKPAeXnkC59IDGD0Wu5mANy0Q2V28L+fNe65pOCXVdVuTJS3WPKaJlFHer32Rbh9gIo9qMuJXio8ra4+YmIymA=="
|
||||
},
|
||||
"d3-random": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/d3-random/-/d3-random-1.1.2.tgz",
|
||||
"integrity": "sha512-6AK5BNpIFqP+cx/sreKzNjWbwZQCSUatxq+pPRmFIQaWuoD+NrbVWw7YWpHiXpCQ/NanKdtGDuB+VQcZDaEmYQ=="
|
||||
},
|
||||
"d3-scale": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-2.2.2.tgz",
|
||||
"integrity": "sha512-LbeEvGgIb8UMcAa0EATLNX0lelKWGYDQiPdHj+gLblGVhGLyNbaCn3EvrJf0A3Y/uOOU5aD6MTh5ZFCdEwGiCw==",
|
||||
"requires": {
|
||||
"d3-array": "^1.2.0",
|
||||
"d3-collection": "1",
|
||||
"d3-format": "1",
|
||||
"d3-interpolate": "1",
|
||||
"d3-time": "1",
|
||||
"d3-time-format": "2"
|
||||
}
|
||||
},
|
||||
"d3-scale-chromatic": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-1.5.0.tgz",
|
||||
"integrity": "sha512-ACcL46DYImpRFMBcpk9HhtIyC7bTBR4fNOPxwVSl0LfulDAwyiHyPOTqcDG1+t5d4P9W7t/2NAuWu59aKko/cg==",
|
||||
"requires": {
|
||||
"d3-color": "1",
|
||||
"d3-interpolate": "1"
|
||||
}
|
||||
},
|
||||
"d3-selection": {
|
||||
"version": "1.4.2",
|
||||
"resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-1.4.2.tgz",
|
||||
"integrity": "sha512-SJ0BqYihzOjDnnlfyeHT0e30k0K1+5sR3d5fNueCNeuhZTnGw4M4o8mqJchSwgKMXCNFo+e2VTChiSJ0vYtXkg=="
|
||||
},
|
||||
"d3-shape": {
|
||||
"version": "1.3.7",
|
||||
"resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz",
|
||||
"integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==",
|
||||
"requires": {
|
||||
"d3-path": "1"
|
||||
}
|
||||
},
|
||||
"d3-time": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-time/-/d3-time-1.1.0.tgz",
|
||||
"integrity": "sha512-Xh0isrZ5rPYYdqhAVk8VLnMEidhz5aP7htAADH6MfzgmmicPkTo8LhkLxci61/lCB7n7UmE3bN0leRt+qvkLxA=="
|
||||
},
|
||||
"d3-time-format": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-2.3.0.tgz",
|
||||
"integrity": "sha512-guv6b2H37s2Uq/GefleCDtbe0XZAuy7Wa49VGkPVPMfLL9qObgBST3lEHJBMUp8S7NdLQAGIvr2KXk8Hc98iKQ==",
|
||||
"requires": {
|
||||
"d3-time": "1"
|
||||
}
|
||||
},
|
||||
"d3-timer": {
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-1.0.10.tgz",
|
||||
"integrity": "sha512-B1JDm0XDaQC+uvo4DT79H0XmBskgS3l6Ve+1SBCfxgmtIb1AVrPIoqd+nPSv+loMX8szQ0sVUhGngL7D5QPiXw=="
|
||||
},
|
||||
"d3-transition": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-1.3.2.tgz",
|
||||
"integrity": "sha512-sc0gRU4PFqZ47lPVHloMn9tlPcv8jxgOQg+0zjhfZXMQuvppjG6YuwdMBE0TuqCZjeJkLecku/l9R0JPcRhaDA==",
|
||||
"requires": {
|
||||
"d3-color": "1",
|
||||
"d3-dispatch": "1",
|
||||
"d3-ease": "1",
|
||||
"d3-interpolate": "1",
|
||||
"d3-selection": "^1.1.0",
|
||||
"d3-timer": "1"
|
||||
}
|
||||
},
|
||||
"d3-zoom": {
|
||||
"version": "1.8.3",
|
||||
"resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-1.8.3.tgz",
|
||||
"integrity": "sha512-VoLXTK4wvy1a0JpH2Il+F2CiOhVu7VRXWF5M/LroMIh3/zBAC3WAt7QoIvPibOavVo20hN6/37vwAsdBejLyKQ==",
|
||||
"requires": {
|
||||
"d3-dispatch": "1",
|
||||
"d3-drag": "1",
|
||||
"d3-interpolate": "1",
|
||||
"d3-selection": "1",
|
||||
"d3-transition": "1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
@@ -4394,6 +4672,14 @@
|
||||
"slash": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"delaunator": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.0.tgz",
|
||||
"integrity": "sha512-AyLvtyJdbv/U1GkiS6gUUzclRoAY4Gs75qkMygJJhU75LW4DNuSF2RMzpxs9jw9Oz1BobHjTdkG3zdP55VxAqw==",
|
||||
"requires": {
|
||||
"robust-predicates": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"depd": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
|
||||
@@ -4532,9 +4818,9 @@
|
||||
}
|
||||
},
|
||||
"dompurify": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.3.1.tgz",
|
||||
"integrity": "sha512-xGWt+NHAQS+4tpgbOAI08yxW0Pr256Gu/FNE2frZVTbgrBUn8M7tz7/ktS/LZ2MHeGqz6topj0/xY+y8R5FBFw=="
|
||||
"version": "2.3.4",
|
||||
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.3.4.tgz",
|
||||
"integrity": "sha512-6BVcgOAVFXjI0JTjEvZy901Rghm+7fDQOrNIcxB4+gdhj6Kwp6T9VBhBY/AbagKHJocRkDYGd6wvI+p4/10xtQ=="
|
||||
},
|
||||
"domutils": {
|
||||
"version": "1.5.1",
|
||||
@@ -6283,6 +6569,11 @@
|
||||
"side-channel": "^1.0.4"
|
||||
}
|
||||
},
|
||||
"internmap": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz",
|
||||
"integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg=="
|
||||
},
|
||||
"interpret": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz",
|
||||
@@ -7077,15 +7368,15 @@
|
||||
"integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="
|
||||
},
|
||||
"mermaid": {
|
||||
"version": "8.12.1",
|
||||
"resolved": "https://registry.npmjs.org/mermaid/-/mermaid-8.12.1.tgz",
|
||||
"integrity": "sha512-0UCcSF0FLoNcPBsRF4f9OIV32t41fV18//z8o3S+FDz2PbDA1CRGKdQF9IX84VP4Tv9kcgJI/oqJdcBEtB/GPA==",
|
||||
"version": "8.13.8",
|
||||
"resolved": "https://registry.npmjs.org/mermaid/-/mermaid-8.13.8.tgz",
|
||||
"integrity": "sha512-Z5v31rvo8P7BPTiGicdJl9BbzyUe9s5sXILK8sM1g7ijkagpfFjPtXZVsq5P1WlN8m/fUp2PPNXVF9SqeTM91w==",
|
||||
"requires": {
|
||||
"@braintree/sanitize-url": "^3.1.0",
|
||||
"d3": "^5.16.0",
|
||||
"d3": "^7.0.0",
|
||||
"dagre": "^0.8.5",
|
||||
"dagre-d3": "^0.6.4",
|
||||
"dompurify": "2.3.1",
|
||||
"dompurify": "2.3.4",
|
||||
"graphlib": "^2.1.8",
|
||||
"khroma": "^1.4.1",
|
||||
"moment-mini": "^2.24.0",
|
||||
@@ -9336,6 +9627,11 @@
|
||||
"glob": "^7.1.3"
|
||||
}
|
||||
},
|
||||
"robust-predicates": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.1.tgz",
|
||||
"integrity": "sha512-ndEIpszUHiG4HtDsQLeIuMvRsDnn8c8rYStabochtUeCvfuvNptb5TUbVD68LRAILPX7p9nqQGh4xJgn3EHS/g=="
|
||||
},
|
||||
"rtl-detect": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/rtl-detect/-/rtl-detect-1.0.4.tgz",
|
||||
@@ -10271,9 +10567,9 @@
|
||||
}
|
||||
},
|
||||
"stylis": {
|
||||
"version": "4.0.10",
|
||||
"resolved": "https://registry.npmjs.org/stylis/-/stylis-4.0.10.tgz",
|
||||
"integrity": "sha512-m3k+dk7QeJw660eIKRRn3xPF6uuvHs/FFzjX3HQ5ove0qYsiygoAhwn5a3IYKaZPo5LrYD0rfVmtv1gNY1uYwg=="
|
||||
"version": "4.0.13",
|
||||
"resolved": "https://registry.npmjs.org/stylis/-/stylis-4.0.13.tgz",
|
||||
"integrity": "sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag=="
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "7.2.0",
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
"@docusaurus/preset-classic": "^2.0.0-beta.6",
|
||||
"@kiwicopple/prism-react-renderer": "github:kiwicopple/prism-react-renderer",
|
||||
"jsrsasign": "^10.4.1",
|
||||
"mermaid": "^8.6.4",
|
||||
"mermaid": "^8.13.8",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-inlinesvg": "^2.0.1"
|
||||
|
||||
@@ -716,6 +716,48 @@ pages:
|
||||
console.log(event, session)
|
||||
})
|
||||
```
|
||||
- name: Listen to sign in
|
||||
js: |
|
||||
```js
|
||||
supabase.auth.onAuthStateChange((event, session) => {
|
||||
if (event == 'SIGNED_IN') console.log('SIGNED_IN', session)
|
||||
})
|
||||
```
|
||||
- name: Listen to sign out
|
||||
js: |
|
||||
```js
|
||||
supabase.auth.onAuthStateChange((event, session) => {
|
||||
if (event == 'SIGNED_OUT') console.log('SIGNED_OUT', session)
|
||||
})
|
||||
```
|
||||
- name: Listen to token refresh
|
||||
js: |
|
||||
```js
|
||||
supabase.auth.onAuthStateChange((event, session) => {
|
||||
if (event == 'TOKEN_REFRESHED') console.log('TOKEN_REFRESHED', session)
|
||||
})
|
||||
```
|
||||
- name: Listen to user updates
|
||||
js: |
|
||||
```js
|
||||
supabase.auth.onAuthStateChange((event, session) => {
|
||||
if (event == 'USER_UPDATED') console.log('USER_UPDATED', session)
|
||||
})
|
||||
```
|
||||
- name: Listen to user deleted
|
||||
js: |
|
||||
```js
|
||||
supabase.auth.onAuthStateChange((event, session) => {
|
||||
if (event == 'USER_DELETED') console.log('USER_DELETED', session)
|
||||
})
|
||||
```
|
||||
- name: Listen to password recovery events
|
||||
js: |
|
||||
```js
|
||||
supabase.auth.onAuthStateChange((event, session) => {
|
||||
if (event == 'PASSWORD_RECOVERY') console.log('PASSWORD_RECOVERY', session)
|
||||
})
|
||||
```
|
||||
auth.api.getUser():
|
||||
title: 'getUser()'
|
||||
$ref: '@supabase/gotrue-js.GoTrueApi.getUser'
|
||||
|
||||
+14
-10
@@ -3,21 +3,23 @@ var axios = require('axios')
|
||||
var fs = require('fs')
|
||||
|
||||
const query = `
|
||||
query BIO_QUERY($username: String!) {
|
||||
organization(login: $username) {
|
||||
query Sponsors {
|
||||
organization(login: "supabase") {
|
||||
id
|
||||
sponsorshipsAsMaintainer(first: 100) {
|
||||
totalCount
|
||||
sponsors(first: 100) {
|
||||
nodes {
|
||||
createdAt
|
||||
privacyLevel
|
||||
tier {
|
||||
name
|
||||
... on Organization {
|
||||
id
|
||||
createdAt
|
||||
name : login
|
||||
}
|
||||
sponsor {
|
||||
... on User {
|
||||
id
|
||||
createdAt
|
||||
login
|
||||
}
|
||||
}
|
||||
totalCount
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -39,10 +41,11 @@ const fetchAllSponsors = async () => {
|
||||
},
|
||||
}
|
||||
)
|
||||
return data.data.organization.sponsorshipsAsMaintainer
|
||||
return data.data.organization.sponsors
|
||||
}
|
||||
|
||||
const formatResults = (graphqlResponse) => {
|
||||
console.log('graph', graphqlResponse)
|
||||
return graphqlResponse.nodes
|
||||
.filter((x) => !!x.sponsor)
|
||||
.map((x) => ({
|
||||
@@ -65,6 +68,7 @@ const writeFile = (data) => {
|
||||
|
||||
const main = async () => {
|
||||
const sponsorsResponse = await fetchAllSponsors()
|
||||
// console.log('sponsorsResponse.totalCount', sponsorsResponse.totalCount)
|
||||
const formatted = formatResults(sponsorsResponse)
|
||||
writeFile(formatted)
|
||||
}
|
||||
|
||||
@@ -199,4 +199,4 @@
|
||||
"tier": "$49 a month",
|
||||
"sponsor": "CryptoJobsList"
|
||||
}
|
||||
]
|
||||
]
|
||||
@@ -243,11 +243,17 @@ const Nav = (props: Props) => {
|
||||
</div>
|
||||
<div className="hidden lg:flex items-center sm:space-x-3">
|
||||
<a href="https://github.com/supabase/supabase" target="_blank">
|
||||
<Button type="default" icon={<IconStar />}>
|
||||
<Button
|
||||
className="sbui-btn sbui-btn-text sbui-btn--tiny sbui-btn--text-align-center"
|
||||
icon={<IconStar />}
|
||||
>
|
||||
Star us on GitHub
|
||||
</Button>
|
||||
</a>
|
||||
<a href="https://app.supabase.io/">
|
||||
<Button type="default">Sign in</Button>
|
||||
</a>
|
||||
<a href="https://app.supabase.io/new/project">
|
||||
<Button>Start your project</Button>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
+16
-16
@@ -1,33 +1,33 @@
|
||||
[
|
||||
{
|
||||
"type": "Announcement",
|
||||
"title": "Launch Week II: The SQL",
|
||||
"description": "We're launching a product every day for one week in July.",
|
||||
"imgUrl": "images/case-study-monitoro.jpg",
|
||||
"logoUrl": "images/logos/monitoro.png",
|
||||
"organization": "Monitoro",
|
||||
"url": "/blog/2021/07/22/supabase-launch-week-sql",
|
||||
"title": "Supabase Launch Week III: Holiday Special",
|
||||
"description": "Santa's little hackers have been hard at work because we've got another five days of launches ready to go.",
|
||||
"imgUrl": "images/blog/launch-week-three/launch-week-three-og.jpg",
|
||||
"logoUrl": "images/blog/launch-week-three/launch-week-three-og.jpg",
|
||||
"organization": "Supabase",
|
||||
"url": "/blog/2021/11/26/supabase-launch-week-the-trilogy",
|
||||
"postMeta": {
|
||||
"name": "Paul Copplestone",
|
||||
"avatarUrl": "https://avatars0.githubusercontent.com/u/10214025?v=4",
|
||||
"publishDate": "Mar 16, 2020",
|
||||
"readLength": 6
|
||||
"publishDate": "Nov 26, 2021",
|
||||
"readLength": 2
|
||||
},
|
||||
"ctaText": "View case study"
|
||||
},
|
||||
{
|
||||
"type": "Announcement",
|
||||
"title": "Supabase Storage",
|
||||
"description": "Supabase launches Storage leveraging Postgres.",
|
||||
"imgUrl": "images/case-study-monitoro.jpg",
|
||||
"logoUrl": "images/logos/monitoro.png",
|
||||
"organization": "Monitoro",
|
||||
"url": "/blog/2021/03/30/supabase-storage",
|
||||
"title": "Supabase $30m Series A",
|
||||
"description": "Supabase just raised $30M, bringing our total funding to $36M. How will we spend this? Read on to find out.",
|
||||
"imgUrl": "images/blog/series-a/supabase-series-a.png",
|
||||
"logoUrl": "images/blog/series-a/supabase-series-a.png",
|
||||
"organization": "Supabase",
|
||||
"url": "/blog/2021/10/28/supabase-series-a",
|
||||
"postMeta": {
|
||||
"name": "Paul Copplestone",
|
||||
"avatarUrl": "https://avatars0.githubusercontent.com/u/10214025?v=4",
|
||||
"publishDate": "Mar 16, 2020",
|
||||
"readLength": 6
|
||||
"publishDate": "Oct 28, 2021",
|
||||
"readLength": 28
|
||||
},
|
||||
"ctaText": "View case study"
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
},
|
||||
{
|
||||
"question": "Is there a cap on the number of projects for the Free Tier?",
|
||||
"answer": "Yes, on the Free Tier you can have a maximum of two organizations, each with up to two projects. This means that you can have a maximum of four free projects in your account."
|
||||
"answer": "Yes, you have can up to 2 free projects in your account across all organizations that you own. You also are able to create as many organizations as you want."
|
||||
},
|
||||
{
|
||||
"question": "When will I be billed?",
|
||||
|
||||
Reference in new issue
Block a user