Products available:
diff --git a/apps/www/data/Announcement.json b/apps/www/data/Announcement.json
index 5944138270f..a0ab4c9ff86 100644
--- a/apps/www/data/Announcement.json
+++ b/apps/www/data/Announcement.json
@@ -1,7 +1,7 @@
{
- "show": false,
- "text": "Auth UI Launch π",
- "cta": "Vote now",
- "link": "https://www.producthunt.com/posts/pre-built-auth-ui-for-react",
- "badge": "Product Hunt"
+ "show": true,
+ "text": "Launch Week 6 begins December 12th",
+ "cta": "Don't miss a thing, get your free ticket",
+ "link": "https://supabase.com/launch-week",
+ "badge": "Get a reminder"
}
diff --git a/apps/www/data/Footer.json b/apps/www/data/Footer.json
index c67c52972bc..c0988c03dfe 100644
--- a/apps/www/data/Footer.json
+++ b/apps/www/data/Footer.json
@@ -111,7 +111,7 @@
},
{
"text": "Careers",
- "url": "https://about.supabase.com/careers"
+ "url": "/careers"
},
{
"text": "Company",
diff --git a/apps/www/data/career.json b/apps/www/data/career.json
new file mode 100644
index 00000000000..348acdee2c3
--- /dev/null
+++ b/apps/www/data/career.json
@@ -0,0 +1,148 @@
+{
+ "company": [
+ {
+ "number": "50+",
+ "text": "team members\n\nin 20+ countries"
+ },
+ {
+ "number": "15+",
+ "text": "languages spoken"
+ },
+ {
+ "number": "$116M",
+ "text": "in funding"
+ },
+ {
+ "number": "8500+",
+ "text": "community members"
+ },
+ {
+ "number": "1000+",
+ "text": "memes posted\n\n(and counting)"
+ }
+ ],
+ "humanPowered": [
+ {
+ "icon": "egoless",
+ "title": "Egoless",
+ "text": "Willing to do the schlep, the team goals come first."
+ },
+ {
+ "icon": "curious",
+ "title": "Polyglot",
+ "text": "Broad skillets. Growth mindset."
+ },
+ {
+ "icon": "process",
+ "title": "Process Driven",
+ "text": "Engineer yourself out of the job."
+ },
+ {
+ "icon": "honesty",
+ "title": "Intellectual Honesty",
+ "text": "Put our own biases aside."
+ },
+ {
+ "icon": "flexibility",
+ "title": "Kaizen mindset",
+ "text": "Continuously improve all functions."
+ }
+ ],
+ "contributors": [
+ "Isaiah-Hamilton",
+ "Hallidayo",
+ "mertovich",
+ "mikqi",
+ "florian-lefebvre",
+ "m4salah",
+ "carlosstenzel",
+ "M4Tdev",
+ "MisterJimson",
+ "aminamos",
+ "vasudeveloper001",
+ "erondpowell",
+ "alfredlua",
+ "saloni137",
+ "rubensdemelo",
+ "zernonia",
+ "timsonner",
+ "sureshdsk",
+ "owlnai"
+ ],
+ "benefits": [
+ {
+ "icon": "remote",
+ "title": "Fully Remote",
+ "text": "We hire globally. We believe you can do your best work from anywhere. There are no Supabase offices, but we provide a co-working membership that you can use anywhere in the world."
+ },
+ {
+ "icon": "tech_allowance",
+ "title": "Hardware Budget",
+ "text": "Use this budget for anything you need to set up your work environment from tech to office setup."
+ },
+ {
+ "icon": "healthcare",
+ "title": "Health Benefits",
+ "text": "We provide 100% health coverage for employees and 80% for dependants. It's important to us that you & your family have health care covered."
+ },
+ {
+ "icon": "offsite",
+ "title": "Annual Off-Sites",
+ "text": "We believe in the value of in-person time, so we all come together annually for a week. Each year we pick somewhere different in the world. It's a highlight of the year!"
+ },
+ {
+ "icon": "flexibility",
+ "title": "Flexible Work",
+ "text": "Work remotely from anywhere in the world. We work in teams, but we work asynchronously. You know what you need to do and when it needs to be done."
+ },
+ {
+ "icon": "education",
+ "title": "Professional Development",
+ "text": "An annual allowance to spend on professional development and education. Use this for courses, books, conferences, or anything that supports your continuous learning."
+ }
+ ],
+ "positions": [
+ {
+ "title": "Elixir Engineers",
+ "location": "US time zone",
+ "employment": "Full-time",
+ "description": "Elixir is powering more and more backend"
+ },
+ {
+ "title": "Elixir Engineers",
+ "location": "US time zone",
+ "employment": "Full-time",
+ "description": "Elixir is powering more and more backend"
+ },
+ {
+ "title": "Elixir Engineers",
+ "location": "US time zone",
+ "employment": "Full-time",
+ "description": "Elixir is powering more and more backend"
+ },
+ {
+ "title": "Elixir Engineers",
+ "location": "US time zone",
+ "employment": "Full-time",
+ "description": "Elixir is powering more and more backend"
+ }
+ ],
+ "hiring": [
+ {
+ "title": "Recruiter Interview",
+ "text": "Chat with our recruiter to tell us about your career journey, professional goals and we'll share more about Supabase, the role & our recruitment process."
+ },
+ {
+ "title": "Technical / Skill-based Interview",
+ "text": "Meet with the team lead. In this interview we'll aim to learn about your hard skills and problem solving approach."
+ },
+ {
+ "title": "Another Technical / Skill-based Interview",
+ "text": "You'll either meet the department lead or peer. This interview will dive deeper into your hard skills and our expectations for this role."
+ },
+ {
+ "title": "Final Founders Interview",
+ "text": "Our co-founders meet every candidate as the final step. Learn more about Supabase's values, mission and vision directly from them."
+ }
+ ]
+}
diff --git a/apps/www/lib/constants.ts b/apps/www/lib/constants.ts
index e72ab554946..e1ddd15bdd8 100644
--- a/apps/www/lib/constants.ts
+++ b/apps/www/lib/constants.ts
@@ -1,2 +1,18 @@
export const APP_NAME = 'Supabase'
export const DESCRIPTION = 'The Open Source Alternative to Firebase.'
+
+// Launch Weeek
+export const SAMPLE_TICKET_NUMBER = 1234
+export const SITE_URL =
+ process.env.NEXT_PUBLIC_VERCEL_ENV === 'production'
+ ? 'https://supabase.com/launch-week'
+ : process.env.NEXT_PUBLIC_VERCEL_URL
+ ? `https://${process.env.NEXT_PUBLIC_VERCEL_URL}/launch-week`
+ : 'http://localhost:3000/launch-week'
+export const SITE_ORIGIN = new URL(SITE_URL).origin
+export const TWITTER_USER_NAME = 'supabase'
+export const COOKIE = 'supa-launch-week-ticke-user-id'
+export const DATE = 'December 12th, 2022'
+export const TWEET_TEXT = 'Got my ticket for #SupaLaunchWeek 6!'
+export const TWEET_TEXT_GOLDEN = `Woop! I got a Golden Ticket for #SupaLaunchWeek 6! SupaSwag on its way!`
+export const SITE_NAME = 'Supabase'
diff --git a/apps/www/lib/helpers.tsx b/apps/www/lib/helpers.tsx
index 33b8fb8ed3f..2d9722c10f1 100644
--- a/apps/www/lib/helpers.tsx
+++ b/apps/www/lib/helpers.tsx
@@ -11,3 +11,21 @@ export const generateReadingTime = (text: string) => {
export function capitalize(word: string) {
return word[0].toUpperCase() + word.substring(1).toLowerCase()
}
+
+export function isMobileOrTablet() {
+ // https://stackoverflow.com/a/8876069/114157
+ const viewportWidth = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0)
+ return viewportWidth < 1200
+}
+
+// Convert numbers or strings to pixel value
+// Helpful for styled-jsx when using a prop
+// height: ${toPixels(height)}; (supports height={20} and height="20px")
+
+export const toPixels = (value: string | number) => {
+ if (typeof value === 'number') {
+ return `${value}px`
+ }
+
+ return value
+}
diff --git a/apps/www/lib/redirects.js b/apps/www/lib/redirects.js
index 40838ca9228..ef43ecd11af 100644
--- a/apps/www/lib/redirects.js
+++ b/apps/www/lib/redirects.js
@@ -1545,4 +1545,24 @@ module.exports = [
source: '/docs/guides/platform/disk-usage',
destination: '/docs/guides/platform/database-usage',
},
+ {
+ permanent: true,
+ source: '/sign-in',
+ destination: 'https://app.supabase.com/sign-in',
+ },
+ {
+ permanent: true,
+ source: '/sign-up',
+ destination: 'https://app.supabase.com/sign-up',
+ },
+ {
+ permanent: true,
+ source: '/forgot-password',
+ destination: 'https://app.supabase.com/forgot-password',
+ },
+ {
+ permanent: true,
+ source: '/docs/guides/functions/examples',
+ destination: '/docs/guides/functions',
+ },
]
diff --git a/apps/www/lib/rewrites.js b/apps/www/lib/rewrites.js
index b5f9efbea19..1fd564e3039 100644
--- a/apps/www/lib/rewrites.js
+++ b/apps/www/lib/rewrites.js
@@ -17,20 +17,6 @@ module.exports = [
source: '/docs/:path*',
destination: `${process.env.NEXT_PUBLIC_DOCS_URL}/:path*`,
},
- // rewrite to keep existing ticket urls working
- {
- source: '/launch-week/tickets/:path',
- destination: `${process.env.NEXT_PUBLIC_LAUNCHWEEKSITE_URL}/tickets/:path`,
- },
- // rewrite to move ticket website to another path
- {
- source: '/launch-week-register',
- destination: `${process.env.NEXT_PUBLIC_LAUNCHWEEKSITE_URL}`,
- },
- {
- source: '/launch-week-register/:path*',
- destination: `${process.env.NEXT_PUBLIC_LAUNCHWEEKSITE_URL}/:path*`,
- },
{
source: '/new-docs',
destination: `${process.env.NEXT_PUBLIC_REFERENCE_DOCS_URL}`,
diff --git a/apps/www/lib/supabase.ts b/apps/www/lib/supabase.ts
index e2572c7016c..29d235578b7 100644
--- a/apps/www/lib/supabase.ts
+++ b/apps/www/lib/supabase.ts
@@ -3,7 +3,7 @@ import { Database } from './database.types'
const SUPABASE_URL = 'https://obuldanrptloktxcffvn.supabase.co'
const SUPABASE_ANON_KEY =
- 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiIsImlhdCI6MTYzNzY1NjAxNSwiZXhwIjoxOTUzMjMyMDE1fQ.0sfp_Njf7l4g-nOCF5a1TQE11rPqtz8Y10uctIetkBA'
+ 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Im9idWxkYW5ycHRsb2t0eGNmZnZuIiwicm9sZSI6ImFub24iLCJpYXQiOjE2Njk3MjcwMTIsImV4cCI6MTk4NTMwMzAxMn0.SZLqryz_-stF8dgzeVXmzZWPOqdOrBwqJROlFES8v3I'
const supabase = createClient
(SUPABASE_URL, SUPABASE_ANON_KEY)
diff --git a/apps/www/next.config.mjs b/apps/www/next.config.mjs
index 62833ff5871..599600fb9cd 100644
--- a/apps/www/next.config.mjs
+++ b/apps/www/next.config.mjs
@@ -43,12 +43,13 @@ const nextConfig = {
'https://s3-us-west-2.amazonaws.com',
's3-us-west-2.amazonaws.com',
'user-images.githubusercontent.com',
+ 'pbs.twimg.com',
],
},
async headers() {
return [
{
- source: '/(.*)',
+ source: '/:path*',
headers: [
{
key: 'Strict-Transport-Security',
diff --git a/apps/www/package.json b/apps/www/package.json
index 6192a59b010..d4cce5c3ea8 100644
--- a/apps/www/package.json
+++ b/apps/www/package.json
@@ -21,6 +21,7 @@
"@supabase/auth-ui-react": "^0.1.6",
"@supabase/supabase-js": "^2.0.0",
"classnames": "^2.3.1",
+ "cobe": "^0.6.2",
"common": "*",
"config": "*",
"date-fns": "2.10.0",
@@ -55,6 +56,7 @@
"ui": "*",
"use-debounce": "^7.0.1",
"uuid": "^8.3.2",
+ "vanilla-tilt": "1.7.0",
"yup": "^0.32.11"
},
"devDependencies": {
diff --git a/apps/www/pages/careers/career.module.css b/apps/www/pages/careers/career.module.css
new file mode 100644
index 00000000000..4526263ae29
--- /dev/null
+++ b/apps/www/pages/careers/career.module.css
@@ -0,0 +1,83 @@
+.contributors-bg-circle {
+ @apply bg-gradient-to-r from-scale-100 via-scale-700 to-scale-100 rounded-full p-[1px] aspect-square absolute;
+}
+
+.contributors-0 {
+ @apply left-[11%] top-[95%] xl:left-[10%] xl:top-[94%];
+}
+
+.contributors-1 {
+ @apply hidden xl:block xl:left-[70%] xl:top-[61%];
+}
+
+.contributors-2 {
+ @apply left-[31%] top-[62%] xl:left-[16%] xl:top-[70%];
+}
+
+.contributors-3 {
+ @apply left-[11%] top-[52%] md:left-[9%] md:top-[55%] xl:left-[21%] xl:top-[85%];
+}
+
+.contributors-4 {
+ @apply left-[42%] top-[77%] xl:left-[29%] xl:top-[94%];
+}
+
+.contributors-5 {
+ @apply left-[61%] top-[93%] xl:left-[33%] xl:top-[75%];
+}
+
+.contributors-6 {
+ @apply hidden md:block md:z-10 md:left-[50%] md:top-[61%] xl:block xl:left-[83%] xl:top-[60%];
+}
+
+.contributors-7 {
+ @apply hidden xl:block xl:left-[78%] xl:top-[45%];
+}
+
+.contributors-8 {
+ @apply z-10 left-[81%] top-[65%] xl:left-[57%] xl:top-[93%];
+}
+
+.contributors-9 {
+ @apply hidden md:block md:z-10 md:left-[32%] md:top-[89%] xl:block xl:left-[94%] xl:top-[74%];
+}
+
+.contributors-10 {
+ @apply z-10 hidden xl:block xl:left-[58%] xl:top-[58%];
+}
+
+.contributors-11 {
+ @apply hidden xl:block xl:left-[74%] xl:top-[82%];
+}
+
+.contributors-12 {
+ @apply hidden xl:block xl:left-[43%] xl:top-[83%];
+}
+
+.contributors-13 {
+ @apply hidden xl:block xl:left-[61%] xl:top-[77%];
+}
+
+.contributors-14 {
+ @apply hidden xl:block xl:left-[52%] xl:top-[40%];
+}
+
+.contributors-15 {
+ @apply hidden xl:block xl:left-[85%] xl:top-[88%];
+}
+
+.contributors-16 {
+ @apply left-[17%] top-[76%] xl:left-[3%] xl:top-[69%];
+}
+
+.contributors-17 {
+ @apply z-10 left-[64%] top-[53%] xl:left-[47%] xl:top-[67%];
+}
+
+.contributors-18 {
+ @apply left-[67%] top-[74%] xl:left-[36%] xl:top-[57%];
+}
+
+.contributors-19 {
+ @apply z-10 left-[82%] top-[86%] xl:left-[27%] xl:top-[50%];
+}
diff --git a/apps/www/pages/careers/index.tsx b/apps/www/pages/careers/index.tsx
new file mode 100644
index 00000000000..d7d4ec2d29a
--- /dev/null
+++ b/apps/www/pages/careers/index.tsx
@@ -0,0 +1,516 @@
+import { NextPage } from 'next'
+import { NextSeo } from 'next-seo'
+import Image from 'next/image'
+import Link from 'next/link'
+import { useRouter } from 'next/router'
+import ReactMarkdown from 'react-markdown'
+import { Badge, Button, IconCheck } from 'ui'
+import Globe from '~/components/Globe'
+import DefaultLayout from '~/components/Layouts/Default'
+import SectionContainer from '~/components/Layouts/SectionContainer'
+import { useTheme } from '~/components/Providers'
+import career from '~/data/career.json'
+import Styles from './career.module.css'
+
+export async function getStaticProps() {
+ const job_res = await fetch('https://boards-api.greenhouse.io/v1/boards/supabase/jobs')
+
+ const job_data = await job_res.json()
+
+ const contributor_res = await fetch(
+ 'https://api.github.com/repos/supabase/supabase/contributors?per_page=100'
+ )
+ const contributor_arr = await contributor_res.json()
+
+ const contributor_data = await contributor_arr.map(
+ (contributor: { login: string; avatar_url: string; html_url: string }) => {
+ return {
+ login: contributor.login,
+ avatar_url: contributor.avatar_url,
+ html_url: contributor.html_url,
+ }
+ }
+ )
+
+ const contributors = await contributor_data.filter((contributor: any) =>
+ career.contributors.includes(contributor.login)
+ )
+
+ contributors.push(
+ {
+ login: 'XquisiteDreamer',
+ avatar_url: 'https://pbs.twimg.com/profile_images/1475874191249399808/H6TPHpq7_400x400.png',
+ html_url: 'https://twitter.com/XquisiteDreamer',
+ },
+ {
+ login: 'marijanasimag',
+ avatar_url: 'https://avatars.githubusercontent.com/u/46031252?v=4',
+ html_url: 'https://github.com/marijanasimag',
+ },
+ {
+ login: 'estee_tey',
+ avatar_url: 'https://pbs.twimg.com/profile_images/1589662526941253632/s1cu3vuD_400x400.jpg',
+ html_url: 'https://twitter.com/estee_tey',
+ },
+ {
+ login: 'ghostdevv',
+ avatar_url: 'https://avatars.githubusercontent.com/u/47755378?v=4',
+ html_url: 'https://github.com/ghostdevv',
+ }
+ )
+
+ if (!job_data && !contributors) {
+ return {
+ props: {
+ notFound: true,
+ },
+ }
+ }
+
+ return {
+ props: {
+ jobs: job_data.jobs,
+ contributors: contributors,
+ },
+ }
+}
+
+const CareerPage: NextPage = ({ jobs, contributors }: any) => {
+ const { isDarkMode } = useTheme()
+ const { basePath } = useRouter()
+
+ const meta_title = 'Careers | Supabase'
+ const meta_description = 'Help build software developers love'
+
+ return (
+ <>
+
+
+
+
+
Careers
+
+ Weβre on a mission to build the best developer platform
+
+
+ Explore remote possibilities and join our team to help us achieve it.
+
+
+ Open positions
+
+
+
+
+
+ {career.company.map((company: { number: string; text: string }, i: number) => {
+ return (
+
+
+
+ {company.number}
+
+
+ {company.text}
+
+
+ )
+ })}
+
+
+
+
+
+
+
+
+
+
+
+
+ We work together, wherever we are
+
+
+ Working in a globally distributed team is rewarding but has its challenges. We
+ are across many different timezones, so we use tools like Notion, Slack, and
+ Discord to stay connected to our team, and our community.
+
+
+
+
+ We deeply believe in the efficacy of collaborative open source
+
+
+
+
+
+
+
+
+
+
+
+ What is Supabase
+
+
+ Supabase is an open source Firebase alternative, built by developers for
+ developers. Supabase adds auth, realtime, storage, restful APIs, and edge
+ functions to Postgres without a single line of code. Supabase was
+ born-remote. Having a globally distributed, open source company is our
+ secret weapon to hiring top-tier talent.
+
+
+
+
+
+
+
+
+
+
+
+ Human powered
+
+
+ As a completely remote and asynchronous team, we focus on these five traits to
+ keep our team effective:
+
+
+ {career.humanPowered.map(
+ (human: { icon: string; title: string; text: string }, i: number) => {
+ return (
+
+
+
+
{human.title}
+
{human.text}
+
+
+ )
+ }
+ )}
+
+
+
+
+
+
+
+ 1,000 + Contributors building Supabase
+
+
+ We're building a community of communities, bringing together developers from
+ many different backgrounds, as well as new developers looking to get involved
+ with open source. We love celebrating everyone who contributes their time to the
+ Supabase mission.
+
+
+
+ {contributors.map((contributor: any, i: number) => {
+ return (
+
+ )
+ })}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Great people deserve great benefits
+
+
+
+ {career.benefits.map(
+ (benefits: { icon: string; title: string; text: string }, i: number) => {
+ return (
+
+
+
+
{benefits.title}
+
+ {benefits.text}
+
+
+
+ )
+ }
+ )}
+
+
+
+
+
+
+
+
How we hire
+
+ The entire process is fully remote and all communication happens over email or via
+ video chat in Google. Meet. The calls are all 1:1 and usually take between 20-45
+ minutes. We know you are interviewing us too, so please ask questions. We are happy
+ to answer.
+
+
+
+ {career.hiring.map((hiring: { title: string; text: string }, i: number) => {
+ return (
+
+
+
+
+ {hiring.title}
+
+
+ {hiring.text}
+
+
+
+ )
+ })}
+
+
+
+
+
+
+
+
+ Open positions
+
+ {jobs.map(
+ (
+ job: {
+ title: string
+ location: any
+ employment: string
+ description: string
+ absolute_url: string
+ },
+ i: number
+ ) => {
+ return (
+
+
+
+
+ {job.title}
+
+
+
+
+
+
+
+ {job.location.name}
+
+
{job.employment}
+
+
{job.description}
+
Apply for position
+
+
+
+
+ )
+ }
+ )}
+
+
+
+
+
+ >
+ )
+}
+
+export default CareerPage
diff --git a/apps/www/pages/launch-week/index.tsx b/apps/www/pages/launch-week/index.tsx
index 6be78f3fd67..99a45254d41 100644
--- a/apps/www/pages/launch-week/index.tsx
+++ b/apps/www/pages/launch-week/index.tsx
@@ -1,20 +1,48 @@
import { NextSeo } from 'next-seo'
+import _days from '~/components/LaunchWeek/days.json'
+import { WeekDayProps } from '~/components/LaunchWeek/types'
import DefaultLayout from '~/components/Layouts/Default'
import SectionContainer from '~/components/Layouts/SectionContainer'
-import _days from '~/components/LaunchWeek/days.json'
-import HackathonSection from '~/components/LaunchWeek/HackathonSection'
-import LaunchHero from '~/components/LaunchWeek/LaunchHero'
-import { LaunchSection } from '~/components/LaunchWeek/LaunchSection'
-import PreLaunchTeaser from '~/components/LaunchWeek/PreLaunchTeaser'
-import ScheduleInfo from '~/components/LaunchWeek/ScheduleInfo'
-import { WeekDayProps } from '~/components/LaunchWeek/types'
+
+import { createClient, Session } from '@supabase/supabase-js'
+import { useRouter } from 'next/router'
+import { useEffect, useState } from 'react'
+import TicketContainer from '~/components/LaunchWeek/Ticket/TicketContainer'
+import { useTheme } from '~/components/Providers'
+import classNames from 'classnames'
+import styleUtils from '~/components/LaunchWeek/Ticket/utils.module.css'
+import { SITE_ORIGIN } from '~/lib/constants'
const days = _days as WeekDayProps[]
export default function launchweek() {
- const shippingHasStarted = days[0].shipped
- const title = 'Launch Week 5'
- const description = 'Supabase Launch Week 5 | 15-19 Aug 2022'
+ const { isDarkMode } = useTheme()
+
+ const title = 'Launch Week 6'
+ const description = 'Supabase Launch Week 6 | 12-18 Dec 2022'
+
+ const [supabase] = useState(() =>
+ createClient(process.env.NEXT_PUBLIC_SUPABASE_URL!, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!)
+ )
+ const [session, setSession] = useState(null)
+ const { query } = useRouter()
+ const ticketNumber = query.ticketNumber?.toString()
+ const defaultUserData = {
+ id: query.id?.toString(),
+ ticketNumber: ticketNumber ? parseInt(ticketNumber, 10) : undefined,
+ name: query.name?.toString(),
+ username: query.username?.toString(),
+ }
+
+ useEffect(() => {
+ supabase.auth.onAuthStateChange((event, session) => {
+ setSession(session)
+ })
+ }, [])
+
+ useEffect(() => {
+ document.body.className = isDarkMode ? 'dark bg-[#121212]' : 'light bg-[#fff]'
+ }, [isDarkMode])
return (
<>
@@ -26,48 +54,68 @@ export default function launchweek() {
url: `https://supabase.com/launch-week`,
images: [
{
- url: `https://supabase.com/images/launchweek/og-image.jpg`,
+ url: `${SITE_ORIGIN}/images/launchweek/launch-week-6.jpg`,
},
],
}}
/>
-
-
-
-
-
- {!shippingHasStarted && }
-
-
- {!shippingHasStarted && }
-
- {days.map((item: WeekDayProps, i) => {
- return (
-
- )
- })}
+
+
+
+
+
+
+
Dec 12 β 16 at 8 AM PT | 11 AM ET
+
+
+
-
-
-
+
>
)
diff --git a/apps/www/pages/launch-week/ticket-image.tsx b/apps/www/pages/launch-week/ticket-image.tsx
new file mode 100644
index 00000000000..9fa19e85f7f
--- /dev/null
+++ b/apps/www/pages/launch-week/ticket-image.tsx
@@ -0,0 +1,5 @@
+import TicketImage from '~/components/LaunchWeek/Ticket/ticket-image'
+
+export default function TicketOnlyPage() {
+ return
+}
diff --git a/apps/www/pages/launch-week/tickets/[username].tsx b/apps/www/pages/launch-week/tickets/[username].tsx
new file mode 100644
index 00000000000..7cc8c32dbee
--- /dev/null
+++ b/apps/www/pages/launch-week/tickets/[username].tsx
@@ -0,0 +1,120 @@
+import { NextSeo } from 'next-seo'
+import { GetStaticProps, GetStaticPaths } from 'next'
+import Error from 'next/error'
+import DefaultLayout from '~/components/Layouts/Default'
+import SectionContainer from '~/components/Layouts/SectionContainer'
+import TicketContainer from '~/components/LaunchWeek/Ticket/TicketContainer'
+import { SITE_URL, SAMPLE_TICKET_NUMBER } from '~/lib/constants'
+import { createClient } from '@supabase/supabase-js'
+import { useEffect, useState } from 'react'
+import { FastGlobOptionsWithoutCwd } from 'globby'
+import { useTheme } from '~/components/Providers'
+
+type Props = {
+ username: string | null
+ name: string | null
+ ticketNumber: number | null
+ golden: boolean
+}
+
+const supabaseAdmin = createClient(
+ process.env.NEXT_PUBLIC_SUPABASE_URL!,
+ process.env.SUPABASE_SERVICE_ROLE_SECRET!
+)
+
+export default function TicketShare({ username, ticketNumber, name, golden }: Props) {
+ const { isDarkMode } = useTheme()
+
+ const [supabase] = useState(() =>
+ createClient(process.env.NEXT_PUBLIC_SUPABASE_URL!, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!)
+ )
+ const description = 'Supabase Launch Week 6 | 12-16 Dec 2022'
+
+ if (!ticketNumber) {
+ return
+ }
+
+ const ogImageUrl = `https://obuldanrptloktxcffvn.functions.supabase.co/launchweek-ticket-og?username=${encodeURIComponent(
+ username ?? ''
+ )}`
+
+ useEffect(() => {
+ document.body.className = isDarkMode ? 'dark bg-[#121212]' : 'light bg-[#fff]'
+ }, [isDarkMode])
+
+ return (
+ <>
+
+
+
+
+
+
+
+
+ >
+ )
+}
+
+export const getStaticProps: GetStaticProps
= async ({ params }) => {
+ const username = params?.username?.toString() || null
+ let name: string | null | undefined
+ let ticketNumber: number | null | undefined
+ let golden = false
+
+ if (username) {
+ const { data: user } = await supabaseAdmin!
+ .from('lw6_tickets_golden')
+ .select('name, ticketNumber, golden')
+ .eq('username', username)
+ .single()
+ name = user?.name
+ ticketNumber = user?.ticketNumber
+ golden = user?.golden ?? false
+ }
+ return {
+ props: {
+ username: ticketNumber ? username : null,
+ usernameFromParams: username || null,
+ name: ticketNumber ? name || username || null : null,
+ ticketNumber: ticketNumber || SAMPLE_TICKET_NUMBER,
+ golden,
+ },
+ revalidate: 5,
+ }
+}
+
+export const getStaticPaths: GetStaticPaths = async () => {
+ return Promise.resolve({
+ paths: [],
+ fallback: 'blocking',
+ })
+}
diff --git a/apps/www/pages/launch-week/tickets/index.tsx b/apps/www/pages/launch-week/tickets/index.tsx
new file mode 100644
index 00000000000..fba61ea897e
--- /dev/null
+++ b/apps/www/pages/launch-week/tickets/index.tsx
@@ -0,0 +1,77 @@
+import { NextSeo } from 'next-seo'
+import DefaultLayout from '~/components/Layouts/Default'
+import SectionContainer from '~/components/Layouts/SectionContainer'
+import TicketContainer from '~/components/LaunchWeek/Ticket/TicketContainer'
+import { SITE_URL } from '~/lib/constants'
+import { useRouter } from 'next/router'
+import { createClient, Session } from '@supabase/supabase-js'
+import { useState, useEffect } from 'react'
+import { useTheme } from '~/components/Providers'
+
+export default function TicketHome() {
+ const { isDarkMode } = useTheme()
+
+ const [supabase] = useState(() =>
+ createClient(process.env.NEXT_PUBLIC_SUPABASE_URL!, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!)
+ )
+ const [session, setSession] = useState(null)
+ const description = 'Supabase Launch Week 6 | 12-16 Dec 2022'
+ const { query } = useRouter()
+ const ticketNumber = query.ticketNumber?.toString()
+ const defaultUserData = {
+ id: query.id?.toString(),
+ ticketNumber: ticketNumber ? parseInt(ticketNumber, 10) : undefined,
+ name: query.name?.toString(),
+ username: query.username?.toString(),
+ }
+
+ useEffect(() => {
+ supabase.auth.onAuthStateChange((event, session) => {
+ setSession(session)
+ })
+ }, [])
+
+ useEffect(() => {
+ document.body.className = isDarkMode ? 'dark bg-[#121212]' : 'light bg-[#fff]'
+ }, [isDarkMode])
+
+ return (
+ <>
+
+
+
+
+
+
+
Dec 12 β 16 at 8 AM PT | 11 AM ET
+
+
+
+
+
+ >
+ )
+}
diff --git a/apps/www/pages/partners/[slug].tsx b/apps/www/pages/partners/[slug].tsx
index 9eb63b5c310..dc498cae9fc 100644
--- a/apps/www/pages/partners/[slug].tsx
+++ b/apps/www/pages/partners/[slug].tsx
@@ -224,6 +224,7 @@ export const getStaticProps: GetStaticProps = async ({ params }) => {
let { data: partner } = await supabase
.from('partners')
.select('*')
+ .eq('approved', true)
.eq('slug', params!.slug as string)
.single()
diff --git a/apps/www/public/images/blog/2020/aom5r917s792cc081bbz.png b/apps/www/public/images/blog/2020/aom5r917s792cc081bbz.png
new file mode 100644
index 00000000000..cf1b4676218
Binary files /dev/null and b/apps/www/public/images/blog/2020/aom5r917s792cc081bbz.png differ
diff --git a/apps/www/public/images/blog/2020/b4o39am95zcl5vl54j75.png b/apps/www/public/images/blog/2020/b4o39am95zcl5vl54j75.png
new file mode 100644
index 00000000000..0e34a02e22f
Binary files /dev/null and b/apps/www/public/images/blog/2020/b4o39am95zcl5vl54j75.png differ
diff --git a/apps/www/public/images/blog/2020/jalcaoz4lsp2b6wegah5.png b/apps/www/public/images/blog/2020/jalcaoz4lsp2b6wegah5.png
new file mode 100644
index 00000000000..7f256983a4a
Binary files /dev/null and b/apps/www/public/images/blog/2020/jalcaoz4lsp2b6wegah5.png differ
diff --git a/apps/www/public/images/blog/2020/jzzm7u56ns6ega9uyc4j.png b/apps/www/public/images/blog/2020/jzzm7u56ns6ega9uyc4j.png
new file mode 100644
index 00000000000..7e0f242504d
Binary files /dev/null and b/apps/www/public/images/blog/2020/jzzm7u56ns6ega9uyc4j.png differ
diff --git a/apps/www/public/images/blog/2020/lai1mxg62kffyd2khmtm.png b/apps/www/public/images/blog/2020/lai1mxg62kffyd2khmtm.png
new file mode 100644
index 00000000000..52cc3289757
Binary files /dev/null and b/apps/www/public/images/blog/2020/lai1mxg62kffyd2khmtm.png differ
diff --git a/apps/www/public/images/blog/2021-march/54yykm6h9hqpric87zad.png b/apps/www/public/images/blog/2021-march/54yykm6h9hqpric87zad.png
new file mode 100644
index 00000000000..37b25e74a0f
Binary files /dev/null and b/apps/www/public/images/blog/2021-march/54yykm6h9hqpric87zad.png differ
diff --git a/apps/www/public/images/blog/2021-march/5j5aqyjdh74qm83slmli.png b/apps/www/public/images/blog/2021-march/5j5aqyjdh74qm83slmli.png
new file mode 100644
index 00000000000..57f62c22560
Binary files /dev/null and b/apps/www/public/images/blog/2021-march/5j5aqyjdh74qm83slmli.png differ
diff --git a/apps/www/public/images/blog/2021-march/7rcfbb12sfabevto571j.png b/apps/www/public/images/blog/2021-march/7rcfbb12sfabevto571j.png
new file mode 100644
index 00000000000..2076273baf0
Binary files /dev/null and b/apps/www/public/images/blog/2021-march/7rcfbb12sfabevto571j.png differ
diff --git a/apps/www/public/images/blog/2021-march/u3dljulzsyqu58i75epn.png b/apps/www/public/images/blog/2021-march/u3dljulzsyqu58i75epn.png
new file mode 100644
index 00000000000..23d3b4a2b98
Binary files /dev/null and b/apps/www/public/images/blog/2021-march/u3dljulzsyqu58i75epn.png differ
diff --git a/apps/www/public/images/blog/2022-11-24-sql-nosql-postgresql/sql-nosql-postgresql.jpg b/apps/www/public/images/blog/2022-11-24-sql-nosql-postgresql/sql-nosql-postgresql.jpg
new file mode 100644
index 00000000000..4bd166328fd
Binary files /dev/null and b/apps/www/public/images/blog/2022-11-24-sql-nosql-postgresql/sql-nosql-postgresql.jpg differ
diff --git a/apps/www/public/images/blog/transparent-column-encryption-with-postgres.jpg b/apps/www/public/images/blog/transparent-column-encryption-with-postgres.jpg
new file mode 100644
index 00000000000..8957abe19b6
Binary files /dev/null and b/apps/www/public/images/blog/transparent-column-encryption-with-postgres.jpg differ
diff --git a/apps/www/public/images/career/1.jpg b/apps/www/public/images/career/1.jpg
new file mode 100644
index 00000000000..cc2feb0edf7
Binary files /dev/null and b/apps/www/public/images/career/1.jpg differ
diff --git a/apps/www/public/images/career/2.jpg b/apps/www/public/images/career/2.jpg
new file mode 100644
index 00000000000..81e2f6db6fa
Binary files /dev/null and b/apps/www/public/images/career/2.jpg differ
diff --git a/apps/www/public/images/career/3.jpg b/apps/www/public/images/career/3.jpg
new file mode 100644
index 00000000000..2eec177a69b
Binary files /dev/null and b/apps/www/public/images/career/3.jpg differ
diff --git a/apps/www/public/images/career/4.jpg b/apps/www/public/images/career/4.jpg
new file mode 100644
index 00000000000..3338f52814d
Binary files /dev/null and b/apps/www/public/images/career/4.jpg differ
diff --git a/apps/www/public/images/career/5.jpg b/apps/www/public/images/career/5.jpg
new file mode 100644
index 00000000000..241b22cb010
Binary files /dev/null and b/apps/www/public/images/career/5.jpg differ
diff --git a/apps/www/public/images/career/6.jpg b/apps/www/public/images/career/6.jpg
new file mode 100644
index 00000000000..77093bcd102
Binary files /dev/null and b/apps/www/public/images/career/6.jpg differ
diff --git a/apps/www/public/images/career/careers_og.jpg b/apps/www/public/images/career/careers_og.jpg
new file mode 100644
index 00000000000..4eafc73441d
Binary files /dev/null and b/apps/www/public/images/career/careers_og.jpg differ
diff --git a/apps/www/public/images/career/icons/billing-light.svg b/apps/www/public/images/career/icons/billing-light.svg
new file mode 100644
index 00000000000..ae3d22e236d
--- /dev/null
+++ b/apps/www/public/images/career/icons/billing-light.svg
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/www/public/images/career/icons/crisis_control-light.svg b/apps/www/public/images/career/icons/crisis_control-light.svg
new file mode 100644
index 00000000000..ea1c63faf26
--- /dev/null
+++ b/apps/www/public/images/career/icons/crisis_control-light.svg
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/apps/www/public/images/career/icons/curious-dark.svg b/apps/www/public/images/career/icons/curious-dark.svg
new file mode 100644
index 00000000000..3ac482aab8c
--- /dev/null
+++ b/apps/www/public/images/career/icons/curious-dark.svg
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/apps/www/public/images/career/icons/curious-light.svg b/apps/www/public/images/career/icons/curious-light.svg
new file mode 100644
index 00000000000..a2c8ca8dc69
--- /dev/null
+++ b/apps/www/public/images/career/icons/curious-light.svg
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/apps/www/public/images/career/icons/education-dark.svg b/apps/www/public/images/career/icons/education-dark.svg
new file mode 100644
index 00000000000..db5c8c1153f
--- /dev/null
+++ b/apps/www/public/images/career/icons/education-dark.svg
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/apps/www/public/images/career/icons/education-light.svg b/apps/www/public/images/career/icons/education-light.svg
new file mode 100644
index 00000000000..3e92aca7bff
--- /dev/null
+++ b/apps/www/public/images/career/icons/education-light.svg
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/apps/www/public/images/career/icons/egoless-dark.svg b/apps/www/public/images/career/icons/egoless-dark.svg
new file mode 100644
index 00000000000..0ac7b4e3303
--- /dev/null
+++ b/apps/www/public/images/career/icons/egoless-dark.svg
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/www/public/images/career/icons/egoless-light.svg b/apps/www/public/images/career/icons/egoless-light.svg
new file mode 100644
index 00000000000..62ca09e67b9
--- /dev/null
+++ b/apps/www/public/images/career/icons/egoless-light.svg
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/www/public/images/career/icons/flexibility-dark.svg b/apps/www/public/images/career/icons/flexibility-dark.svg
new file mode 100644
index 00000000000..bfb0cc7d462
--- /dev/null
+++ b/apps/www/public/images/career/icons/flexibility-dark.svg
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/www/public/images/career/icons/flexibility-light.svg b/apps/www/public/images/career/icons/flexibility-light.svg
new file mode 100644
index 00000000000..45f5cb66136
--- /dev/null
+++ b/apps/www/public/images/career/icons/flexibility-light.svg
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/www/public/images/career/icons/globe-dark.svg b/apps/www/public/images/career/icons/globe-dark.svg
new file mode 100644
index 00000000000..b5182ca85ab
--- /dev/null
+++ b/apps/www/public/images/career/icons/globe-dark.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/apps/www/public/images/career/icons/healthcare-dark.svg b/apps/www/public/images/career/icons/healthcare-dark.svg
new file mode 100644
index 00000000000..946324be4fc
--- /dev/null
+++ b/apps/www/public/images/career/icons/healthcare-dark.svg
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/www/public/images/career/icons/healthcare-light.svg b/apps/www/public/images/career/icons/healthcare-light.svg
new file mode 100644
index 00000000000..3fa16cfd2b1
--- /dev/null
+++ b/apps/www/public/images/career/icons/healthcare-light.svg
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/www/public/images/career/icons/honesty-dark.svg b/apps/www/public/images/career/icons/honesty-dark.svg
new file mode 100644
index 00000000000..5f7a3c5f16a
--- /dev/null
+++ b/apps/www/public/images/career/icons/honesty-dark.svg
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/apps/www/public/images/career/icons/honesty-light.svg b/apps/www/public/images/career/icons/honesty-light.svg
new file mode 100644
index 00000000000..b6fa609b7e8
--- /dev/null
+++ b/apps/www/public/images/career/icons/honesty-light.svg
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/apps/www/public/images/career/icons/jobs-dark.svg b/apps/www/public/images/career/icons/jobs-dark.svg
new file mode 100644
index 00000000000..206189f35b7
--- /dev/null
+++ b/apps/www/public/images/career/icons/jobs-dark.svg
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/www/public/images/career/icons/jobs-light.svg b/apps/www/public/images/career/icons/jobs-light.svg
new file mode 100644
index 00000000000..ff571524680
--- /dev/null
+++ b/apps/www/public/images/career/icons/jobs-light.svg
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/www/public/images/career/icons/kaizen-dark.svg b/apps/www/public/images/career/icons/kaizen-dark.svg
new file mode 100644
index 00000000000..6f227f02088
--- /dev/null
+++ b/apps/www/public/images/career/icons/kaizen-dark.svg
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/www/public/images/career/icons/kaizen-light.svg b/apps/www/public/images/career/icons/kaizen-light.svg
new file mode 100644
index 00000000000..108993c5a30
--- /dev/null
+++ b/apps/www/public/images/career/icons/kaizen-light.svg
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/www/public/images/career/icons/offsite-dark.svg b/apps/www/public/images/career/icons/offsite-dark.svg
new file mode 100644
index 00000000000..9c4b5d01426
--- /dev/null
+++ b/apps/www/public/images/career/icons/offsite-dark.svg
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/apps/www/public/images/career/icons/offsite-light.svg b/apps/www/public/images/career/icons/offsite-light.svg
new file mode 100644
index 00000000000..c1b916f83fd
--- /dev/null
+++ b/apps/www/public/images/career/icons/offsite-light.svg
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/apps/www/public/images/career/icons/open_source-dark.svg b/apps/www/public/images/career/icons/open_source-dark.svg
new file mode 100644
index 00000000000..a499faa7824
--- /dev/null
+++ b/apps/www/public/images/career/icons/open_source-dark.svg
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/www/public/images/career/icons/open_source-light.svg b/apps/www/public/images/career/icons/open_source-light.svg
new file mode 100644
index 00000000000..f2eeb46e1db
--- /dev/null
+++ b/apps/www/public/images/career/icons/open_source-light.svg
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/www/public/images/career/icons/process-dark.svg b/apps/www/public/images/career/icons/process-dark.svg
new file mode 100644
index 00000000000..b88fa4929da
--- /dev/null
+++ b/apps/www/public/images/career/icons/process-dark.svg
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/www/public/images/career/icons/process-light.svg b/apps/www/public/images/career/icons/process-light.svg
new file mode 100644
index 00000000000..84a2624f4ae
--- /dev/null
+++ b/apps/www/public/images/career/icons/process-light.svg
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/www/public/images/career/icons/remote-dark.svg b/apps/www/public/images/career/icons/remote-dark.svg
new file mode 100644
index 00000000000..48870018b63
--- /dev/null
+++ b/apps/www/public/images/career/icons/remote-dark.svg
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/www/public/images/career/icons/remote-light.svg b/apps/www/public/images/career/icons/remote-light.svg
new file mode 100644
index 00000000000..048f9285284
--- /dev/null
+++ b/apps/www/public/images/career/icons/remote-light.svg
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/www/public/images/career/icons/tech_allowance-dark.svg b/apps/www/public/images/career/icons/tech_allowance-dark.svg
new file mode 100644
index 00000000000..474a9af89f5
--- /dev/null
+++ b/apps/www/public/images/career/icons/tech_allowance-dark.svg
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/apps/www/public/images/career/icons/tech_allowance-light.svg b/apps/www/public/images/career/icons/tech_allowance-light.svg
new file mode 100644
index 00000000000..8770d71bcec
--- /dev/null
+++ b/apps/www/public/images/career/icons/tech_allowance-light.svg
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/apps/www/public/images/career/icons/time_off-light.svg b/apps/www/public/images/career/icons/time_off-light.svg
new file mode 100644
index 00000000000..a7c6674a0d2
--- /dev/null
+++ b/apps/www/public/images/career/icons/time_off-light.svg
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/apps/www/public/images/launchweek/2x-gold-ticket-background.jpg b/apps/www/public/images/launchweek/2x-gold-ticket-background.jpg
new file mode 100644
index 00000000000..2458ba6e641
Binary files /dev/null and b/apps/www/public/images/launchweek/2x-gold-ticket-background.jpg differ
diff --git a/apps/www/public/images/launchweek/2x-regular-ticket-background.jpg b/apps/www/public/images/launchweek/2x-regular-ticket-background.jpg
new file mode 100644
index 00000000000..e2bcd23470e
Binary files /dev/null and b/apps/www/public/images/launchweek/2x-regular-ticket-background.jpg differ
diff --git a/apps/www/public/images/launchweek/gold-ticket-background.png b/apps/www/public/images/launchweek/gold-ticket-background.png
new file mode 100644
index 00000000000..5cdf8d40a9c
Binary files /dev/null and b/apps/www/public/images/launchweek/gold-ticket-background.png differ
diff --git a/apps/www/public/images/launchweek/golden-ticket.svg b/apps/www/public/images/launchweek/golden-ticket.svg
new file mode 100644
index 00000000000..9f4bebcf11e
--- /dev/null
+++ b/apps/www/public/images/launchweek/golden-ticket.svg
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/www/public/images/launchweek/green-ticket.svg b/apps/www/public/images/launchweek/green-ticket.svg
new file mode 100644
index 00000000000..350ca923c70
--- /dev/null
+++ b/apps/www/public/images/launchweek/green-ticket.svg
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/www/public/images/launchweek/launch-week-6.jpg b/apps/www/public/images/launchweek/launch-week-6.jpg
new file mode 100644
index 00000000000..cf7c77d3cda
Binary files /dev/null and b/apps/www/public/images/launchweek/launch-week-6.jpg differ
diff --git a/apps/www/public/images/launchweek/launchweek-logo--dark.svg b/apps/www/public/images/launchweek/launchweek-logo--dark.svg
index 90d87475b6f..5a3f62beff2 100644
--- a/apps/www/public/images/launchweek/launchweek-logo--dark.svg
+++ b/apps/www/public/images/launchweek/launchweek-logo--dark.svg
@@ -1,11 +1,20 @@
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/www/public/images/launchweek/launchweek-logo--dark_old.svg b/apps/www/public/images/launchweek/launchweek-logo--dark_old.svg
new file mode 100644
index 00000000000..90d87475b6f
--- /dev/null
+++ b/apps/www/public/images/launchweek/launchweek-logo--dark_old.svg
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/www/public/images/launchweek/launchweek-logo--light.svg b/apps/www/public/images/launchweek/launchweek-logo--light.svg
index cbe5120a68c..1c272051d85 100644
--- a/apps/www/public/images/launchweek/launchweek-logo--light.svg
+++ b/apps/www/public/images/launchweek/launchweek-logo--light.svg
@@ -1,11 +1,20 @@
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/www/public/images/launchweek/launchweek-logo--light__old.svg b/apps/www/public/images/launchweek/launchweek-logo--light__old.svg
new file mode 100644
index 00000000000..cbe5120a68c
--- /dev/null
+++ b/apps/www/public/images/launchweek/launchweek-logo--light__old.svg
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/www/public/images/launchweek/launchweek-logo--light_old0.svg b/apps/www/public/images/launchweek/launchweek-logo--light_old0.svg
new file mode 100644
index 00000000000..5a3f62beff2
--- /dev/null
+++ b/apps/www/public/images/launchweek/launchweek-logo--light_old0.svg
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/www/public/images/launchweek/regular-ticket-background.png b/apps/www/public/images/launchweek/regular-ticket-background.png
new file mode 100644
index 00000000000..044d67a0de7
Binary files /dev/null and b/apps/www/public/images/launchweek/regular-ticket-background.png differ
diff --git a/apps/www/public/images/launchweek/supabadge-connected.svg b/apps/www/public/images/launchweek/supabadge-connected.svg
new file mode 100644
index 00000000000..dc9995463b2
--- /dev/null
+++ b/apps/www/public/images/launchweek/supabadge-connected.svg
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/www/public/images/launchweek/supabadge-disconnected.svg b/apps/www/public/images/launchweek/supabadge-disconnected.svg
new file mode 100644
index 00000000000..f121eb57e36
--- /dev/null
+++ b/apps/www/public/images/launchweek/supabadge-disconnected.svg
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/www/public/images/launchweek/supabadge-gold.svg b/apps/www/public/images/launchweek/supabadge-gold.svg
new file mode 100644
index 00000000000..583db3b4f47
--- /dev/null
+++ b/apps/www/public/images/launchweek/supabadge-gold.svg
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/www/public/images/launchweek/ticket-logo-dark.svg b/apps/www/public/images/launchweek/ticket-logo-dark.svg
new file mode 100644
index 00000000000..3263424d622
--- /dev/null
+++ b/apps/www/public/images/launchweek/ticket-logo-dark.svg
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/www/public/images/launchweek/ticket-logo-light.svg b/apps/www/public/images/launchweek/ticket-logo-light.svg
new file mode 100644
index 00000000000..2af92a1516c
--- /dev/null
+++ b/apps/www/public/images/launchweek/ticket-logo-light.svg
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/www/public/images/twitter-profiles/rLgwUZSB_400x400.jpg b/apps/www/public/images/twitter-profiles/rLgwUZSB_400x400.jpg
new file mode 100644
index 00000000000..02ebc8e7afc
Binary files /dev/null and b/apps/www/public/images/twitter-profiles/rLgwUZSB_400x400.jpg differ
diff --git a/apps/www/public/rss.xml b/apps/www/public/rss.xml
index 9fc43287ca0..947b9a551dd 100644
--- a/apps/www/public/rss.xml
+++ b/apps/www/public/rss.xml
@@ -5,14 +5,35 @@
https://supabase.com
Latest news from Supabase
en
- Wed, 16 Nov 2022 03:03:30 +0000
+ Wed, 30 Nov 2022 16:04:00 +0000
-
+
https://supabase.com/blog/transparent-column-encryption-with-postgres
+ Transparent Column Encryption with Postgres
+ https://supabase.com/blog/transparent-column-encryption-with-postgres
+ Using pgsodium's Transparent Column Encryption to encrypt data and provide your users with row-level encryption.
+ Wed, 30 Nov 2022 16:04:00 +0000
+
+-
+
https://supabase.com/blog/sql-or-nosql-both-with-postgresql
+ SQL or NoSQL? Why not use both (with PostgreSQL)?
+ https://supabase.com/blog/sql-or-nosql-both-with-postgresql
+ How to turn Postgres into an easy-to-use NoSQL database that retains all the power of SQL
+ Wed, 23 Nov 2022 16:04:00 +0000
+
+-
+
https://supabase.com/blog/flutter-authentication-and-authorization-with-rls
+ Flutter Authentication and Authorization with RLS
+ https://supabase.com/blog/flutter-authentication-and-authorization-with-rls
+ Learn how you can secure your Flutter app using Supabase Row Level Security.
+ Mon, 21 Nov 2022 16:04:00 +0000
+
+-
https://supabase.com/blog/fetching-and-caching-supabase-data-in-next-js-server-components
Fetching and caching Supabase data in Next.js 13 Server Components
https://supabase.com/blog/fetching-and-caching-supabase-data-in-next-js-server-components
Next.js 13 introduces new data fetching and caching methods to enable React Server Components and Suspense.
- Wed, 16 Nov 2022 03:03:30 +0000
+ Wed, 16 Nov 2022 16:04:00 +0000
-
https://supabase.com/blog/authentication-in-ionic-angular
@@ -26,196 +47,196 @@
Supabase Beta October 2022
https://supabase.com/blog/supabase-beta-update-october-2022
New SDKs, quickstarts, Functions tricks, and more. But, more importantly, Launch Week 6οΈ has a date!
- Tue, 01 Nov 2022 02:02:30 +0000
+ Tue, 01 Nov 2022 16:04:00 +0000
-
https://supabase.com/blog/postgresql-commitfest
What is PostgreSQL commitfest and how to contribute
https://supabase.com/blog/postgresql-commitfest
A time-tested method for contributing to the core Postgres code
- Wed, 26 Oct 2022 02:02:30 +0000
+ Wed, 26 Oct 2022 16:04:00 +0000
-
https://supabase.com/blog/supabase-flutter-sdk-v1-released
supabase-flutter v1 Released
https://supabase.com/blog/supabase-flutter-sdk-v1-released
We've released supabase-flutter v1. More intuitive way of accessing Supabase from your Flutter application.
- Thu, 20 Oct 2022 02:02:30 +0000
+ Thu, 20 Oct 2022 16:04:00 +0000
-
https://supabase.com/blog/supabase-js-v2-released
supabase-js v2 Released
https://supabase.com/blog/supabase-js-v2-released
We've released supabase-js v2. Updated examples, quickstarts, and an improved experience.
- Wed, 19 Oct 2022 02:02:30 +0000
+ Wed, 19 Oct 2022 16:04:00 +0000
-
https://supabase.com/blog/postgres-full-text-search-vs-the-rest
Postgres Full Text Search vs the rest
https://supabase.com/blog/postgres-full-text-search-vs-the-rest
Comparing one of the most popular Postgres features against alternatives
- Thu, 13 Oct 2022 02:02:30 +0000
+ Thu, 13 Oct 2022 16:04:00 +0000
-
https://supabase.com/blog/supabase-beta-update-september-2022
Supabase Beta September 2022
https://supabase.com/blog/supabase-beta-update-september-2022
We were too focused on clearing out the backlog so we didn't ship anything new last month... or did we?!
- Tue, 04 Oct 2022 02:02:30 +0000
+ Tue, 04 Oct 2022 16:04:00 +0000
-
https://supabase.com/blog/postgres-wasm
Postgres WASM by Snaplet and Supabase
https://supabase.com/blog/postgres-wasm
We're open sourcing postgres-wasm, a PostgresQL server that runs inside a browser, with our friends at Snaplet.
- Sun, 02 Oct 2022 02:02:30 +0000
+ Sun, 02 Oct 2022 16:04:00 +0000
-
https://supabase.com/blog/choosing-a-postgres-primary-key
Choosing a Postgres Primary Key
https://supabase.com/blog/choosing-a-postgres-primary-key
Turns out the question of which identifier to use as a Primary Key is complicated -- we're going to dive into some of the complexity and inherent trade-offs, and figure things out
- Wed, 07 Sep 2022 02:02:30 +0000
+ Wed, 07 Sep 2022 16:04:00 +0000
-
https://supabase.com/blog/supabase-beta-update-august-2022
Supabase Beta August 2022
https://supabase.com/blog/supabase-beta-update-august-2022
Launch Week Special. See everything we shipped, plus winners of the Hackathon and the extended Community Highlights
- Tue, 06 Sep 2022 02:02:30 +0000
+ Tue, 06 Sep 2022 16:04:00 +0000
-
https://supabase.com/blog/launch-week-5-hackathon-winners
Launch Week 5 Hackathon Winners
https://supabase.com/blog/launch-week-5-hackathon-winners
Announcing the winners of the Launch Week 5 Hackathon!
- Wed, 24 Aug 2022 02:02:30 +0000
+ Wed, 24 Aug 2022 16:04:00 +0000
-
https://supabase.com/blog/building-a-realtime-trello-board-with-supabase-and-angular
Building a Realtime Trello Board with Supabase and Angular
https://supabase.com/blog/building-a-realtime-trello-board-with-supabase-and-angular
Go beyond the hello world example with this real world project.
- Tue, 23 Aug 2022 02:02:30 +0000
+ Tue, 23 Aug 2022 16:04:00 +0000
-
https://supabase.com/blog/supabase-vault
Supabase Vault
https://supabase.com/blog/supabase-vault
Today we're announcing Vault, a Postgres extension for managing secrets and encryption inside your database.
- Thu, 18 Aug 2022 02:02:30 +0000
+ Thu, 18 Aug 2022 16:04:00 +0000
-
https://supabase.com/blog/postgrest-v10
PostgREST v10: EXPLAIN and Improved Relationship Detection
https://supabase.com/blog/postgrest-v10
Today, PostgREST 10 was released. Let's take a look at some of the new features that go hand in hand with supabase-js v2.
- Thu, 18 Aug 2022 02:02:30 +0000
+ Thu, 18 Aug 2022 16:04:00 +0000
-
https://supabase.com/blog/pg-jsonschema-a-postgres-extension-for-json-validation
pg_jsonschema: JSON Schema support for Postgres
https://supabase.com/blog/pg-jsonschema-a-postgres-extension-for-json-validation
Today we're releasing pg_jsonschema, a Postgres extension for JSON validation.
- Thu, 18 Aug 2022 02:02:30 +0000
+ Thu, 18 Aug 2022 16:04:00 +0000
-
https://supabase.com/blog/launch-week-5-one-more-thing
One more thing
https://supabase.com/blog/launch-week-5-one-more-thing
Let's be honest, it's never just one more thing.
- Thu, 18 Aug 2022 02:02:30 +0000
+ Thu, 18 Aug 2022 16:04:00 +0000
-
https://supabase.com/blog/launch-week-5-community-day
Community Day
https://supabase.com/blog/launch-week-5-community-day
Wrapping up Launch Week 5 with contributors, partners, and friends.
- Thu, 18 Aug 2022 02:02:30 +0000
+ Thu, 18 Aug 2022 16:04:00 +0000
-
https://supabase.com/blog/supabase-realtime-multiplayer-general-availability
Realtime: Multiplayer Edition
https://supabase.com/blog/supabase-realtime-multiplayer-general-availability
Announcing the general availability of Realtime's Broadcast and Presence.
- Wed, 17 Aug 2022 02:02:30 +0000
+ Wed, 17 Aug 2022 16:04:00 +0000
-
https://supabase.com/blog/supabase-soc2
Supabase is SOC2 compliant
https://supabase.com/blog/supabase-soc2
Supabase is now SOC2 compliant. Learn how we got here and what it means for our customers.
- Tue, 16 Aug 2022 02:02:30 +0000
+ Tue, 16 Aug 2022 16:04:00 +0000
-
https://supabase.com/blog/supabase-js-v2
supabase-js v2
https://supabase.com/blog/supabase-js-v2
A look at supabase-js v2, which brings type support and focuses on quality-of-life improvements for developers.
- Mon, 15 Aug 2022 02:02:30 +0000
+ Mon, 15 Aug 2022 16:04:00 +0000
-
https://supabase.com/blog/supabase-cli-v1-and-admin-api-beta
Supabase CLI v1 and Management API Beta
https://supabase.com/blog/supabase-cli-v1-and-admin-api-beta
We are moving Supabase CLI v1 out of beta, and releasing Management API beta.
- Sun, 14 Aug 2022 02:02:30 +0000
+ Sun, 14 Aug 2022 16:04:00 +0000
-
https://supabase.com/blog/supabase-series-b
Supabase Series B
https://supabase.com/blog/supabase-series-b
Supabase raised $80M in May, bringing our total funding to $116M.
- Thu, 11 Aug 2022 02:02:30 +0000
+ Thu, 11 Aug 2022 16:04:00 +0000
-
https://supabase.com/blog/launch-week-5-hackathon
Launch Week 5 Hackathon
https://supabase.com/blog/launch-week-5-hackathon
Build to win $1500 - Friday 12th to Monday 21st August 2022
- Tue, 09 Aug 2022 02:02:30 +0000
+ Tue, 09 Aug 2022 16:04:00 +0000
-
https://supabase.com/blog/slack-consolidate-slackbot-to-consolidate-messages
Slack Consolidate: a slackbot built with Python and Supabase
https://supabase.com/blog/slack-consolidate-slackbot-to-consolidate-messages
A slackbot to consolidate messages from different channels using Supabase, Slack SDK and Python
- Mon, 08 Aug 2022 02:02:30 +0000
+ Mon, 08 Aug 2022 16:04:00 +0000
-
https://supabase.com/blog/supabase-beta-update-july-2022
Supabase Beta July 2022
https://supabase.com/blog/supabase-beta-update-july-2022
Launch Week Golden Tickets, Flutter SDK 1.0 Developer Preview and more...
- Tue, 02 Aug 2022 02:02:30 +0000
+ Tue, 02 Aug 2022 16:04:00 +0000
-
https://supabase.com/blog/supabase-flutter-sdk-1-developer-preview
Supabase Flutter SDK 1.0 Developer Preview
https://supabase.com/blog/supabase-flutter-sdk-1-developer-preview
Supabase Flutter SDK is getting a major update and we need your help making it better.
- Mon, 01 Aug 2022 02:02:30 +0000
+ Mon, 01 Aug 2022 16:04:00 +0000
-
https://supabase.com/blog/seen-by-in-postgresql
Implementing "seen by" functionality with Postgres
https://supabase.com/blog/seen-by-in-postgresql
Different approaches for tracking visitor counts with PostgreSQL.
- Sun, 17 Jul 2022 02:02:30 +0000
+ Sun, 17 Jul 2022 16:04:00 +0000
-
https://supabase.com/blog/supabase-auth-helpers-with-sveltekit-support
Revamped Auth Helpers for Supabase (with SvelteKit support)
https://supabase.com/blog/supabase-auth-helpers-with-sveltekit-support
Supabase Auth Helpers now have improved developer experience, Sveltekit support, and more.
- Tue, 12 Jul 2022 02:02:30 +0000
+ Tue, 12 Jul 2022 16:04:00 +0000
-
https://supabase.com/blog/beta-update-june-2022
Supabase Beta June 2022
https://supabase.com/blog/beta-update-june-2022
Auth Helpers, Unlimited Free Projects, CLI and more...
- Tue, 05 Jul 2022 02:02:30 +0000
+ Tue, 05 Jul 2022 16:04:00 +0000
-
https://supabase.com/blog/flutter-tutorial-building-a-chat-app
@@ -229,700 +250,700 @@
Visualizing Supabase Data using Metabase
https://supabase.com/blog/visualizing-supabase-data-using-metabase
How to create different kinds of charts out of data stored in Supabase using Metabase.
- Tue, 28 Jun 2022 02:02:30 +0000
+ Tue, 28 Jun 2022 16:04:00 +0000
-
https://supabase.com/blog/partial-postgresql-data-dumps-with-rls
Partial data dumps using Postgres Row Level Security
https://supabase.com/blog/partial-postgresql-data-dumps-with-rls
Using RLS to create seed files for local PostgreSQL testing.
- Mon, 27 Jun 2022 02:02:30 +0000
+ Mon, 27 Jun 2022 16:04:00 +0000
-
https://supabase.com/blog/loading-data-supabase-python
Python data loading with Supabase
https://supabase.com/blog/loading-data-supabase-python
An example of how to load data into Supabase using supabase-py
- Thu, 16 Jun 2022 02:02:30 +0000
+ Thu, 16 Jun 2022 16:04:00 +0000
-
https://supabase.com/blog/beta-update-may-2022
Supabase Beta May 2022
https://supabase.com/blog/beta-update-may-2022
Product and community updates including wildcard auth redirects, edge functions with webhooks, and Prometheus endpoints for everybody.
- Tue, 31 May 2022 02:02:30 +0000
+ Tue, 31 May 2022 16:04:00 +0000
-
https://supabase.com/blog/how-supabase-accelerates-development-of-all-pull-together
How Mike Lyndon is using Supabase to accelerate development of AllPullTogether
https://supabase.com/blog/how-supabase-accelerates-development-of-all-pull-together
Mike Lyndon is learning web development as he builds AllPullTogether, and Supabase is helping him accelerate what he can accomplish.
- Wed, 25 May 2022 02:02:30 +0000
+ Wed, 25 May 2022 16:04:00 +0000
-
https://supabase.com/blog/partner-gallery-works-with-supabase
Works With Supabase - announcing our Partner Gallery
https://supabase.com/blog/partner-gallery-works-with-supabase
Introducing our Partner Gallery - open source and made with Supabase.
- Tue, 19 Apr 2022 02:02:30 +0000
+ Tue, 19 Apr 2022 16:04:00 +0000
-
https://supabase.com/blog/bring-the-func-hackathon-winners
Bring the Func Hackathon Winners 2022
https://supabase.com/blog/bring-the-func-hackathon-winners
Celebrating many amazing OSS Hackathon projects using GraphQL and Edge Functions.
- Sun, 17 Apr 2022 02:02:30 +0000
+ Sun, 17 Apr 2022 16:04:00 +0000
-
https://supabase.com/blog/beta-update-march-2022
Supabase Beta March 2022
https://supabase.com/blog/beta-update-march-2022
Functions, GraphQL, and much more.
- Thu, 14 Apr 2022 02:02:30 +0000
+ Thu, 14 Apr 2022 16:04:00 +0000
-
https://supabase.com/blog/supabrew
Supabrew - Never Code Thirsty
https://supabase.com/blog/supabrew
A light and refreshing non-alcoholic beer for devs.
- Fri, 01 Apr 2022 02:02:30 +0000
+ Thu, 31 Mar 2022 16:04:00 +0000
-
https://supabase.com/blog/supabase-realtime-with-multiplayer-features
Supabase Realtime, with Multiplayer Features
https://supabase.com/blog/supabase-realtime-with-multiplayer-features
Today we're announced Realtime, with multiplayer features. Realtime enables broadcast, presence, and listening to database changes delivered over WebSockets.
- Fri, 01 Apr 2022 02:02:30 +0000
+ Thu, 31 Mar 2022 16:04:00 +0000
-
https://supabase.com/blog/hackathon-bring-the-func
Hackathon: Bring the Func(πΊ)
https://supabase.com/blog/hackathon-bring-the-func
Build open-source projects with our latest features, win limited edition swag and plant a tree!
- Fri, 01 Apr 2022 02:02:30 +0000
+ Thu, 31 Mar 2022 16:04:00 +0000
-
https://supabase.com/blog/supabase-edge-functions
Edge Functions are now available in Supabase
https://supabase.com/blog/supabase-edge-functions
Today we're launching Edge Functions. Edge Functions let you execute Typescript code close to your users, no matter where they're located.
- Wed, 30 Mar 2022 02:02:30 +0000
+ Wed, 30 Mar 2022 16:04:00 +0000
-
https://supabase.com/blog/supabase-enterprise
Introducing Supabase Enterprise
https://supabase.com/blog/supabase-enterprise
Today we are releasing Supabase Enterprise, a suite of features to scale your project.
- Tue, 29 Mar 2022 02:02:30 +0000
+ Tue, 29 Mar 2022 16:04:00 +0000
-
https://supabase.com/blog/graphql-now-available
GraphQL is now available in Supabase
https://supabase.com/blog/graphql-now-available
GraphQL support is now in general availability on the Supabase platform via our open source PostgreSQL extension, pg_graphql (beta).
- Mon, 28 Mar 2022 02:02:30 +0000
+ Mon, 28 Mar 2022 16:04:00 +0000
-
https://supabase.com/blog/community-day-lw4
Community Day
https://supabase.com/blog/community-day-lw4
Kicking off Launch Week 4 with contributors, partners, and friends.
- Sun, 27 Mar 2022 02:02:30 +0000
+ Sun, 27 Mar 2022 16:04:00 +0000
-
https://supabase.com/blog/supabase-launch-week-four
Supabase Launch Week 4
https://supabase.com/blog/supabase-launch-week-four
Launch Week 4: One new feature every day for an entire week. Starting Monday 28th March.
- Thu, 24 Mar 2022 02:02:30 +0000
+ Thu, 24 Mar 2022 16:04:00 +0000
-
https://supabase.com/blog/should-i-open-source-my-company
Should I Open Source my Company?
https://supabase.com/blog/should-i-open-source-my-company
The unexpected upsides of building in public
- Thu, 24 Mar 2022 02:02:30 +0000
+ Thu, 24 Mar 2022 16:04:00 +0000
-
https://supabase.com/blog/audit
Postgres Auditing in 150 lines of SQL
https://supabase.com/blog/audit
PostgreSQL has a robust set of features which we can leverage to create a generic auditing solution in 150 lines of SQL.
- Mon, 07 Mar 2022 03:03:30 +0000
+ Mon, 07 Mar 2022 16:04:00 +0000
-
https://supabase.com/blog/supabase-beta-january-2022
Supabase Beta January 2022
https://supabase.com/blog/supabase-beta-january-2022
New auth providers, SMS providers, and new videos.
- Mon, 21 Feb 2022 03:03:30 +0000
+ Mon, 21 Feb 2022 16:04:00 +0000
-
https://supabase.com/blog/supabase-beta-december-2021
Supabase Beta December 2021
https://supabase.com/blog/supabase-beta-december-2021
New crypto extension, Postgres videos, and a bunch of cool integrations.
- Wed, 19 Jan 2022 03:03:30 +0000
+ Wed, 19 Jan 2022 16:04:00 +0000
-
https://supabase.com/blog/product-hunt-golden-kitty-awards-2021
Golden Kitty Awards Ceremony Watch Party with Supabase
https://supabase.com/blog/product-hunt-golden-kitty-awards-2021
Hang out with us while watching the Product Hunt Golden Kitty Awards Ceremony
- Wed, 19 Jan 2022 03:03:30 +0000
+ Wed, 19 Jan 2022 16:04:00 +0000
-
https://supabase.com/blog/holiday-hackdays-winners-2021
Holiday Hackdays Winners 2021
https://supabase.com/blog/holiday-hackdays-winners-2021
Celebrating many amazing projects submitted to our Holiday Hackdays Hackathon.
- Thu, 16 Dec 2021 03:03:30 +0000
+ Thu, 16 Dec 2021 16:04:00 +0000
-
https://supabase.com/blog/beta-november-2021-launch-week-recap
Supabase Beta November 2021: Launch Week Recap
https://supabase.com/blog/beta-november-2021-launch-week-recap
We wrapped up November with Supabase's third Launch Week. Here's all the awesome stuff that got shipped ...
- Tue, 14 Dec 2021 03:03:30 +0000
+ Tue, 14 Dec 2021 16:04:00 +0000
-
https://supabase.com/blog/supabase-holiday-hackdays-hackathon
Kicking off the Holiday Hackdays
https://supabase.com/blog/supabase-holiday-hackdays-hackathon
Build cool stuff and celebrate open-source software with us during the Holiday Hackdays!
- Thu, 02 Dec 2021 03:03:30 +0000
+ Thu, 02 Dec 2021 16:04:00 +0000
-
https://supabase.com/blog/pg-graphql
pg_graphql: A GraphQL extension for PostgreSQL
https://supabase.com/blog/pg-graphql
GraphQL support is in development for PostgreSQL + Supabase.
- Thu, 02 Dec 2021 03:03:30 +0000
+ Thu, 02 Dec 2021 16:04:00 +0000
-
https://supabase.com/blog/launch-week-three-friday-five-more-things
Five more things
https://supabase.com/blog/launch-week-three-friday-five-more-things
It's never just one more thing!
- Thu, 02 Dec 2021 03:03:30 +0000
+ Thu, 02 Dec 2021 16:04:00 +0000
-
https://supabase.com/blog/supabase-acquires-logflare
Supabase acquires Logflare
https://supabase.com/blog/supabase-acquires-logflare
Today, we're ecstatic to announce that Logflare is joining Supabase.
- Wed, 01 Dec 2021 03:03:30 +0000
+ Wed, 01 Dec 2021 16:04:00 +0000
-
https://supabase.com/blog/realtime-row-level-security-in-postgresql
Realtime Postgres RLS now available on Supabase
https://supabase.com/blog/realtime-row-level-security-in-postgresql
Realtime database changes are now broadcast to authenticated users, respecting the same PostgreSQL policies that you use for Row Level Security.
- Tue, 30 Nov 2021 03:03:30 +0000
+ Tue, 30 Nov 2021 16:04:00 +0000
-
https://supabase.com/blog/supabase-studio
Supabase Studio
https://supabase.com/blog/supabase-studio
The same Dashboard that you're using on our Platform is now available for local development and Self-Hosting.
- Mon, 29 Nov 2021 03:03:30 +0000
+ Mon, 29 Nov 2021 16:04:00 +0000
-
https://supabase.com/blog/community-day-lw3
Community Day
https://supabase.com/blog/community-day-lw3
Kicking off launch week by highlighting the communities around Supabase.
- Sun, 28 Nov 2021 03:03:30 +0000
+ Sun, 28 Nov 2021 16:04:00 +0000
-
https://supabase.com/blog/whats-new-in-postgres-14
New in PostgreSQL 14: What every developer should know
https://supabase.com/blog/whats-new-in-postgres-14
A quick look at some new features and functionality in PostgreSQL 14.
- Sat, 27 Nov 2021 03:03:30 +0000
+ Sat, 27 Nov 2021 16:04:00 +0000
-
https://supabase.com/blog/postgrest-9
PostgREST 9
https://supabase.com/blog/postgrest-9
New features and updates in PostgREST version 9.
- Fri, 26 Nov 2021 03:03:30 +0000
+ Fri, 26 Nov 2021 16:04:00 +0000
-
https://supabase.com/blog/supabase-launch-week-the-trilogy
Supabase Launch Week III: Holiday Special
https://supabase.com/blog/supabase-launch-week-the-trilogy
Tis the season to be shipping.
- Thu, 25 Nov 2021 03:03:30 +0000
+ Thu, 25 Nov 2021 16:04:00 +0000
-
https://supabase.com/blog/supabase-how-we-launch
How we launch at Supabase
https://supabase.com/blog/supabase-how-we-launch
The history and methodology of Supabase Launch Week.
- Thu, 25 Nov 2021 03:03:30 +0000
+ Thu, 25 Nov 2021 16:04:00 +0000
-
https://supabase.com/blog/supabase-beta-october-2021
Supabase Beta October 2021
https://supabase.com/blog/supabase-beta-october-2021
Three new Auth providers, multi-schema support, and we're gearing up for another Launch Week.
- Sat, 06 Nov 2021 02:02:30 +0000
+ Sat, 06 Nov 2021 16:04:00 +0000
-
https://supabase.com/blog/supabase-series-a
Supabase $30m Series A
https://supabase.com/blog/supabase-series-a
Supabase just raised $30M, bringing our total funding to $36M.
- Wed, 27 Oct 2021 02:02:30 +0000
+ Wed, 27 Oct 2021 16:04:00 +0000
-
https://supabase.com/blog/replenysh-time-to-value-in-less-than-24-hours
Replenysh uses Supabase to implement OTP in less than 24-hours
https://supabase.com/blog/replenysh-time-to-value-in-less-than-24-hours
Learn how Replenysh uses Supabase to power the circular economy, redefining how brands interact with their customers and products.
- Mon, 18 Oct 2021 02:02:30 +0000
+ Mon, 18 Oct 2021 16:04:00 +0000
-
https://supabase.com/blog/hacktoberfest-hackathon-winners-2021
Hacktoberfest Hackathon Winners 2021
https://supabase.com/blog/hacktoberfest-hackathon-winners-2021
Celebrating many amazing projects submitted to our Hacktoberfest Hackathon.
- Wed, 13 Oct 2021 02:02:30 +0000
+ Wed, 13 Oct 2021 16:04:00 +0000
-
https://supabase.com/blog/supabase-beta-sept-2021
Supabase Beta Sept 2021
https://supabase.com/blog/supabase-beta-sept-2021
Hackathon, Aborting request, UI updates, and now Hiring.
- Sun, 03 Oct 2021 02:02:30 +0000
+ Sun, 03 Oct 2021 16:04:00 +0000
-
https://supabase.com/blog/supabase-hacktoberfest-hackathon-2021
Supabase Hacktoberfest Hackathon 2021
https://supabase.com/blog/supabase-hacktoberfest-hackathon-2021
We're running another Supabase Hackathon during Hacktoberfest!
- Mon, 27 Sep 2021 02:02:30 +0000
+ Mon, 27 Sep 2021 16:04:00 +0000
-
https://supabase.com/blog/supabase-beta-august-2021
Supabase Beta August 2021
https://supabase.com/blog/supabase-beta-august-2021
Fundraising, Realtime Security, custom SMS templates, and deployments in South Korea.
- Thu, 09 Sep 2021 02:02:30 +0000
+ Thu, 09 Sep 2021 16:04:00 +0000
-
https://supabase.com/blog/supabase-beta-july-2021
Supabase Beta July 2021
https://supabase.com/blog/supabase-beta-july-2021
Discord Logins, Vercel Integration, Full text search, and OAuth guides.
- Wed, 11 Aug 2021 02:02:30 +0000
+ Wed, 11 Aug 2021 16:04:00 +0000
-
https://supabase.com/blog/hackathon-winners
Open Source Hackathon Winners
https://supabase.com/blog/hackathon-winners
Let the medal ceremony begin for the best projects submitted during the Supabase Hackathon.
- Sun, 08 Aug 2021 02:02:30 +0000
+ Sun, 08 Aug 2021 16:04:00 +0000
-
https://supabase.com/blog/supabase-swag-store
Supabase Swag Store
https://supabase.com/blog/supabase-swag-store
Today we are officially launching the Supabase Swag Store.
- Thu, 29 Jul 2021 02:02:30 +0000
+ Thu, 29 Jul 2021 16:04:00 +0000
-
https://supabase.com/blog/supabase-functions-updates
Updates for Supabase Functions
https://supabase.com/blog/supabase-functions-updates
The question on everyone's mind - are we launching Supabase Functions? Well, it's complicated.
- Thu, 29 Jul 2021 02:02:30 +0000
+ Thu, 29 Jul 2021 16:04:00 +0000
-
https://supabase.com/blog/1-the-supabase-hackathon
The Supabase Hackathon
https://supabase.com/blog/1-the-supabase-hackathon
A whole week of Hacking for Fun and Prizes.
- Thu, 29 Jul 2021 02:02:30 +0000
+ Thu, 29 Jul 2021 16:04:00 +0000
-
https://supabase.com/blog/supabase-reports-and-metrics
Supabase Reports and Metrics
https://supabase.com/blog/supabase-reports-and-metrics
We're exposing a full set of metrics in your projects, so that you can build better (and faster) products for your users.
- Wed, 28 Jul 2021 02:02:30 +0000
+ Wed, 28 Jul 2021 16:04:00 +0000
-
https://supabase.com/blog/supabase-auth-passwordless-sms-login
Supabase Auth v2: Phone Auth now available
https://supabase.com/blog/supabase-auth-passwordless-sms-login
Phone Auth is available today on all new and existing Supabase projects.
- Tue, 27 Jul 2021 02:02:30 +0000
+ Tue, 27 Jul 2021 16:04:00 +0000
-
https://supabase.com/blog/mobbin-supabase-200000-users
Mobbin uses Supabase to authenticate 200,000 users
https://supabase.com/blog/mobbin-supabase-200000-users
Learn how Mobbin migrated 200,000 users from Firebase for a better authentication experience.
- Tue, 27 Jul 2021 02:02:30 +0000
+ Tue, 27 Jul 2021 16:04:00 +0000
-
https://supabase.com/blog/storage-beta
Supabase Storage now in Beta
https://supabase.com/blog/storage-beta
Supabase Storage moves into Beta.
- Mon, 26 Jul 2021 02:02:30 +0000
+ Mon, 26 Jul 2021 16:04:00 +0000
-
https://supabase.com/blog/spot-flutter-with-postgres
Spot: a video sharing app built with Flutter
https://supabase.com/blog/spot-flutter-with-postgres
Spot is a geolocation-based video-sharing app with some social networking features.
- Mon, 26 Jul 2021 02:02:30 +0000
+ Mon, 26 Jul 2021 16:04:00 +0000
-
https://supabase.com/blog/supabase-postgres-13
Supabase is now on Postgres 13.3
https://supabase.com/blog/supabase-postgres-13
From today, new Supabase projects will be on a version of Supabase Postgres that runs on Postgres 13.3.
- Sun, 25 Jul 2021 02:02:30 +0000
+ Sun, 25 Jul 2021 16:04:00 +0000
-
https://supabase.com/blog/supabase-community-day
Supabase Community Day
https://supabase.com/blog/supabase-community-day
Community Day
- Sun, 25 Jul 2021 02:02:30 +0000
+ Sun, 25 Jul 2021 16:04:00 +0000
-
https://supabase.com/blog/epsilon3-self-hosting
Epsilon3 Self-Host Supabase To Revolutionize Space Operations
https://supabase.com/blog/epsilon3-self-hosting
Learn how the team at Epsilon3 use Supabase to help teams execute secure and reliable operations in an industry that project spend runs into the billions.
- Sun, 25 Jul 2021 02:02:30 +0000
+ Sun, 25 Jul 2021 16:04:00 +0000
-
https://supabase.com/blog/supabase-launch-week-sql
Supabase Launch Week II: The SQL
https://supabase.com/blog/supabase-launch-week-sql
Five days of Supabase. Again.
- Wed, 21 Jul 2021 02:02:30 +0000
+ Wed, 21 Jul 2021 16:04:00 +0000
-
https://supabase.com/blog/roles-postgres-hooks
Protecting reserved roles with PostgreSQL Hooks
https://supabase.com/blog/roles-postgres-hooks
Using Postgres Hooks to protect functionality in your Postgres database.
- Thu, 01 Jul 2021 02:02:30 +0000
+ Thu, 01 Jul 2021 16:04:00 +0000
-
https://supabase.com/blog/supabase-beta-june-2021
Supabase Beta June 2021
https://supabase.com/blog/supabase-beta-june-2021
Discord Logins, Vercel Integration, Full text search, and OAuth guides.
- Tue, 01 Jun 2021 02:02:30 +0000
+ Tue, 01 Jun 2021 16:04:00 +0000
-
https://supabase.com/blog/supabase-beta-may-2021
Supabase Beta May 2021
https://supabase.com/blog/supabase-beta-may-2021
Apple & Twitter Logins, Supabase Grid, Go & Swift Libraries.
- Tue, 01 Jun 2021 02:02:30 +0000
+ Tue, 01 Jun 2021 16:04:00 +0000
-
https://supabase.com/blog/supabase-beta-april-2021
Supabase Beta April 2021
https://supabase.com/blog/supabase-beta-april-2021
Supabase "gardening" - stability, security, and community support.
- Tue, 04 May 2021 02:02:30 +0000
+ Tue, 04 May 2021 16:04:00 +0000
-
https://supabase.com/blog/supabase-beta-march-2021
Supabase Beta March 2021
https://supabase.com/blog/supabase-beta-march-2021
Launch week, Storage, Supabase CLI, Connection Pooling, Supabase UI, and Pricing.
- Mon, 05 Apr 2021 02:02:30 +0000
+ Mon, 05 Apr 2021 16:04:00 +0000
-
https://supabase.com/blog/supabase-workflows
Workflows are coming to Supabase
https://supabase.com/blog/supabase-workflows
Functions are great, but you know what's better?
- Thu, 01 Apr 2021 02:02:30 +0000
+ Thu, 01 Apr 2021 16:04:00 +0000
-
https://supabase.com/blog/supabase-pgbouncer
PgBouncer is now available in Supabase
https://supabase.com/blog/supabase-pgbouncer
Better support for Serverless and Postgres.
- Thu, 01 Apr 2021 02:02:30 +0000
+ Thu, 01 Apr 2021 16:04:00 +0000
-
https://supabase.com/blog/supabase-dot-com
Supabase Dot Com
https://supabase.com/blog/supabase-dot-com
The Supabase Domain name is changing.
- Thu, 01 Apr 2021 02:02:30 +0000
+ Thu, 01 Apr 2021 16:04:00 +0000
-
https://supabase.com/blog/supabase-nft-marketplace
Supabase Launches NFT Marketplace
https://supabase.com/blog/supabase-nft-marketplace
A fully encrypted NFT platform to protect and transact your digital assets
- Thu, 01 Apr 2021 02:02:30 +0000
+ Wed, 31 Mar 2021 16:04:00 +0000
-
https://supabase.com/blog/supabase-cli
Supabase CLI
https://supabase.com/blog/supabase-cli
Local development, database migrations, and self-hosting.
- Wed, 31 Mar 2021 02:02:30 +0000
+ Tue, 30 Mar 2021 16:04:00 +0000
-
https://supabase.com/blog/supabase-storage
Storage is now available in Supabase
https://supabase.com/blog/supabase-storage
Launching Supabase Storage and how you can use it in your apps
- Tue, 30 Mar 2021 02:02:30 +0000
+ Mon, 29 Mar 2021 16:04:00 +0000
-
https://supabase.com/blog/pricing
Supabase Beta Pricing
https://supabase.com/blog/pricing
Supabase launches Beta pricing structure
- Mon, 29 Mar 2021 02:02:30 +0000
+ Sun, 28 Mar 2021 16:04:00 +0000
-
https://supabase.com/blog/launch-week
Launch week
https://supabase.com/blog/launch-week
Five days of Supabase.
- Wed, 24 Mar 2021 02:02:30 +0000
+ Wed, 24 Mar 2021 16:04:00 +0000
-
https://supabase.com/blog/angels-of-supabase
Angels of Supabase
https://supabase.com/blog/angels-of-supabase
Meet the investors of Supabase.
- Wed, 24 Mar 2021 02:02:30 +0000
+ Wed, 24 Mar 2021 16:04:00 +0000
-
https://supabase.com/blog/In-The-Loop
Developers stay up to date with intheloop.dev
https://supabase.com/blog/In-The-Loop
Learn why Kevin is building intheloop.dev with Supabase
- Mon, 22 Mar 2021 02:02:30 +0000
+ Sun, 21 Mar 2021 16:04:00 +0000
-
https://supabase.com/blog/using-supabase-replit
Using Supabase in Replit
https://supabase.com/blog/using-supabase-replit
Free hosted relational database from within your node.js repl
- Thu, 11 Mar 2021 03:03:30 +0000
+ Wed, 10 Mar 2021 16:04:00 +0000
-
https://supabase.com/blog/toad-a-link-shortener-with-simple-apis-for-low-coders
Toad, a link shortener with simple APIs for low-coders
https://supabase.com/blog/toad-a-link-shortener-with-simple-apis-for-low-coders
An easy-to-use link shortening tool with simple APIs
- Mon, 08 Mar 2021 03:03:30 +0000
+ Sun, 07 Mar 2021 16:04:00 +0000
-
https://supabase.com/blog/postgres-as-a-cron-server
Postgres as a CRON Server
https://supabase.com/blog/postgres-as-a-cron-server
Running repetitive tasks with your Postgres database.
- Fri, 05 Mar 2021 03:03:30 +0000
+ Thu, 04 Mar 2021 16:04:00 +0000
-
https://supabase.com/blog/supabase-beta-february-2021
Supabase Beta February 2021
https://supabase.com/blog/supabase-beta-february-2021
One year of building.
- Tue, 02 Mar 2021 03:03:30 +0000
+ Mon, 01 Mar 2021 16:04:00 +0000
-
https://supabase.com/blog/cracking-postgres-interview
Cracking PostgreSQL Interview Questions
https://supabase.com/blog/cracking-postgres-interview
Understand the top PostgreSQL Interview Questions
- Sat, 27 Feb 2021 03:03:30 +0000
+ Fri, 26 Feb 2021 16:04:00 +0000
-
https://supabase.com/blog/case-study-roboflow
Roboflow.com choose Supabase to power Paint.wtf leaderboard
https://supabase.com/blog/case-study-roboflow
Learn how Roboflow.com used Supabase to build their Paint.wtf leaderboard
- Tue, 09 Feb 2021 03:03:30 +0000
+ Mon, 08 Feb 2021 16:04:00 +0000
-
https://supabase.com/blog/supabase-beta-january-2021
Supabase Beta January 2021
https://supabase.com/blog/supabase-beta-january-2021
Eleven months of building.
- Tue, 02 Feb 2021 03:03:30 +0000
+ Mon, 01 Feb 2021 16:04:00 +0000
-
https://supabase.com/blog/supabase-beta-december-2020
Supabase Beta December 2020
https://supabase.com/blog/supabase-beta-december-2020
Ten months of building.
- Sat, 02 Jan 2021 03:03:30 +0000
+ Fri, 01 Jan 2021 16:04:00 +0000
-
https://supabase.com/blog/supabase-dashboard-performance
Making the Supabase Dashboard Supa-fast
https://supabase.com/blog/supabase-dashboard-performance
Improving the performance of the Supabase dashboard
- Sun, 13 Dec 2020 03:03:30 +0000
+ Sat, 12 Dec 2020 16:04:00 +0000
-
https://supabase.com/blog/supabase-striveschool
Supabase Partners With Strive School To Help Teach Open Source
https://supabase.com/blog/supabase-striveschool
Supabase Partners With Strive School To Help Teach Open Source To The Next Generation Of Developers
- Wed, 02 Dec 2020 03:03:30 +0000
+ Tue, 01 Dec 2020 16:04:00 +0000
-
https://supabase.com/blog/case-study-xendit
Xendit Built a Counter-Fraud Watchlist for the Fintech Industry
https://supabase.com/blog/case-study-xendit
See how Xendit use Supabase to build a full-text search engine.
- Wed, 02 Dec 2020 03:03:30 +0000
+ Tue, 01 Dec 2020 16:04:00 +0000
-
https://supabase.com/blog/case-study-tayfa
TAYFA Built a No-Code Website Builder in Seven Days
https://supabase.com/blog/case-study-tayfa
See how Tayfa went from idea to paying customer in less than 30 days.
- Wed, 02 Dec 2020 03:03:30 +0000
+ Tue, 01 Dec 2020 16:04:00 +0000
-
https://supabase.com/blog/case-study-monitoro
Monitoro Built a Web Crawler Handling Millions of API Requests
https://supabase.com/blog/case-study-monitoro
See how Monitoro built an automated scraping platform using Supabase.
- Wed, 02 Dec 2020 03:03:30 +0000
+ Tue, 01 Dec 2020 16:04:00 +0000
-
https://supabase.com/blog/supabase-alpha-november-2020
Supabase Alpha November 2020
https://supabase.com/blog/supabase-alpha-november-2020
Nine months of building.
- Tue, 01 Dec 2020 03:03:30 +0000
+ Mon, 30 Nov 2020 16:04:00 +0000
-
https://supabase.com/blog/postgresql-views
Postgres Views
https://supabase.com/blog/postgresql-views
Creating and using a view in PostgreSQL.
- Wed, 18 Nov 2020 03:03:30 +0000
+ Tue, 17 Nov 2020 16:04:00 +0000
-
https://supabase.com/blog/supabase-alpha-october-2020
Supabase Alpha October 2020
https://supabase.com/blog/supabase-alpha-october-2020
Eight months of building.
- Mon, 02 Nov 2020 03:03:30 +0000
+ Sun, 01 Nov 2020 16:04:00 +0000
-
https://supabase.com/blog/improved-dx
Supabase.js 1.0
https://supabase.com/blog/improved-dx
We're releasing a new version of our Supabase client with some awesome new improvements.
- Fri, 30 Oct 2020 02:02:30 +0000
+ Thu, 29 Oct 2020 16:04:00 +0000
-
https://supabase.com/blog/supabase-alpha-september-2020
Supabase Alpha September 2020
https://supabase.com/blog/supabase-alpha-september-2020
Seven months of building.
- Sat, 03 Oct 2020 02:02:30 +0000
+ Fri, 02 Oct 2020 16:04:00 +0000
-
https://supabase.com/blog/supabase-hacktoberfest-2020
Supabase Hacktoberfest 2020
https://supabase.com/blog/supabase-hacktoberfest-2020
Join us for a celebration of open source software and learn how to contribute to Supabase.
- Fri, 11 Sep 2020 02:02:30 +0000
+ Thu, 10 Sep 2020 16:04:00 +0000
-
https://supabase.com/blog/supabase-alpha-august-2020
Supabase Alpha August 2020
https://supabase.com/blog/supabase-alpha-august-2020
Six months of building
- Thu, 03 Sep 2020 02:02:30 +0000
+ Wed, 02 Sep 2020 16:04:00 +0000
-
https://supabase.com/blog/supabase-auth
Supabase Auth
https://supabase.com/blog/supabase-auth
Authenticate and authorize your users with Supabase Auth
- Wed, 05 Aug 2020 02:02:30 +0000
+ Tue, 04 Aug 2020 16:04:00 +0000
-
https://supabase.com/blog/supabase-alpha-july-2020
Supabase Alpha July 2020
https://supabase.com/blog/supabase-alpha-july-2020
Five months of building
- Sun, 02 Aug 2020 02:02:30 +0000
+ Sat, 01 Aug 2020 16:04:00 +0000
-
https://supabase.com/blog/continuous-postgresql-backup-walg
Continuous PostgreSQL Backups using WAL-G
https://supabase.com/blog/continuous-postgresql-backup-walg
Have you ever wanted to restore your database's state to a particular moment in time? This post explains how, using WAL-G.
- Sun, 02 Aug 2020 02:02:30 +0000
+ Sat, 01 Aug 2020 16:04:00 +0000
-
https://supabase.com/blog/alpha-launch-postmortem
Alpha Launch Postmortem
https://supabase.com/blog/alpha-launch-postmortem
Everything that went wrong with Supabase's launch
- Fri, 10 Jul 2020 02:02:30 +0000
+ Thu, 09 Jul 2020 16:04:00 +0000
-
https://supabase.com/blog/postgresql-templates
What are PostgreSQL Templates?
https://supabase.com/blog/postgresql-templates
What are PostgreSQL templates and what are they used for?
- Thu, 09 Jul 2020 02:02:30 +0000
+ Wed, 08 Jul 2020 16:04:00 +0000
-
https://supabase.com/blog/postgresql-physical-logical-backups
Physical vs Logical Backups in PostgreSQL
https://supabase.com/blog/postgresql-physical-logical-backups
What are physical and logical backups in Postgres?
- Tue, 07 Jul 2020 02:02:30 +0000
+ Mon, 06 Jul 2020 16:04:00 +0000
-
https://supabase.com/blog/supabase-alpha-june-2020
Supabase Alpha June 2020
https://supabase.com/blog/supabase-alpha-june-2020
Four months of building
- Wed, 01 Jul 2020 02:02:30 +0000
+ Tue, 30 Jun 2020 16:04:00 +0000
-
https://supabase.com/blog/supabase-steve-chavez
Steve Chavez has joined Supabase
https://supabase.com/blog/supabase-steve-chavez
Steve joins Supabase to help build Auth.
- Mon, 15 Jun 2020 02:02:30 +0000
+ Sun, 14 Jun 2020 16:04:00 +0000
-
https://supabase.com/blog/supabase-alpha-may-2020
Supabase Alpha May 2020
https://supabase.com/blog/supabase-alpha-may-2020
Three months of building
- Mon, 01 Jun 2020 02:02:30 +0000
+ Sun, 31 May 2020 16:04:00 +0000
-
https://supabase.com/blog/supabase-alpha-april-2020
Supabase Alpha April 2020
https://supabase.com/blog/supabase-alpha-april-2020
Two months of building
- Mon, 01 Jun 2020 02:02:30 +0000
+ Sun, 31 May 2020 16:04:00 +0000
diff --git a/apps/www/public/sitemap_www.xml b/apps/www/public/sitemap_www.xml
index 3d294d2668b..b94e96a79ce 100644
--- a/apps/www/public/sitemap_www.xml
+++ b/apps/www/public/sitemap_www.xml
@@ -48,12 +48,6 @@
0.5
-
- https://supabase.com/auth
- weekly
- 0.5
-
-
https://supabase.com/blog/
weekly
@@ -61,7 +55,7 @@
- https://supabase.com/database
+ https://supabase.com/auth
weekly
0.5
@@ -78,12 +72,24 @@
0.5
+
+ https://supabase.com/database
+ weekly
+ 0.5
+
+
https://supabase.com/edge-functions
weekly
0.5
+
+ https://supabase.com/launch-week/ticket-image
+ weekly
+ 0.5
+
+
https://supabase.com/legal/dpa
weekly
@@ -902,6 +908,24 @@
0.5
+
+ https://supabase.com/blog/flutter-authentication-and-authorization-with-rls
+ weekly
+ 0.5
+
+
+
+ https://supabase.com/blog/sql-or-nosql-both-with-postgresql
+ weekly
+ 0.5
+
+
+
+ https://supabase.com/blog/transparent-column-encryption-with-postgres
+ weekly
+ 0.5
+
+
https://supabase.com/alternatives/supabase-vs-firebase
weekly
diff --git a/apps/www/styles/index.css b/apps/www/styles/index.css
index b86beb234ef..3728791dcd8 100644
--- a/apps/www/styles/index.css
+++ b/apps/www/styles/index.css
@@ -281,7 +281,7 @@ launch week
}
.launch-week-gradientBg--announcement-bar {
- background-image: url('/images/launchweek/supabase-launch-week-5-bg.jpg');
+ background: radial-gradient(circle, rgba(51, 68, 60, 1) 0%, rgba(0, 0, 0, 1) 100%);
background-color: hsl(0, 0%, 11%);
width: 100%;
clear: both;
@@ -291,11 +291,6 @@ launch week
background-repeat: no-repeat;
}
-.dark .launch-week-gradientBg--announcement-bar {
- background-image: url('/images/launchweek/supabase-launch-week-5-bg.jpg');
- background-color: #1c1c1c;
-}
-
@media screen and (min-width: 1032px) {
.launch-week-gradientBg--announcement-bar {
background-position-y: -780px;
@@ -373,6 +368,7 @@ launch week
:root {
--auth-ui-card-height: 50vh;
+ --lw-secondary-color: #8a8f98;
}
.glow-area {
@@ -428,3 +424,238 @@ launch week
white-space: pre !important;
}
}
+
+.gradient-container {
+ min-height: 480px;
+ position: relative;
+ max-width: 1600px;
+ margin: 0 auto;
+ left: 0;
+ right: 0;
+ overflow: hidden;
+ /* background: radial-gradient(
+ circle at 50% -150%,
+ #39617d 0%,
+ #00ded1 30%,
+ #121212 80%,
+ #121212 100%
+ ); */
+}
+@media screen and (max-width: 769px) {
+ .gradient-container {
+ left: 50%;
+ transform: translateX(-50%);
+ }
+}
+
+.gradient-mask {
+ z-index: -10;
+ position: absolute;
+ min-height: 100%;
+ width: 75%;
+ margin: 0 auto;
+ left: 0;
+ right: 0;
+ background: radial-gradient(
+ circle at 50% -35%,
+ rgba(57, 97, 125, 0.32) 0%,
+ rgba(57, 97, 125, 0.32) 5%,
+ rgba(0, 222, 209, 0.75) 8%,
+ #121212 65%,
+ #121212 100%
+ );
+}
+
+.light .gradient-mask {
+ background: radial-gradient(
+ circle at 50% -35%,
+ rgba(57, 97, 125, 0.32) 0%,
+ rgba(57, 97, 125, 0.32) 5%,
+ rgb(113 191 187 / 75%) 8%,
+ #ffffff 65%,
+ #ffffff 100%
+ );
+}
+
+@media screen and (max-width: 769px) {
+ .gradient-mask {
+ width: 100%;
+ }
+
+ .light .gradient-mask {
+ background: radial-gradient(
+ circle at 50% -35%,
+ rgba(57, 97, 125, 0.32) 0%,
+ rgba(57, 97, 125, 0.32) 5%,
+ rgb(155 246 241 / 75%) 8%,
+ #90cebd 65%,
+ #67eae8 100%
+ );
+ }
+}
+
+/* The bottom part below the stroke */
+.gradient-mask--masked {
+ z-index: -10;
+ position: absolute;
+ min-height: 100%;
+ width: 100%;
+ margin: 0 auto;
+ left: 0;
+ right: 0;
+ background: radial-gradient(circle at 50% -60%, rgba(255, 255, 255, 0) 0%, #121212 65%);
+}
+
+.light .gradient-mask--masked {
+ background: radial-gradient(circle at 50% -60%, rgba(255, 255, 255, 0) 0%, #fff 65%);
+}
+
+@media screen and (max-width: 769px) {
+ .gradient-mask--masked {
+ background: radial-gradient(circle at 50% -40%, rgba(255, 255, 255, 0) 0%, #121212 65%);
+ }
+
+ .light .gradient-mask--masked {
+ background: radial-gradient(circle at 50% -40%, rgba(255, 255, 255, 0) 0%, #fff 65%);
+ }
+}
+
+/* The stroke on the circle */
+.flair-mask-a {
+ position: absolute;
+ background-color: #375965;
+ top: 1px;
+ width: 180%;
+ left: -40%;
+ height: 500px;
+ -webkit-clip-path: ellipse(52% 135px at 50% 3px);
+ clip-path: ellipse(52% 213px at 50% -75px);
+}
+
+.light .flair-mask-a {
+ background-color: #d7d7d7;
+}
+
+/* The inside of the circle */
+.flair-mask-b {
+ position: absolute;
+ background-color: #121212;
+ top: 0px;
+ width: 182%;
+ left: -41%;
+
+ height: 500px;
+ -webkit-clip-path: ellipse(52% 135px at 50% 3px);
+ clip-path: ellipse(52% 213px at 50% -75px);
+}
+
+.light .flair-mask-b {
+ background-color: #fff;
+}
+
+@media only screen and (min-width: 600px) {
+ .flair-mask-a {
+ top: 1px;
+ margin: 0 auto;
+ width: 140%;
+ left: -20%;
+ right: 0;
+ }
+ .flair-mask-b {
+ top: 0px;
+ margin: 0 auto;
+ width: 142%;
+ left: -21%;
+ right: 0;
+ }
+}
+
+@media only screen and (min-width: 960px) {
+ .flair-mask-a {
+ top: 1px;
+ margin: 0 auto;
+ width: 120%;
+ left: -10%;
+ right: 0;
+ }
+ .flair-mask-b {
+ top: 0px;
+ margin: 0 auto;
+ width: 121%;
+ left: -10.5%;
+ right: 0;
+ }
+}
+
+/* @media only screen and (min-width: 1024px) {
+ .flair-mask-a {
+ width: 69.5%;
+ }
+ .flair-mask-b {
+ width: 70%;
+ }
+} */
+
+.orbit {
+ width: 192px;
+ height: 192px;
+ border-radius: 50%;
+ background: var(--colors-scale2) content-box;
+ border: 1px solid gray;
+ box-shadow: 0 0 0 50px var(--colors-scale2), 0 0 0 51px gray, 0 0 0 100px var(--colors-scale2),
+ 0 0 0 101px gray, 0 0 0 150px var(--colors-scale2), 0 0 0 151px gray;
+ margin: auto;
+ position: relative;
+}
+
+.orbit span {
+ position: absolute;
+ height: 45px;
+ width: 45px;
+ background: blue;
+ border-radius: inherit;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%) rotate(var(--r, 0deg)) translateX(var(--d, 0px));
+}
+
+.planet1 {
+ --d: 96px;
+ --r: -90deg;
+}
+
+.planet2 {
+ --d: 146px;
+ --r: -137deg;
+}
+
+.planet3 {
+ --d: 196px;
+ --r: -45deg;
+}
+
+.planet4 {
+ --d: 246px;
+ --r: -110deg;
+}
+
+.radial-mask {
+ /* -webkit-mask-image: conic-gradient(
+ from 0deg at 45% 47%,
+ #ffffffff 0%,
+ #000000ff 25%,
+ #000000ff 50%,
+ #000000ff 75%,
+ #ffffffff 100%
+ );
+ mask-image: conic-gradient(
+ from 0deg at 45% 47%,
+ #ffffffff 0%,
+ #000000ff 25%,
+ #000000ff 50%,
+ #000000ff 75%,
+ #ffffffff 100%
+ ); */
+
+ -webkit-mask-image: linear-gradient(rgba(0, 0, 0, 1), transparent);
+}
diff --git a/examples/edge-functions/supabase/functions/oak-server/README.md b/examples/edge-functions/supabase/functions/oak-server/README.md
new file mode 100644
index 00000000000..b1db6166231
--- /dev/null
+++ b/examples/edge-functions/supabase/functions/oak-server/README.md
@@ -0,0 +1,24 @@
+# Writing functions using Oak Server Middleware
+
+This example shows how you can write functions using Oak server middleware (https://oakserver.github.io/oak/)
+
+## Run locally
+
+```bash
+supabase functions serve oak-server
+```
+
+Use cURL or Postman to make a POST request to http://localhost:54321/functions/v1/oak-server.
+
+```
+ curl --location --request POST 'http://localhost:54321/functions/v1/oak-server' \
+--header 'Authorization: Bearer YOUR_TOKEN' \
+--header 'Content-Type: application/json' \
+--data-raw '{ "name": "John Doe" }'
+```
+
+## Deploy
+
+```bash
+supabase functions deploy oak-server
+```
diff --git a/examples/edge-functions/supabase/functions/oak-server/index.ts b/examples/edge-functions/supabase/functions/oak-server/index.ts
new file mode 100644
index 00000000000..8e96d1f0033
--- /dev/null
+++ b/examples/edge-functions/supabase/functions/oak-server/index.ts
@@ -0,0 +1,25 @@
+import { Application, Router } from 'https://deno.land/x/oak/mod.ts'
+
+const router = new Router()
+router
+ // Note: path will be prefixed with function name
+ .get('/oak-server', (context) => {
+ context.response.body = 'This is an example Oak server running on Edge Functions!'
+ })
+ .post('/oak-server/greet', (context) => {
+ // Note: request body will be streamed to the function as chunks, set limit to 0 to fully read it.
+ const result = context.request.body({ type: 'json', limit: 0 })
+ const body = await result.value
+ const name = body.name || 'you'
+
+ context.response.body = { msg: `Hey ${name}!` }
+ })
+ .get('/oak-server/redirect', (context) => {
+ context.response.redirect('https://www.example.com')
+ })
+
+const app = new Application()
+app.use(router.routes())
+app.use(router.allowedMethods())
+
+await app.listen({ port: 8000 })
diff --git a/examples/edge-functions/supabase/functions/og-image-with-storage-cdn/handler.tsx b/examples/edge-functions/supabase/functions/og-image-with-storage-cdn/handler.tsx
index 6a47dc69170..80ef24e2ccd 100644
--- a/examples/edge-functions/supabase/functions/og-image-with-storage-cdn/handler.tsx
+++ b/examples/edge-functions/supabase/functions/og-image-with-storage-cdn/handler.tsx
@@ -4,12 +4,13 @@ import { createClient } from 'https://esm.sh/@supabase/supabase-js@2'
import { corsHeaders } from '../_shared/cors.ts'
const STORAGE_URL = 'https://obuldanrptloktxcffvn.supabase.co/storage/v1/object/public/images/lw6'
-const BACKGROUND_IMAGE_STD = `${STORAGE_URL}/lw6_ticket_regular.jpg`
-const BACKGROUND_IMAGE_GOLDEN = `${STORAGE_URL}/lw6_ticket_gold.jpg`
+const BACKGROUND_IMAGE_STD = `${STORAGE_URL}/lw6_ticket_regular.png`
+const BACKGROUND_IMAGE_GOLDEN = `${STORAGE_URL}/lw6_ticket_gold.png`
const SUPA_CHECKMARK = `${STORAGE_URL}/supaverified.png`
+const SUPA_CHECKMARK_GOLD = `${STORAGE_URL}/supaverified_gold.png?v=3`
// Load custom font
-const FONT_URL = `${STORAGE_URL}/CircularStd-Bold.otf`
+const FONT_URL = `${STORAGE_URL}/CircularStd-Book.otf`
const font = fetch(new URL(FONT_URL, import.meta.url)).then((res) => res.arrayBuffer())
export async function handler(req: Request) {
@@ -27,7 +28,7 @@ export async function handler(req: Request) {
try {
// Try to get image from Supabase Storage CDN.
- const storageResponse = await fetch(`${STORAGE_URL}/tickets/${username}.png?version=dev`) // TODO change for prod.
+ const storageResponse = await fetch(`${STORAGE_URL}/tickets/${username}.png?v=3`)
if (storageResponse.ok) return storageResponse
// Else, generate image ad upload to storage.
@@ -37,133 +38,149 @@ export async function handler(req: Request) {
const generatedImage = new ImageResponse(
(
-
- {/* Background image */}
-
- {/* GitHub Avatar image */}
-
- {/* Name & username */}
+ <>
-
- {name}
-
- {/* Username and supaverified checkmark */}
+ src={golden ? BACKGROUND_IMAGE_GOLDEN : BACKGROUND_IMAGE_STD}
+ />
+ {/* GitHub Avatar image */}
+
+ {/* Name & username */}
-
{`@${username}`}
-
-
-
+
+ {name}
+
+
+ {/* Username and supaverified checkmark */}
+
+
{`@${username}`}
+
+
+
+
+ {/* Date */}
+
+ December 12th 2022
+
+ {/* URL */}
+
+ supabase.com/launch-week
+
- {/* Date */}
-
- December 12th, 2022
-
- {/* URL */}
-
- supabase.com/launch-week
-
{/* Ticket No */}
- {`β ${prefix}${ticketNumber}`}
+ {`No ${prefix}${ticketNumber}`}
-
+ >
),
{
- width: 2000,
- height: 1000,
+ width: 1200,
+ height: 630,
fonts: [
{
name: 'Circular',
@@ -190,7 +207,8 @@ export async function handler(req: Request) {
const { error } = await supabaseAdminClient.storage
.from('images')
.upload(`lw6/tickets/${username}.png`, generatedImage.body!, {
- // cacheControl: '31536000', // TODO add for prod
+ contentType: 'image/png',
+ cacheControl: '31536000',
upsert: false,
})
if (error) throw error
diff --git a/examples/edge-functions/supabase/functions/puppeteer/README.md b/examples/edge-functions/supabase/functions/puppeteer/README.md
new file mode 100644
index 00000000000..353df27fd05
--- /dev/null
+++ b/examples/edge-functions/supabase/functions/puppeteer/README.md
@@ -0,0 +1,11 @@
+# Using Puppeteer
+
+This example shows how you can use Puppeteer and a headless-browser to generate screenshots of a web page. Pass the `url` of the web page as a query string.
+
+Since Edge Functions cannot run a Headless Browser instance due to resource constraints, you will need to use a hosted browser service like https://browserless.io.
+
+## Deploy
+
+```bash
+supabase functions deploy puppeteer --no-verify-jwt
+```
diff --git a/examples/edge-functions/supabase/functions/puppeteer/index.ts b/examples/edge-functions/supabase/functions/puppeteer/index.ts
new file mode 100644
index 00000000000..7eac140f29f
--- /dev/null
+++ b/examples/edge-functions/supabase/functions/puppeteer/index.ts
@@ -0,0 +1,25 @@
+import { serve } from 'https://deno.land/std@0.131.0/http/server.ts'
+import puppeteer from 'https://deno.land/x/puppeteer@16.2.0/mod.ts'
+
+serve(async (req) => {
+ try {
+ // Visit browserless.io to get your free API token
+ const browser = await puppeteer.connect({
+ browserWSEndpoint: 'wss://chrome.browserless.io?token=YOUR_API_TOKEN',
+ })
+ const page = await browser.newPage()
+
+ const url = new URL(req.url).searchParams.get('url') || 'http://www.example.com'
+
+ await page.goto(url)
+ const screenshot = await page.screenshot()
+
+ return new Response(screenshot, { headers: { 'Content-Type': 'image/png' } })
+ } catch (e) {
+ console.error(e)
+ return new Response(JSON.stringify(`Error occurred when generating the screenshot`), {
+ headers: { 'Content-Type': 'application/json' },
+ status: 500,
+ })
+ }
+})
diff --git a/examples/edge-functions/supabase/functions/stripe-webhooks/index.ts b/examples/edge-functions/supabase/functions/stripe-webhooks/index.ts
index 3379e6060e8..6b159a2a5b4 100644
--- a/examples/edge-functions/supabase/functions/stripe-webhooks/index.ts
+++ b/examples/edge-functions/supabase/functions/stripe-webhooks/index.ts
@@ -5,7 +5,7 @@
import { serve } from 'https://deno.land/std@0.132.0/http/server.ts'
// esm.sh is used to compile stripe-node to be compatible with ES modules.
-import Stripe from 'https://esm.sh/stripe@10.13.0?target=deno&deno-std=0.132.0'
+import Stripe from 'https://esm.sh/stripe@10.13.0?target=deno&no-check&deno-std=0.132.0'
const stripe = Stripe(Deno.env.get('STRIPE_API_KEY'), {
// This is needed to use the Fetch API rather than relying on the Node http
diff --git a/examples/user-management/flutter-user-management/.gitignore b/examples/user-management/flutter-user-management/.gitignore
index 0fa6b675c0a..6d47c6f3495 100644
--- a/examples/user-management/flutter-user-management/.gitignore
+++ b/examples/user-management/flutter-user-management/.gitignore
@@ -30,6 +30,7 @@
.pub-cache/
.pub/
/build/
+pubspec.lock
# Web related
lib/generated_plugin_registrant.dart
diff --git a/examples/user-management/flutter-user-management/pubspec.lock b/examples/user-management/flutter-user-management/pubspec.lock
deleted file mode 100644
index 306226cee79..00000000000
--- a/examples/user-management/flutter-user-management/pubspec.lock
+++ /dev/null
@@ -1,516 +0,0 @@
-# Generated by pub
-# See https://dart.dev/tools/pub/glossary#lockfile
-packages:
- app_links:
- dependency: transitive
- description:
- name: app_links
- url: "https://pub.dartlang.org"
- source: hosted
- version: "3.2.0"
- app_links_macos:
- dependency: transitive
- description:
- name: app_links_macos
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.0.0"
- app_links_platform_interface:
- dependency: transitive
- description:
- name: app_links_platform_interface
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.0.2"
- app_links_web:
- dependency: transitive
- description:
- name: app_links_web
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.0.0"
- app_links_windows:
- dependency: transitive
- description:
- name: app_links_windows
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.0.0"
- async:
- dependency: transitive
- description:
- name: async
- url: "https://pub.dartlang.org"
- source: hosted
- version: "2.9.0"
- boolean_selector:
- dependency: transitive
- description:
- name: boolean_selector
- url: "https://pub.dartlang.org"
- source: hosted
- version: "2.1.0"
- characters:
- dependency: transitive
- description:
- name: characters
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.2.1"
- clock:
- dependency: transitive
- description:
- name: clock
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.1.1"
- collection:
- dependency: transitive
- description:
- name: collection
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.16.0"
- cross_file:
- dependency: transitive
- description:
- name: cross_file
- url: "https://pub.dartlang.org"
- source: hosted
- version: "0.3.3+1"
- crypto:
- dependency: transitive
- description:
- name: crypto
- url: "https://pub.dartlang.org"
- source: hosted
- version: "3.0.2"
- fake_async:
- dependency: transitive
- description:
- name: fake_async
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.3.1"
- ffi:
- dependency: transitive
- description:
- name: ffi
- url: "https://pub.dartlang.org"
- source: hosted
- version: "2.0.1"
- file:
- dependency: transitive
- description:
- name: file
- url: "https://pub.dartlang.org"
- source: hosted
- version: "6.1.2"
- flutter:
- dependency: "direct main"
- description: flutter
- source: sdk
- version: "0.0.0"
- flutter_plugin_android_lifecycle:
- dependency: transitive
- description:
- name: flutter_plugin_android_lifecycle
- url: "https://pub.dartlang.org"
- source: hosted
- version: "2.0.7"
- flutter_test:
- dependency: "direct dev"
- description: flutter
- source: sdk
- version: "0.0.0"
- flutter_web_plugins:
- dependency: transitive
- description: flutter
- source: sdk
- version: "0.0.0"
- functions_client:
- dependency: transitive
- description:
- name: functions_client
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.0.0"
- gotrue:
- dependency: transitive
- description:
- name: gotrue
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.0.0"
- hive:
- dependency: transitive
- description:
- name: hive
- url: "https://pub.dartlang.org"
- source: hosted
- version: "2.2.3"
- hive_flutter:
- dependency: transitive
- description:
- name: hive_flutter
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.1.0"
- http:
- dependency: transitive
- description:
- name: http
- url: "https://pub.dartlang.org"
- source: hosted
- version: "0.13.5"
- http_parser:
- dependency: transitive
- description:
- name: http_parser
- url: "https://pub.dartlang.org"
- source: hosted
- version: "4.0.1"
- image_picker:
- dependency: "direct main"
- description:
- name: image_picker
- url: "https://pub.dartlang.org"
- source: hosted
- version: "0.8.5+3"
- image_picker_android:
- dependency: transitive
- description:
- name: image_picker_android
- url: "https://pub.dartlang.org"
- source: hosted
- version: "0.8.5+1"
- image_picker_for_web:
- dependency: transitive
- description:
- name: image_picker_for_web
- url: "https://pub.dartlang.org"
- source: hosted
- version: "2.1.8"
- image_picker_ios:
- dependency: transitive
- description:
- name: image_picker_ios
- url: "https://pub.dartlang.org"
- source: hosted
- version: "0.8.5+6"
- image_picker_platform_interface:
- dependency: transitive
- description:
- name: image_picker_platform_interface
- url: "https://pub.dartlang.org"
- source: hosted
- version: "2.6.1"
- js:
- dependency: transitive
- description:
- name: js
- url: "https://pub.dartlang.org"
- source: hosted
- version: "0.6.4"
- jwt_decode:
- dependency: transitive
- description:
- name: jwt_decode
- url: "https://pub.dartlang.org"
- source: hosted
- version: "0.3.1"
- lint:
- dependency: "direct dev"
- description:
- name: lint
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.10.0"
- matcher:
- dependency: transitive
- description:
- name: matcher
- url: "https://pub.dartlang.org"
- source: hosted
- version: "0.12.12"
- material_color_utilities:
- dependency: transitive
- description:
- name: material_color_utilities
- url: "https://pub.dartlang.org"
- source: hosted
- version: "0.1.5"
- meta:
- dependency: transitive
- description:
- name: meta
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.8.0"
- mime:
- dependency: transitive
- description:
- name: mime
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.0.2"
- path:
- dependency: transitive
- description:
- name: path
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.8.2"
- path_provider:
- dependency: transitive
- description:
- name: path_provider
- url: "https://pub.dartlang.org"
- source: hosted
- version: "2.0.11"
- path_provider_android:
- dependency: transitive
- description:
- name: path_provider_android
- url: "https://pub.dartlang.org"
- source: hosted
- version: "2.0.17"
- path_provider_ios:
- dependency: transitive
- description:
- name: path_provider_ios
- url: "https://pub.dartlang.org"
- source: hosted
- version: "2.0.11"
- path_provider_linux:
- dependency: transitive
- description:
- name: path_provider_linux
- url: "https://pub.dartlang.org"
- source: hosted
- version: "2.1.7"
- path_provider_macos:
- dependency: transitive
- description:
- name: path_provider_macos
- url: "https://pub.dartlang.org"
- source: hosted
- version: "2.0.6"
- path_provider_platform_interface:
- dependency: transitive
- description:
- name: path_provider_platform_interface
- url: "https://pub.dartlang.org"
- source: hosted
- version: "2.0.4"
- path_provider_windows:
- dependency: transitive
- description:
- name: path_provider_windows
- url: "https://pub.dartlang.org"
- source: hosted
- version: "2.1.1"
- platform:
- dependency: transitive
- description:
- name: platform
- url: "https://pub.dartlang.org"
- source: hosted
- version: "3.1.0"
- plugin_platform_interface:
- dependency: transitive
- description:
- name: plugin_platform_interface
- url: "https://pub.dartlang.org"
- source: hosted
- version: "2.1.2"
- postgrest:
- dependency: transitive
- description:
- name: postgrest
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.0.0"
- process:
- dependency: transitive
- description:
- name: process
- url: "https://pub.dartlang.org"
- source: hosted
- version: "4.2.4"
- realtime_client:
- dependency: transitive
- description:
- name: realtime_client
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.0.0"
- sky_engine:
- dependency: transitive
- description: flutter
- source: sdk
- version: "0.0.99"
- source_span:
- dependency: transitive
- description:
- name: source_span
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.9.0"
- stack_trace:
- dependency: transitive
- description:
- name: stack_trace
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.10.0"
- storage_client:
- dependency: transitive
- description:
- name: storage_client
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.0.0"
- stream_channel:
- dependency: transitive
- description:
- name: stream_channel
- url: "https://pub.dartlang.org"
- source: hosted
- version: "2.1.0"
- string_scanner:
- dependency: transitive
- description:
- name: string_scanner
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.1.1"
- supabase:
- dependency: transitive
- description:
- name: supabase
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.0.1"
- supabase_flutter:
- dependency: "direct main"
- description:
- name: supabase_flutter
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.0.1"
- term_glyph:
- dependency: transitive
- description:
- name: term_glyph
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.2.1"
- test_api:
- dependency: transitive
- description:
- name: test_api
- url: "https://pub.dartlang.org"
- source: hosted
- version: "0.4.12"
- typed_data:
- dependency: transitive
- description:
- name: typed_data
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.3.1"
- universal_io:
- dependency: transitive
- description:
- name: universal_io
- url: "https://pub.dartlang.org"
- source: hosted
- version: "2.0.4"
- url_launcher:
- dependency: transitive
- description:
- name: url_launcher
- url: "https://pub.dartlang.org"
- source: hosted
- version: "6.1.5"
- url_launcher_android:
- dependency: transitive
- description:
- name: url_launcher_android
- url: "https://pub.dartlang.org"
- source: hosted
- version: "6.0.17"
- url_launcher_ios:
- dependency: transitive
- description:
- name: url_launcher_ios
- url: "https://pub.dartlang.org"
- source: hosted
- version: "6.0.17"
- url_launcher_linux:
- dependency: transitive
- description:
- name: url_launcher_linux
- url: "https://pub.dartlang.org"
- source: hosted
- version: "3.0.1"
- url_launcher_macos:
- dependency: transitive
- description:
- name: url_launcher_macos
- url: "https://pub.dartlang.org"
- source: hosted
- version: "3.0.1"
- url_launcher_platform_interface:
- dependency: transitive
- description:
- name: url_launcher_platform_interface
- url: "https://pub.dartlang.org"
- source: hosted
- version: "2.1.0"
- url_launcher_web:
- dependency: transitive
- description:
- name: url_launcher_web
- url: "https://pub.dartlang.org"
- source: hosted
- version: "2.0.12"
- url_launcher_windows:
- dependency: transitive
- description:
- name: url_launcher_windows
- url: "https://pub.dartlang.org"
- source: hosted
- version: "3.0.1"
- vector_math:
- dependency: transitive
- description:
- name: vector_math
- url: "https://pub.dartlang.org"
- source: hosted
- version: "2.1.2"
- web_socket_channel:
- dependency: transitive
- description:
- name: web_socket_channel
- url: "https://pub.dartlang.org"
- source: hosted
- version: "2.2.0"
- win32:
- dependency: transitive
- description:
- name: win32
- url: "https://pub.dartlang.org"
- source: hosted
- version: "2.7.0"
- xdg_directories:
- dependency: transitive
- description:
- name: xdg_directories
- url: "https://pub.dartlang.org"
- source: hosted
- version: "0.2.0+1"
-sdks:
- dart: ">=2.17.0 <3.0.0"
- flutter: ">=3.0.0"
diff --git a/examples/user-management/flutter-user-management/pubspec.yaml b/examples/user-management/flutter-user-management/pubspec.yaml
index c38e49f8498..82b27ca5aea 100644
--- a/examples/user-management/flutter-user-management/pubspec.yaml
+++ b/examples/user-management/flutter-user-management/pubspec.yaml
@@ -13,7 +13,7 @@ dependencies:
sdk: flutter
image_picker: ^0.8.4
- supabase_flutter: ^1.0.0
+ supabase_flutter: ^1.2.0
dev_dependencies:
flutter_test:
diff --git a/i18n/README.pt-br.md b/i18n/README.pt-br.md
index f16daefe69c..fa90c744008 100644
--- a/i18n/README.pt-br.md
+++ b/i18n/README.pt-br.md
@@ -109,7 +109,7 @@ Nossa biblioteca de cliente Γ© modular. Cada sub-biblioteca Γ© uma implementaΓ§
postgrest-csharp
gotrue-csharp
realtime-csharp
- -
+ storage-csharp
Flutter
diff --git a/package-lock.json b/package-lock.json
index 6e853856f36..aa43ea6420d 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -44,10 +44,10 @@
"@algolia/autocomplete-plugin-recent-searches": "^1.7.2",
"@apollo/client": "^3.6.6",
"@code-hike/mdx": "^0.7.4",
- "@docsearch/react": "1.0.0-alpha.27",
- "@mdx-js/loader": "^2.1.5",
- "@mdx-js/react": "^2.1.5",
- "@next/mdx": "^12.3.2",
+ "@docsearch/react": "^3.3.0",
+ "@mdx-js/loader": "^1.6.22",
+ "@mdx-js/react": "^1.6.22",
+ "@next/mdx": "^12.0.4",
"@radix-ui/react-accordion": "^1.0.1",
"@tailwindcss/typography": "^0.4.1",
"algoliasearch": "^4.14.2",
@@ -104,6 +104,140 @@
"typescript": "^4.5.3"
}
},
+ "apps/docs/node_modules/@babel/core": {
+ "version": "7.12.9",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.9.tgz",
+ "integrity": "sha512-gTXYh3M5wb7FRXQy+FErKFAv90BnlOuNn1QkCK2lREoPAjrQCO49+HVSrFoe5uakFAF5eenS75KbO2vQiLrTMQ==",
+ "dependencies": {
+ "@babel/code-frame": "^7.10.4",
+ "@babel/generator": "^7.12.5",
+ "@babel/helper-module-transforms": "^7.12.1",
+ "@babel/helpers": "^7.12.5",
+ "@babel/parser": "^7.12.7",
+ "@babel/template": "^7.12.7",
+ "@babel/traverse": "^7.12.9",
+ "@babel/types": "^7.12.7",
+ "convert-source-map": "^1.7.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.1",
+ "json5": "^2.1.2",
+ "lodash": "^4.17.19",
+ "resolve": "^1.3.2",
+ "semver": "^5.4.1",
+ "source-map": "^0.5.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/babel"
+ }
+ },
+ "apps/docs/node_modules/@babel/helper-plugin-utils": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+ "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg=="
+ },
+ "apps/docs/node_modules/@babel/plugin-proposal-object-rest-spread": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.1.tgz",
+ "integrity": "sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/plugin-syntax-object-rest-spread": "^7.8.0",
+ "@babel/plugin-transform-parameters": "^7.12.1"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "apps/docs/node_modules/@babel/plugin-syntax-jsx": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.1.tgz",
+ "integrity": "sha512-1yRi7yAtB0ETgxdY9ti/p2TivUxJkTdhu/ZbF9MshVGqOx1TdB3b7xCXs49Fupgg50N45KcAsRP/ZqWjs9SRjg==",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "apps/docs/node_modules/@mdx-js/loader": {
+ "version": "1.6.22",
+ "resolved": "https://registry.npmjs.org/@mdx-js/loader/-/loader-1.6.22.tgz",
+ "integrity": "sha512-9CjGwy595NaxAYp0hF9B/A0lH6C8Rms97e2JS9d3jVUtILn6pT5i5IV965ra3lIWc7Rs1GG1tBdVF7dCowYe6Q==",
+ "dependencies": {
+ "@mdx-js/mdx": "1.6.22",
+ "@mdx-js/react": "1.6.22",
+ "loader-utils": "2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "apps/docs/node_modules/@mdx-js/mdx": {
+ "version": "1.6.22",
+ "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-1.6.22.tgz",
+ "integrity": "sha512-AMxuLxPz2j5/6TpF/XSdKpQP1NlG0z11dFOlq+2IP/lSgl11GY8ji6S/rgsViN/L0BDvHvUMruRb7ub+24LUYA==",
+ "dependencies": {
+ "@babel/core": "7.12.9",
+ "@babel/plugin-syntax-jsx": "7.12.1",
+ "@babel/plugin-syntax-object-rest-spread": "7.8.3",
+ "@mdx-js/util": "1.6.22",
+ "babel-plugin-apply-mdx-type-prop": "1.6.22",
+ "babel-plugin-extract-import-names": "1.6.22",
+ "camelcase-css": "2.0.1",
+ "detab": "2.0.4",
+ "hast-util-raw": "6.0.1",
+ "lodash.uniq": "4.5.0",
+ "mdast-util-to-hast": "10.0.1",
+ "remark-footnotes": "2.0.0",
+ "remark-mdx": "1.6.22",
+ "remark-parse": "8.0.3",
+ "remark-squeeze-paragraphs": "4.0.0",
+ "style-to-object": "0.3.0",
+ "unified": "9.2.0",
+ "unist-builder": "2.0.3",
+ "unist-util-visit": "2.0.3"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "apps/docs/node_modules/@mdx-js/mdx/node_modules/remark-mdx": {
+ "version": "1.6.22",
+ "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-1.6.22.tgz",
+ "integrity": "sha512-phMHBJgeV76uyFkH4rvzCftLfKCr2RZuF+/gmVcaKrpsihyzmhXjA0BEMDaPTXG5y8qZOKPVo83NAOX01LPnOQ==",
+ "dependencies": {
+ "@babel/core": "7.12.9",
+ "@babel/helper-plugin-utils": "7.10.4",
+ "@babel/plugin-proposal-object-rest-spread": "7.12.1",
+ "@babel/plugin-syntax-jsx": "7.12.1",
+ "@mdx-js/util": "1.6.22",
+ "is-alphabetical": "1.0.4",
+ "remark-parse": "8.0.3",
+ "unified": "9.2.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "apps/docs/node_modules/@mdx-js/react": {
+ "version": "1.6.22",
+ "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-1.6.22.tgz",
+ "integrity": "sha512-TDoPum4SHdfPiGSAaRBw7ECyI8VaHpK8GJugbJIJuqyh6kzw9ZLJZW3HGL3NNrJGxcAixUvqROm+YuQOo5eXtg==",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ },
+ "peerDependencies": {
+ "react": "^16.13.1 || ^17.0.0"
+ }
+ },
"apps/docs/node_modules/ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
@@ -172,6 +306,68 @@
"url": "https://opencollective.com/eslint"
}
},
+ "apps/docs/node_modules/is-buffer": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz",
+ "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "apps/docs/node_modules/is-plain-obj": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
+ "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "apps/docs/node_modules/loader-utils": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
+ "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
+ "dependencies": {
+ "big.js": "^5.2.2",
+ "emojis-list": "^3.0.0",
+ "json5": "^2.1.2"
+ },
+ "engines": {
+ "node": ">=8.9.0"
+ }
+ },
+ "apps/docs/node_modules/mdast-util-to-hast": {
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-10.0.1.tgz",
+ "integrity": "sha512-BW3LM9SEMnjf4HXXVApZMt8gLQWVNXc3jryK0nJu/rOXPOnlkUjmdkDlmxMirpbU9ILncGFIwLH/ubnWBbcdgA==",
+ "dependencies": {
+ "@types/mdast": "^3.0.0",
+ "@types/unist": "^2.0.0",
+ "mdast-util-definitions": "^4.0.0",
+ "mdurl": "^1.0.0",
+ "unist-builder": "^2.0.0",
+ "unist-util-generated": "^1.0.0",
+ "unist-util-position": "^3.0.0",
+ "unist-util-visit": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
"apps/docs/node_modules/mdx-mermaid": {
"version": "2.0.0-rc3",
"resolved": "https://registry.npmjs.org/mdx-mermaid/-/mdx-mermaid-2.0.0-rc3.tgz",
@@ -189,6 +385,145 @@
"unist-util-visit": "^4.1.0"
}
},
+ "apps/docs/node_modules/remark-parse": {
+ "version": "8.0.3",
+ "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-8.0.3.tgz",
+ "integrity": "sha512-E1K9+QLGgggHxCQtLt++uXltxEprmWzNfg+MxpfHsZlrddKzZ/hZyWHDbK3/Ap8HJQqYJRXP+jHczdL6q6i85Q==",
+ "dependencies": {
+ "ccount": "^1.0.0",
+ "collapse-white-space": "^1.0.2",
+ "is-alphabetical": "^1.0.0",
+ "is-decimal": "^1.0.0",
+ "is-whitespace-character": "^1.0.0",
+ "is-word-character": "^1.0.0",
+ "markdown-escapes": "^1.0.0",
+ "parse-entities": "^2.0.0",
+ "repeat-string": "^1.5.4",
+ "state-toggle": "^1.0.0",
+ "trim": "0.0.1",
+ "trim-trailing-lines": "^1.0.0",
+ "unherit": "^1.0.4",
+ "unist-util-remove-position": "^2.0.0",
+ "vfile-location": "^3.0.0",
+ "xtend": "^4.0.1"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "apps/docs/node_modules/semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
+ "apps/docs/node_modules/source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "apps/docs/node_modules/unified": {
+ "version": "9.2.0",
+ "resolved": "https://registry.npmjs.org/unified/-/unified-9.2.0.tgz",
+ "integrity": "sha512-vx2Z0vY+a3YoTj8+pttM3tiJHCwY5UFbYdiWrwBEbHmK8pvsPj2rtAX2BFfgXen8T39CJWblWRDT4L5WGXtDdg==",
+ "dependencies": {
+ "bail": "^1.0.0",
+ "extend": "^3.0.0",
+ "is-buffer": "^2.0.0",
+ "is-plain-obj": "^2.0.0",
+ "trough": "^1.0.0",
+ "vfile": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "apps/docs/node_modules/unist-builder": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/unist-builder/-/unist-builder-2.0.3.tgz",
+ "integrity": "sha512-f98yt5pnlMWlzP539tPc4grGMsFaQQlP/vM396b00jngsiINumNmsY8rkXjfoi1c6QaM8nQ3vaGDuoKWbe/1Uw==",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "apps/docs/node_modules/unist-util-generated": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-1.1.6.tgz",
+ "integrity": "sha512-cln2Mm1/CZzN5ttGK7vkoGw+RZ8VcUH6BtGbq98DDtRGquAAOXig1mrBQYelOwMXYS8rK+vZDyyojSjp7JX+Lg==",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "apps/docs/node_modules/unist-util-remove-position": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-2.0.1.tgz",
+ "integrity": "sha512-fDZsLYIe2uT+oGFnuZmy73K6ZxOPG/Qcm+w7jbEjaFcJgbQ6cqjs/eSPzXhsmGpAsWPkqZM9pYjww5QTn3LHMA==",
+ "dependencies": {
+ "unist-util-visit": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "apps/docs/node_modules/unist-util-stringify-position": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz",
+ "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==",
+ "dependencies": {
+ "@types/unist": "^2.0.2"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "apps/docs/node_modules/vfile": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz",
+ "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==",
+ "dependencies": {
+ "@types/unist": "^2.0.0",
+ "is-buffer": "^2.0.0",
+ "unist-util-stringify-position": "^2.0.0",
+ "vfile-message": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "apps/docs/node_modules/vfile-location": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-3.2.0.tgz",
+ "integrity": "sha512-aLEIZKv/oxuCDZ8lkJGhuhztf/BW4M+iHdCwglA/eWc+vtuRFJj8EtgceYFX4LRjOhCAAiNHsKGssC6onJ+jbA==",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "apps/docs/node_modules/vfile-message": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz",
+ "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==",
+ "dependencies": {
+ "@types/unist": "^2.0.0",
+ "unist-util-stringify-position": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
"apps/www": {
"version": "0.0.3",
"license": "MIT",
@@ -201,6 +536,7 @@
"@supabase/auth-ui-react": "^0.1.6",
"@supabase/supabase-js": "^2.0.0",
"classnames": "^2.3.1",
+ "cobe": "^0.6.2",
"common": "*",
"config": "*",
"date-fns": "2.10.0",
@@ -235,6 +571,7 @@
"ui": "*",
"use-debounce": "^7.0.1",
"uuid": "^8.3.2",
+ "vanilla-tilt": "1.7.0",
"yup": "^0.32.11"
},
"devDependencies": {
@@ -2682,25 +3019,62 @@
}
},
"node_modules/@docsearch/css": {
- "version": "1.0.0-alpha.28",
- "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-1.0.0-alpha.28.tgz",
- "integrity": "sha512-1AhRzVdAkrWwhaxTX6/R7SnFHz8yLz1W8I/AldlTrfbNvZs9INk1FZiEFTJdgHaP68nhgQNWSGlQiDiI3y2RYg=="
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.3.0.tgz",
+ "integrity": "sha512-rODCdDtGyudLj+Va8b6w6Y85KE85bXRsps/R4Yjwt5vueXKXZQKYw0aA9knxLBT6a/bI/GMrAcmCR75KYOM6hg=="
},
"node_modules/@docsearch/react": {
- "version": "1.0.0-alpha.27",
- "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-1.0.0-alpha.27.tgz",
- "integrity": "sha512-jcgUHZsrNNRsaVsplqKhXWheh4VzRTCdhsPuVhJMRvfsFUqXEPo/7kVt5xIybtOj9u+/FVdeSO+APJEE2rakYA==",
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.3.0.tgz",
+ "integrity": "sha512-fhS5adZkae2SSdMYEMVg6pxI5a/cE+tW16ki1V0/ur4Fdok3hBRkmN/H8VvlXnxzggkQIIRIVvYPn00JPjen3A==",
"dependencies": {
- "@docsearch/css": "^1.0.0-alpha.27",
- "@francoischalifour/autocomplete-core": "^1.0.0-alpha.27",
- "@francoischalifour/autocomplete-preset-algolia": "^1.0.0-alpha.27",
+ "@algolia/autocomplete-core": "1.7.2",
+ "@algolia/autocomplete-preset-algolia": "1.7.2",
+ "@docsearch/css": "3.3.0",
"algoliasearch": "^4.0.0"
},
"peerDependencies": {
- "react": "^16.8.0",
- "react-dom": "^16.8.0"
+ "@types/react": ">= 16.8.0 < 19.0.0",
+ "react": ">= 16.8.0 < 19.0.0",
+ "react-dom": ">= 16.8.0 < 19.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ },
+ "react-dom": {
+ "optional": true
+ }
}
},
+ "node_modules/@docsearch/react/node_modules/@algolia/autocomplete-core": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.7.2.tgz",
+ "integrity": "sha512-eclwUDC6qfApNnEfu1uWcL/rudQsn59tjEoUYZYE2JSXZrHLRjBUGMxiCoknobU2Pva8ejb0eRxpIYDtVVqdsw==",
+ "dependencies": {
+ "@algolia/autocomplete-shared": "1.7.2"
+ }
+ },
+ "node_modules/@docsearch/react/node_modules/@algolia/autocomplete-preset-algolia": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.7.2.tgz",
+ "integrity": "sha512-+RYEG6B0QiGGfRb2G3MtPfyrl0dALF3cQNTWBzBX6p5o01vCCGTTinAm2UKG3tfc2CnOMAtnPLkzNZyJUpnVJw==",
+ "dependencies": {
+ "@algolia/autocomplete-shared": "1.7.2"
+ },
+ "peerDependencies": {
+ "@algolia/client-search": ">= 4.9.1 < 6",
+ "algoliasearch": ">= 4.9.1 < 6"
+ }
+ },
+ "node_modules/@docsearch/react/node_modules/@algolia/autocomplete-shared": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.7.2.tgz",
+ "integrity": "sha512-QCckjiC7xXHIUaIL3ektBtjJ0w7tTA3iqKcAE/Hjn1lZ5omp7i3Y4e09rAr9ZybqirL7AbxCLLq0Ra5DDPKeug=="
+ },
"node_modules/@eslint/eslintrc": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz",
@@ -2750,16 +3124,6 @@
"npm": ">=6.0.0"
}
},
- "node_modules/@francoischalifour/autocomplete-core": {
- "version": "1.0.0-alpha.28",
- "resolved": "https://registry.npmjs.org/@francoischalifour/autocomplete-core/-/autocomplete-core-1.0.0-alpha.28.tgz",
- "integrity": "sha512-rL9x+72btViw+9icfBKUJjZj87FgjFrD2esuTUqtj4RAX3s4AuVZiN8XEsfjQBSc6qJk31cxlvqZHC/BIyYXgg=="
- },
- "node_modules/@francoischalifour/autocomplete-preset-algolia": {
- "version": "1.0.0-alpha.28",
- "resolved": "https://registry.npmjs.org/@francoischalifour/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.0.0-alpha.28.tgz",
- "integrity": "sha512-bprfNmYt1opFUFEtD2XfY/kEsm13bzHQgU80uMjhuK0DJ914IjolT1GytpkdM6tJ4MBvyiJPP+bTtWO+BZ7c7w=="
- },
"node_modules/@gar/promisify": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz",
@@ -9257,6 +9621,75 @@
"tailwindcss": ">=2.0.0"
}
},
+ "node_modules/@tanstack/match-sorter-utils": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/@tanstack/match-sorter-utils/-/match-sorter-utils-8.1.1.tgz",
+ "integrity": "sha512-IdmEekEYxQsoLOR0XQyw3jD1GujBpRRYaGJYQUw1eOT1eUugWxdc7jomh1VQ1EKHcdwDLpLaCz/8y4KraU4T9A==",
+ "dependencies": {
+ "remove-accents": "0.4.2"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/kentcdodds"
+ }
+ },
+ "node_modules/@tanstack/query-core": {
+ "version": "4.15.1",
+ "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-4.15.1.tgz",
+ "integrity": "sha512-+UfqJsNbPIVo0a9ANW0ZxtjiMfGLaaoIaL9vZeVycvmBuWywJGtSi7fgPVMCPdZQFOzMsaXaOsDtSKQD5xLRVQ==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/tannerlinsley"
+ }
+ },
+ "node_modules/@tanstack/react-query": {
+ "version": "4.16.1",
+ "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-4.16.1.tgz",
+ "integrity": "sha512-PDE9u49wSDykPazlCoLFevUpceLjQ0Mm8i6038HgtTEKb/aoVnUZdlUP7C392ds3Cd75+EGlHU7qpEX06R7d9Q==",
+ "dependencies": {
+ "@tanstack/query-core": "4.15.1",
+ "use-sync-external-store": "^1.2.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/tannerlinsley"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0",
+ "react-native": "*"
+ },
+ "peerDependenciesMeta": {
+ "react-dom": {
+ "optional": true
+ },
+ "react-native": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@tanstack/react-query-devtools": {
+ "version": "4.16.1",
+ "resolved": "https://registry.npmjs.org/@tanstack/react-query-devtools/-/react-query-devtools-4.16.1.tgz",
+ "integrity": "sha512-VrDYLmG+OOcvGSZL5avG4R8jhqeMFP7pzW2sh2BWEV9UfI+aocG+CW8y8ygacxuKy48m8Tyo/xfe8H1z9BGb+g==",
+ "dependencies": {
+ "@tanstack/match-sorter-utils": "8.1.1",
+ "superjson": "^1.10.0",
+ "use-sync-external-store": "^1.2.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/tannerlinsley"
+ },
+ "peerDependencies": {
+ "@tanstack/react-query": "4.16.1",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
"node_modules/@testdeck/core": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/@testdeck/core/-/core-0.2.2.tgz",
@@ -12929,6 +13362,14 @@
"node": ">= 0.12.0"
}
},
+ "node_modules/cobe": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/cobe/-/cobe-0.6.2.tgz",
+ "integrity": "sha512-0lU+QD18yzxsWsuTy4HB+kRYT/SugVPRx95MhfteZgD2UgEJ+6fScChroCVqIXWi5IxL0T8Ywm8avHvmOsl5xQ==",
+ "dependencies": {
+ "phenomenon": "^1.6.0"
+ }
+ },
"node_modules/code-point-at": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
@@ -13228,6 +13669,20 @@
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
"dev": true
},
+ "node_modules/copy-anything": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.2.tgz",
+ "integrity": "sha512-CzATjGXzUQ0EvuvgOCI6A4BGOo2bcVx8B+eC2nF862iv9fopnPQwlrbACakNCHRIJbCSBj+J/9JeDf60k64MkA==",
+ "dependencies": {
+ "is-what": "^4.1.6"
+ },
+ "engines": {
+ "node": ">=12.13"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mesqueeb"
+ }
+ },
"node_modules/copy-concurrently": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz",
@@ -19912,6 +20367,17 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/is-what": {
+ "version": "4.1.7",
+ "resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.7.tgz",
+ "integrity": "sha512-DBVOQNiPKnGMxRMLIYSwERAS5MVY1B7xYiGnpgctsOFvVDz9f9PFXXxMcTOHuoqYp4NK9qFYQaIC1NRRxLMpBQ==",
+ "engines": {
+ "node": ">=12.13"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mesqueeb"
+ }
+ },
"node_modules/is-whitespace-character": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz",
@@ -26507,6 +26973,11 @@
"split2": "^4.1.0"
}
},
+ "node_modules/phenomenon": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/phenomenon/-/phenomenon-1.6.0.tgz",
+ "integrity": "sha512-7h9/fjPD3qNlgggzm88cY58l9sudZ6Ey+UmZsizfhtawO6E3srZQXywaNm2lBwT72TbpHYRPy7ytIHeBUD/G0A=="
+ },
"node_modules/picocolors": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
@@ -31423,6 +31894,11 @@
"sprintf-js": "~1.0.2"
}
},
+ "node_modules/remove-accents": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.4.2.tgz",
+ "integrity": "sha512-7pXIJqJOq5tFgG1A2Zxti3Ht8jJF337m4sowbuHsW30ZnkQFnDzy9qBNhgzX8ZLW4+UBcXiiR7SwR6pokHsxiA=="
+ },
"node_modules/remove-trailing-separator": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
@@ -33215,6 +33691,17 @@
"resolved": "tests",
"link": true
},
+ "node_modules/superjson": {
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/superjson/-/superjson-1.11.0.tgz",
+ "integrity": "sha512-6PfAg1FKhqkwWvPb2uXhH4MkMttdc17eJ91+Aoz4s1XUEDZFmLfFx/xVA3wgkPxAGy5dpozgGdK6V/n20Wj9yg==",
+ "dependencies": {
+ "copy-anything": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -35089,6 +35576,14 @@
"react": "^16.8.0 || ^17.0.0"
}
},
+ "node_modules/use-sync-external-store": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz",
+ "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==",
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
"node_modules/utf-8-validate": {
"version": "5.0.10",
"resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz",
@@ -35236,6 +35731,11 @@
"spdx-expression-parse": "^3.0.0"
}
},
+ "node_modules/vanilla-tilt": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/vanilla-tilt/-/vanilla-tilt-1.7.0.tgz",
+ "integrity": "sha512-u9yUhpSasFeqQCuiTon+RSb0aHzcj9stvWVXQIswzKL5oG491lkYk7U1GmhOAEZt7yPT6EiYZRJhIh2MFBncOA=="
+ },
"node_modules/vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
@@ -36918,7 +37418,9 @@
"@supabase/postgres-meta": "^0.26.1",
"@supabase/react-data-grid": "^7.1.0-beta.7",
"@supabase/shared-types": "^0.1.29",
- "@supabase/supabase-js": "^2.1.0",
+ "@supabase/supabase-js": "^2.1.1",
+ "@tanstack/react-query": "^4.16.1",
+ "@tanstack/react-query-devtools": "^4.16.1",
"ajv": "^8.6.3",
"analytics-node": "^3.5.0",
"awesome-debounce-promise": "^2.1.0",
@@ -37022,7 +37524,7 @@
"storybook-dark-mode": "^1.0.4",
"tailwindcss": "^3.0.22",
"ts-jest": "^27.0.7",
- "typescript": "4.3.4"
+ "typescript": "4.8.4"
}
},
"studio/node_modules/@next/bundle-analyzer": {
@@ -37243,9 +37745,9 @@
}
},
"studio/node_modules/typescript": {
- "version": "4.3.4",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.4.tgz",
- "integrity": "sha512-uauPG7XZn9F/mo+7MrsRjyvbxFpzemRjKEZXS4AK83oP2KKOJPvb+9cO/gmnv8arWZvhnjVOXz7B49m1l0e9Ew==",
+ "version": "4.8.4",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz",
+ "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==",
"dev": true,
"bin": {
"tsc": "bin/tsc",
@@ -39063,19 +39565,42 @@
"dev": true
},
"@docsearch/css": {
- "version": "1.0.0-alpha.28",
- "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-1.0.0-alpha.28.tgz",
- "integrity": "sha512-1AhRzVdAkrWwhaxTX6/R7SnFHz8yLz1W8I/AldlTrfbNvZs9INk1FZiEFTJdgHaP68nhgQNWSGlQiDiI3y2RYg=="
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.3.0.tgz",
+ "integrity": "sha512-rODCdDtGyudLj+Va8b6w6Y85KE85bXRsps/R4Yjwt5vueXKXZQKYw0aA9knxLBT6a/bI/GMrAcmCR75KYOM6hg=="
},
"@docsearch/react": {
- "version": "1.0.0-alpha.27",
- "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-1.0.0-alpha.27.tgz",
- "integrity": "sha512-jcgUHZsrNNRsaVsplqKhXWheh4VzRTCdhsPuVhJMRvfsFUqXEPo/7kVt5xIybtOj9u+/FVdeSO+APJEE2rakYA==",
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.3.0.tgz",
+ "integrity": "sha512-fhS5adZkae2SSdMYEMVg6pxI5a/cE+tW16ki1V0/ur4Fdok3hBRkmN/H8VvlXnxzggkQIIRIVvYPn00JPjen3A==",
"requires": {
- "@docsearch/css": "^1.0.0-alpha.27",
- "@francoischalifour/autocomplete-core": "^1.0.0-alpha.27",
- "@francoischalifour/autocomplete-preset-algolia": "^1.0.0-alpha.27",
+ "@algolia/autocomplete-core": "1.7.2",
+ "@algolia/autocomplete-preset-algolia": "1.7.2",
+ "@docsearch/css": "3.3.0",
"algoliasearch": "^4.0.0"
+ },
+ "dependencies": {
+ "@algolia/autocomplete-core": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.7.2.tgz",
+ "integrity": "sha512-eclwUDC6qfApNnEfu1uWcL/rudQsn59tjEoUYZYE2JSXZrHLRjBUGMxiCoknobU2Pva8ejb0eRxpIYDtVVqdsw==",
+ "requires": {
+ "@algolia/autocomplete-shared": "1.7.2"
+ }
+ },
+ "@algolia/autocomplete-preset-algolia": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.7.2.tgz",
+ "integrity": "sha512-+RYEG6B0QiGGfRb2G3MtPfyrl0dALF3cQNTWBzBX6p5o01vCCGTTinAm2UKG3tfc2CnOMAtnPLkzNZyJUpnVJw==",
+ "requires": {
+ "@algolia/autocomplete-shared": "1.7.2"
+ }
+ },
+ "@algolia/autocomplete-shared": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.7.2.tgz",
+ "integrity": "sha512-QCckjiC7xXHIUaIL3ektBtjJ0w7tTA3iqKcAE/Hjn1lZ5omp7i3Y4e09rAr9ZybqirL7AbxCLLq0Ra5DDPKeug=="
+ }
}
},
"@eslint/eslintrc": {
@@ -39115,16 +39640,6 @@
"integrity": "sha512-8YXBE2ZcU/pImVOHX7MWrSR/X5up7t6rPWZlk34RwZEcdr3ua6X+32pSd6XuOQRN+vbuvYNfA6iey8NbrjuMFQ==",
"dev": true
},
- "@francoischalifour/autocomplete-core": {
- "version": "1.0.0-alpha.28",
- "resolved": "https://registry.npmjs.org/@francoischalifour/autocomplete-core/-/autocomplete-core-1.0.0-alpha.28.tgz",
- "integrity": "sha512-rL9x+72btViw+9icfBKUJjZj87FgjFrD2esuTUqtj4RAX3s4AuVZiN8XEsfjQBSc6qJk31cxlvqZHC/BIyYXgg=="
- },
- "@francoischalifour/autocomplete-preset-algolia": {
- "version": "1.0.0-alpha.28",
- "resolved": "https://registry.npmjs.org/@francoischalifour/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.0.0-alpha.28.tgz",
- "integrity": "sha512-bprfNmYt1opFUFEtD2XfY/kEsm13bzHQgU80uMjhuK0DJ914IjolT1GytpkdM6tJ4MBvyiJPP+bTtWO+BZ7c7w=="
- },
"@gar/promisify": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz",
@@ -43986,6 +44501,38 @@
"lodash.uniq": "^4.5.0"
}
},
+ "@tanstack/match-sorter-utils": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/@tanstack/match-sorter-utils/-/match-sorter-utils-8.1.1.tgz",
+ "integrity": "sha512-IdmEekEYxQsoLOR0XQyw3jD1GujBpRRYaGJYQUw1eOT1eUugWxdc7jomh1VQ1EKHcdwDLpLaCz/8y4KraU4T9A==",
+ "requires": {
+ "remove-accents": "0.4.2"
+ }
+ },
+ "@tanstack/query-core": {
+ "version": "4.15.1",
+ "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-4.15.1.tgz",
+ "integrity": "sha512-+UfqJsNbPIVo0a9ANW0ZxtjiMfGLaaoIaL9vZeVycvmBuWywJGtSi7fgPVMCPdZQFOzMsaXaOsDtSKQD5xLRVQ=="
+ },
+ "@tanstack/react-query": {
+ "version": "4.16.1",
+ "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-4.16.1.tgz",
+ "integrity": "sha512-PDE9u49wSDykPazlCoLFevUpceLjQ0Mm8i6038HgtTEKb/aoVnUZdlUP7C392ds3Cd75+EGlHU7qpEX06R7d9Q==",
+ "requires": {
+ "@tanstack/query-core": "4.15.1",
+ "use-sync-external-store": "^1.2.0"
+ }
+ },
+ "@tanstack/react-query-devtools": {
+ "version": "4.16.1",
+ "resolved": "https://registry.npmjs.org/@tanstack/react-query-devtools/-/react-query-devtools-4.16.1.tgz",
+ "integrity": "sha512-VrDYLmG+OOcvGSZL5avG4R8jhqeMFP7pzW2sh2BWEV9UfI+aocG+CW8y8ygacxuKy48m8Tyo/xfe8H1z9BGb+g==",
+ "requires": {
+ "@tanstack/match-sorter-utils": "8.1.1",
+ "superjson": "^1.10.0",
+ "use-sync-external-store": "^1.2.0"
+ }
+ },
"@testdeck/core": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/@testdeck/core/-/core-0.2.2.tgz",
@@ -46929,6 +47476,14 @@
"integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==",
"dev": true
},
+ "cobe": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/cobe/-/cobe-0.6.2.tgz",
+ "integrity": "sha512-0lU+QD18yzxsWsuTy4HB+kRYT/SugVPRx95MhfteZgD2UgEJ+6fScChroCVqIXWi5IxL0T8Ywm8avHvmOsl5xQ==",
+ "requires": {
+ "phenomenon": "^1.6.0"
+ }
+ },
"code-point-at": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
@@ -47214,6 +47769,14 @@
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
"dev": true
},
+ "copy-anything": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.2.tgz",
+ "integrity": "sha512-CzATjGXzUQ0EvuvgOCI6A4BGOo2bcVx8B+eC2nF862iv9fopnPQwlrbACakNCHRIJbCSBj+J/9JeDf60k64MkA==",
+ "requires": {
+ "is-what": "^4.1.6"
+ }
+ },
"copy-concurrently": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz",
@@ -48848,10 +49411,10 @@
"@algolia/autocomplete-plugin-recent-searches": "^1.7.2",
"@apollo/client": "^3.6.6",
"@code-hike/mdx": "^0.7.4",
- "@docsearch/react": "1.0.0-alpha.27",
- "@mdx-js/loader": "^2.1.5",
- "@mdx-js/react": "^2.1.5",
- "@next/mdx": "^12.3.2",
+ "@docsearch/react": "^3.3.0",
+ "@mdx-js/loader": "^1.6.22",
+ "@mdx-js/react": "^1.6.22",
+ "@next/mdx": "^12.0.4",
"@radix-ui/react-accordion": "^1.0.1",
"@tailwindcss/typography": "^0.4.1",
"@types/node": "^17.0.12",
@@ -48904,6 +49467,111 @@
"ui": "*"
},
"dependencies": {
+ "@babel/core": {
+ "version": "7.12.9",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.9.tgz",
+ "integrity": "sha512-gTXYh3M5wb7FRXQy+FErKFAv90BnlOuNn1QkCK2lREoPAjrQCO49+HVSrFoe5uakFAF5eenS75KbO2vQiLrTMQ==",
+ "requires": {
+ "@babel/code-frame": "^7.10.4",
+ "@babel/generator": "^7.12.5",
+ "@babel/helper-module-transforms": "^7.12.1",
+ "@babel/helpers": "^7.12.5",
+ "@babel/parser": "^7.12.7",
+ "@babel/template": "^7.12.7",
+ "@babel/traverse": "^7.12.9",
+ "@babel/types": "^7.12.7",
+ "convert-source-map": "^1.7.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.1",
+ "json5": "^2.1.2",
+ "lodash": "^4.17.19",
+ "resolve": "^1.3.2",
+ "semver": "^5.4.1",
+ "source-map": "^0.5.0"
+ }
+ },
+ "@babel/helper-plugin-utils": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+ "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg=="
+ },
+ "@babel/plugin-proposal-object-rest-spread": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.1.tgz",
+ "integrity": "sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA==",
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/plugin-syntax-object-rest-spread": "^7.8.0",
+ "@babel/plugin-transform-parameters": "^7.12.1"
+ }
+ },
+ "@babel/plugin-syntax-jsx": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.1.tgz",
+ "integrity": "sha512-1yRi7yAtB0ETgxdY9ti/p2TivUxJkTdhu/ZbF9MshVGqOx1TdB3b7xCXs49Fupgg50N45KcAsRP/ZqWjs9SRjg==",
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@mdx-js/loader": {
+ "version": "1.6.22",
+ "resolved": "https://registry.npmjs.org/@mdx-js/loader/-/loader-1.6.22.tgz",
+ "integrity": "sha512-9CjGwy595NaxAYp0hF9B/A0lH6C8Rms97e2JS9d3jVUtILn6pT5i5IV965ra3lIWc7Rs1GG1tBdVF7dCowYe6Q==",
+ "requires": {
+ "@mdx-js/mdx": "1.6.22",
+ "@mdx-js/react": "1.6.22",
+ "loader-utils": "2.0.0"
+ }
+ },
+ "@mdx-js/mdx": {
+ "version": "1.6.22",
+ "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-1.6.22.tgz",
+ "integrity": "sha512-AMxuLxPz2j5/6TpF/XSdKpQP1NlG0z11dFOlq+2IP/lSgl11GY8ji6S/rgsViN/L0BDvHvUMruRb7ub+24LUYA==",
+ "requires": {
+ "@babel/core": "7.12.9",
+ "@babel/plugin-syntax-jsx": "7.12.1",
+ "@babel/plugin-syntax-object-rest-spread": "7.8.3",
+ "@mdx-js/util": "1.6.22",
+ "babel-plugin-apply-mdx-type-prop": "1.6.22",
+ "babel-plugin-extract-import-names": "1.6.22",
+ "camelcase-css": "2.0.1",
+ "detab": "2.0.4",
+ "hast-util-raw": "6.0.1",
+ "lodash.uniq": "4.5.0",
+ "mdast-util-to-hast": "10.0.1",
+ "remark-footnotes": "2.0.0",
+ "remark-mdx": "1.6.22",
+ "remark-parse": "8.0.3",
+ "remark-squeeze-paragraphs": "4.0.0",
+ "style-to-object": "0.3.0",
+ "unified": "9.2.0",
+ "unist-builder": "2.0.3",
+ "unist-util-visit": "2.0.3"
+ },
+ "dependencies": {
+ "remark-mdx": {
+ "version": "1.6.22",
+ "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-1.6.22.tgz",
+ "integrity": "sha512-phMHBJgeV76uyFkH4rvzCftLfKCr2RZuF+/gmVcaKrpsihyzmhXjA0BEMDaPTXG5y8qZOKPVo83NAOX01LPnOQ==",
+ "requires": {
+ "@babel/core": "7.12.9",
+ "@babel/helper-plugin-utils": "7.10.4",
+ "@babel/plugin-proposal-object-rest-spread": "7.12.1",
+ "@babel/plugin-syntax-jsx": "7.12.1",
+ "@mdx-js/util": "1.6.22",
+ "is-alphabetical": "1.0.4",
+ "remark-parse": "8.0.3",
+ "unified": "9.2.0"
+ }
+ }
+ }
+ },
+ "@mdx-js/react": {
+ "version": "1.6.22",
+ "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-1.6.22.tgz",
+ "integrity": "sha512-TDoPum4SHdfPiGSAaRBw7ECyI8VaHpK8GJugbJIJuqyh6kzw9ZLJZW3HGL3NNrJGxcAixUvqROm+YuQOo5eXtg==",
+ "requires": {}
+ },
"ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
@@ -48959,11 +49627,143 @@
"v8-compile-cache": "^2.0.3"
}
},
+ "is-buffer": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz",
+ "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ=="
+ },
+ "is-plain-obj": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
+ "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA=="
+ },
+ "loader-utils": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
+ "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
+ "requires": {
+ "big.js": "^5.2.2",
+ "emojis-list": "^3.0.0",
+ "json5": "^2.1.2"
+ }
+ },
+ "mdast-util-to-hast": {
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-10.0.1.tgz",
+ "integrity": "sha512-BW3LM9SEMnjf4HXXVApZMt8gLQWVNXc3jryK0nJu/rOXPOnlkUjmdkDlmxMirpbU9ILncGFIwLH/ubnWBbcdgA==",
+ "requires": {
+ "@types/mdast": "^3.0.0",
+ "@types/unist": "^2.0.0",
+ "mdast-util-definitions": "^4.0.0",
+ "mdurl": "^1.0.0",
+ "unist-builder": "^2.0.0",
+ "unist-util-generated": "^1.0.0",
+ "unist-util-position": "^3.0.0",
+ "unist-util-visit": "^2.0.0"
+ }
+ },
"mdx-mermaid": {
"version": "2.0.0-rc3",
"resolved": "https://registry.npmjs.org/mdx-mermaid/-/mdx-mermaid-2.0.0-rc3.tgz",
"integrity": "sha512-zshJVTyepNE8Sjrj7Hv1UyDq3UwJVnwKsHGuDBYM4jixsofrC2j9wj2sXQ3PnlryFxLm9pU9ctqiGQgbxYXLjg==",
"requires": {}
+ },
+ "remark-parse": {
+ "version": "8.0.3",
+ "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-8.0.3.tgz",
+ "integrity": "sha512-E1K9+QLGgggHxCQtLt++uXltxEprmWzNfg+MxpfHsZlrddKzZ/hZyWHDbK3/Ap8HJQqYJRXP+jHczdL6q6i85Q==",
+ "requires": {
+ "ccount": "^1.0.0",
+ "collapse-white-space": "^1.0.2",
+ "is-alphabetical": "^1.0.0",
+ "is-decimal": "^1.0.0",
+ "is-whitespace-character": "^1.0.0",
+ "is-word-character": "^1.0.0",
+ "markdown-escapes": "^1.0.0",
+ "parse-entities": "^2.0.0",
+ "repeat-string": "^1.5.4",
+ "state-toggle": "^1.0.0",
+ "trim": "0.0.1",
+ "trim-trailing-lines": "^1.0.0",
+ "unherit": "^1.0.4",
+ "unist-util-remove-position": "^2.0.0",
+ "vfile-location": "^3.0.0",
+ "xtend": "^4.0.1"
+ }
+ },
+ "semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ=="
+ },
+ "unified": {
+ "version": "9.2.0",
+ "resolved": "https://registry.npmjs.org/unified/-/unified-9.2.0.tgz",
+ "integrity": "sha512-vx2Z0vY+a3YoTj8+pttM3tiJHCwY5UFbYdiWrwBEbHmK8pvsPj2rtAX2BFfgXen8T39CJWblWRDT4L5WGXtDdg==",
+ "requires": {
+ "bail": "^1.0.0",
+ "extend": "^3.0.0",
+ "is-buffer": "^2.0.0",
+ "is-plain-obj": "^2.0.0",
+ "trough": "^1.0.0",
+ "vfile": "^4.0.0"
+ }
+ },
+ "unist-builder": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/unist-builder/-/unist-builder-2.0.3.tgz",
+ "integrity": "sha512-f98yt5pnlMWlzP539tPc4grGMsFaQQlP/vM396b00jngsiINumNmsY8rkXjfoi1c6QaM8nQ3vaGDuoKWbe/1Uw=="
+ },
+ "unist-util-generated": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-1.1.6.tgz",
+ "integrity": "sha512-cln2Mm1/CZzN5ttGK7vkoGw+RZ8VcUH6BtGbq98DDtRGquAAOXig1mrBQYelOwMXYS8rK+vZDyyojSjp7JX+Lg=="
+ },
+ "unist-util-remove-position": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-2.0.1.tgz",
+ "integrity": "sha512-fDZsLYIe2uT+oGFnuZmy73K6ZxOPG/Qcm+w7jbEjaFcJgbQ6cqjs/eSPzXhsmGpAsWPkqZM9pYjww5QTn3LHMA==",
+ "requires": {
+ "unist-util-visit": "^2.0.0"
+ }
+ },
+ "unist-util-stringify-position": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz",
+ "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==",
+ "requires": {
+ "@types/unist": "^2.0.2"
+ }
+ },
+ "vfile": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz",
+ "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==",
+ "requires": {
+ "@types/unist": "^2.0.0",
+ "is-buffer": "^2.0.0",
+ "unist-util-stringify-position": "^2.0.0",
+ "vfile-message": "^2.0.0"
+ }
+ },
+ "vfile-location": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-3.2.0.tgz",
+ "integrity": "sha512-aLEIZKv/oxuCDZ8lkJGhuhztf/BW4M+iHdCwglA/eWc+vtuRFJj8EtgceYFX4LRjOhCAAiNHsKGssC6onJ+jbA=="
+ },
+ "vfile-message": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz",
+ "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==",
+ "requires": {
+ "@types/unist": "^2.0.0",
+ "unist-util-stringify-position": "^2.0.0"
+ }
}
}
},
@@ -52455,6 +53255,11 @@
"get-intrinsic": "^1.1.1"
}
},
+ "is-what": {
+ "version": "4.1.7",
+ "resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.7.tgz",
+ "integrity": "sha512-DBVOQNiPKnGMxRMLIYSwERAS5MVY1B7xYiGnpgctsOFvVDz9f9PFXXxMcTOHuoqYp4NK9qFYQaIC1NRRxLMpBQ=="
+ },
"is-whitespace-character": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz",
@@ -57502,6 +58307,11 @@
"split2": "^4.1.0"
}
},
+ "phenomenon": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/phenomenon/-/phenomenon-1.6.0.tgz",
+ "integrity": "sha512-7h9/fjPD3qNlgggzm88cY58l9sudZ6Ey+UmZsizfhtawO6E3srZQXywaNm2lBwT72TbpHYRPy7ytIHeBUD/G0A=="
+ },
"picocolors": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
@@ -61025,6 +61835,11 @@
}
}
},
+ "remove-accents": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.4.2.tgz",
+ "integrity": "sha512-7pXIJqJOq5tFgG1A2Zxti3Ht8jJF337m4sowbuHsW30ZnkQFnDzy9qBNhgzX8ZLW4+UBcXiiR7SwR6pokHsxiA=="
+ },
"remove-trailing-separator": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
@@ -62393,8 +63208,10 @@
"@supabase/postgres-meta": "^0.26.1",
"@supabase/react-data-grid": "^7.1.0-beta.7",
"@supabase/shared-types": "^0.1.29",
- "@supabase/supabase-js": "^2.1.0",
+ "@supabase/supabase-js": "^2.1.1",
"@tailwindcss/typography": "^0.5.2",
+ "@tanstack/react-query": "^4.16.1",
+ "@tanstack/react-query-devtools": "^4.16.1",
"@testing-library/dom": "^8.11.1",
"@testing-library/react": "^12.1.2",
"@testing-library/user-event": "^13.5.0",
@@ -62479,7 +63296,7 @@
"swr": "^1.2.1",
"tailwindcss": "^3.0.22",
"ts-jest": "^27.0.7",
- "typescript": "4.3.4",
+ "typescript": "4.8.4",
"ui": "*",
"uniforms-bootstrap4": "^3.6.2",
"uniforms-bridge-json-schema": "^3.6.2",
@@ -62672,9 +63489,9 @@
"requires": {}
},
"typescript": {
- "version": "4.3.4",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.4.tgz",
- "integrity": "sha512-uauPG7XZn9F/mo+7MrsRjyvbxFpzemRjKEZXS4AK83oP2KKOJPvb+9cO/gmnv8arWZvhnjVOXz7B49m1l0e9Ew==",
+ "version": "4.8.4",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz",
+ "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==",
"dev": true
},
"webpack-bundle-analyzer": {
@@ -62861,6 +63678,14 @@
}
}
},
+ "superjson": {
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/superjson/-/superjson-1.11.0.tgz",
+ "integrity": "sha512-6PfAg1FKhqkwWvPb2uXhH4MkMttdc17eJ91+Aoz4s1XUEDZFmLfFx/xVA3wgkPxAGy5dpozgGdK6V/n20Wj9yg==",
+ "requires": {
+ "copy-anything": "^3.0.2"
+ }
+ },
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -64308,6 +65133,12 @@
"object-assign": "^4.1.1"
}
},
+ "use-sync-external-store": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz",
+ "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==",
+ "requires": {}
+ },
"utf-8-validate": {
"version": "5.0.10",
"resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz",
@@ -64434,6 +65265,11 @@
"spdx-expression-parse": "^3.0.0"
}
},
+ "vanilla-tilt": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/vanilla-tilt/-/vanilla-tilt-1.7.0.tgz",
+ "integrity": "sha512-u9yUhpSasFeqQCuiTon+RSb0aHzcj9stvWVXQIswzKL5oG491lkYk7U1GmhOAEZt7yPT6EiYZRJhIh2MFBncOA=="
+ },
"vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
@@ -65422,6 +66258,7 @@
"@types/react-syntax-highlighter": "^13.5.2",
"autoprefixer": "^10.4.12",
"classnames": "^2.3.1",
+ "cobe": "^0.6.2",
"common": "*",
"config": "*",
"date-fns": "2.10.0",
@@ -65462,6 +66299,7 @@
"ui": "*",
"use-debounce": "^7.0.1",
"uuid": "^8.3.2",
+ "vanilla-tilt": "1.7.0",
"yup": "^0.32.11"
},
"dependencies": {
diff --git a/packages/config/tailwind.config.js b/packages/config/tailwind.config.js
index 47db462a769..0f1c25dbfe3 100644
--- a/packages/config/tailwind.config.js
+++ b/packages/config/tailwind.config.js
@@ -212,7 +212,8 @@ module.exports = ui({
},
},
}),
- // screens: {
+ screens: {
+ xs: '480px'
// sm: '640px',
// // => @media (min-width: 640px) { ... }
// md: '768px',
@@ -223,7 +224,7 @@ module.exports = ui({
// // => @media (min-width: 1280px) { ... }
// '2xl': '1536px',
// // => @media (min-width: 1536px) { ... }
- // },
+ },
// colors: {
// 'gray-light': '#7B7F86',
// 'gray-dark': '#7B7F86',
diff --git a/packages/ui/index.tsx b/packages/ui/index.tsx
index f2d6744f6b1..cc297cf34b9 100644
--- a/packages/ui/index.tsx
+++ b/packages/ui/index.tsx
@@ -40,7 +40,7 @@ export * from './src/components/Popover'
export * from './src/components/Space'
export * from './src/components/Loading'
export * from './src/components/Divider'
-export * from './src/components/ThemeProvider'
+// export * from './src/components/ThemeProvider'
// DATA ENTRY
diff --git a/spec/supabase_dart_v1.yml b/spec/supabase_dart_v1.yml
index 382c76bae08..6f3ef71a653 100644
--- a/spec/supabase_dart_v1.yml
+++ b/spec/supabase_dart_v1.yml
@@ -836,7 +836,6 @@ pages:
description: |
Retrieves the details of all Storage buckets within an existing product.
title: 'listBuckets()'
- $ref: '@supabase/storage-js.packages/StorageBucketApi.default.listBuckets'
notes: |
- Policy permissions required:
- `buckets` permissions: `select`
@@ -855,7 +854,6 @@ pages:
description: |
Retrieves the details of an existing Storage bucket.
title: 'getBucket()'
- $ref: '@supabase/storage-js.packages/StorageBucketApi.default.getBucket'
notes: |
- Policy permissions required:
- `buckets` permissions: `select`
@@ -945,7 +943,6 @@ pages:
description: |
Uploads a file to an existing bucket.
title: 'from.upload()'
- $ref: '@supabase/storage-js.packages/StorageFileApi.default.upload'
notes: |
- Policy permissions required:
- `buckets` permissions: none
@@ -1022,6 +1019,24 @@ pages:
.createSignedUrl('avatar1.png', 60);
```
+ storage.from.createSignedUrls():
+ title: 'from.createSignedUrls()'
+ notes: |
+ - RLS policy permissions required:
+ - `buckets` table permissions: none
+ - `objects` table permissions: `select`
+ - Refer to the [Storage guide](/docs/guides/storage#access-control) on how access control works
+ examples:
+ - name: Create Signed URLs
+ isSpotlight: true
+ dart: |
+ ```dart
+ final List signedUrls = await supabase
+ .storage
+ .from('avatars')
+ .createSignedUrls(['folder/avatar1.png', 'folder/avatar2.png'], 60);
+ ```
+
storage.from.getPublicUrl():
description: |
Retrieve URLs for assets in public buckets
@@ -1671,7 +1686,6 @@ pages:
.lte():
description: |
Finds all rows whose value on the stated `column` is less than or equal to the specified `value`.
- $ref: '@supabase/postgrest-js.PostgrestFilterBuilder.lte'
examples:
- name: With `select()`
isSpotlight: true
@@ -1710,7 +1724,6 @@ pages:
.like():
description: |
Finds all rows whose value in the stated `column` matches the supplied `pattern` (case sensitive).
- $ref: '@supabase/postgrest-js.PostgrestFilterBuilder.lte'
examples:
- name: With `select()`
isSpotlight: true
@@ -2045,7 +2058,6 @@ pages:
```
.rangeLte():
- $ref: '@supabase/postgrest-js.PostgrestFilterBuilder.rangeLte'
examples:
- name: With `select()`
isSpotlight: true
diff --git a/studio/components/interfaces/Billing/AddOns/AddOns.utils.ts b/studio/components/interfaces/Billing/AddOns/AddOns.utils.ts
index d3d559d3abf..4440c0a0f78 100644
--- a/studio/components/interfaces/Billing/AddOns/AddOns.utils.ts
+++ b/studio/components/interfaces/Billing/AddOns/AddOns.utils.ts
@@ -91,3 +91,39 @@ export const formatPITROptions = (addons: DatabaseAddon[]) => {
if (pitrOptions.length === 0) return []
else return [noPITROption].concat(pitrOptions)
}
+
+export const formatCustomDomainOptions = (addons: DatabaseAddon[]) => {
+ const customDomainOrder = ['addon_custom_domains']
+ const noCustomDomainOption: DatabaseAddon = {
+ id: undefined,
+ name: 'Disable Custom Domains',
+ metadata: {
+ default_price_id: undefined,
+ supabase_prod_id: 'addon_custom_domains_disabled',
+ features: '',
+ },
+ prices: [
+ {
+ id: undefined,
+ currency: 'usd',
+ recurring: {
+ interval: 'month',
+ usage_type: 'licensed',
+ interval_count: 1,
+ aggregate_usage: null,
+ trial_period_days: null,
+ },
+ unit_amount: 0,
+ },
+ ],
+ }
+
+ const customDomainOptions = customDomainOrder
+ .map((id: string) => {
+ return addons.find((option) => option.metadata.supabase_prod_id === id)
+ })
+ .filter((option) => option !== undefined) as DatabaseAddon[]
+
+ if (customDomainOptions.length === 0) return []
+ else return [noCustomDomainOption].concat(customDomainOptions)
+}
diff --git a/studio/components/interfaces/Billing/AddOns/CustomDomainSelection.tsx b/studio/components/interfaces/Billing/AddOns/CustomDomainSelection.tsx
new file mode 100644
index 00000000000..a43d9f17f34
--- /dev/null
+++ b/studio/components/interfaces/Billing/AddOns/CustomDomainSelection.tsx
@@ -0,0 +1,70 @@
+import { FC } from 'react'
+import { Badge, Radio } from 'ui'
+
+import { useStore, useFlag } from 'hooks'
+import { getProductPrice } from '../Billing.utils'
+import DisabledWarningDueToIncident from 'components/ui/DisabledWarningDueToIncident'
+
+interface Props {
+ options: any[]
+ currentOption?: any
+ selectedOption: any
+ onSelectOption: (option: any) => void
+}
+
+const CustomDomainSelection: FC = ({
+ options,
+ currentOption,
+ selectedOption,
+ onSelectOption,
+}) => {
+ const addonUpdateDisabled = useFlag('disableProjectCreationAndUpdate')
+ return (
+
+
+
+
Custom Domains
+ Optional
+
+
Present a branded experience to your users
+
+ {addonUpdateDisabled ? (
+
+ ) : (
+
+ {options.map((option: any) => {
+ const defaultPrice = getProductPrice(option)
+ return (
+
+ {option.name}
+ {currentOption?.id === option.id && (
+ Current selection
+ )}
+
+ }
+ // @ts-ignore
+ description={
+
+
{option.metadata.features}
+
+ }
+ value={option.id}
+ optionalLabel={${defaultPrice.unit_amount / 100} / month
}
+ checked={selectedOption?.id === option.id}
+ onChange={() => onSelectOption(option)}
+ />
+ )
+ })}
+
+ )}
+
+ )
+}
+
+export default CustomDomainSelection
diff --git a/studio/components/interfaces/Billing/AddOns/PITRDurationSelection.tsx b/studio/components/interfaces/Billing/AddOns/PITRDurationSelection.tsx
index cf97a169668..ec5ed6bf2a6 100644
--- a/studio/components/interfaces/Billing/AddOns/PITRDurationSelection.tsx
+++ b/studio/components/interfaces/Billing/AddOns/PITRDurationSelection.tsx
@@ -29,7 +29,7 @@ const PITRDurationSelection: FC = ({
const addonUpdateDisabled = useFlag('disableProjectCreationAndUpdate')
// Only projects of version greater than supabase-postgrest-14.1.0.44 can use PITR
- const canUsePITR = getSemanticVersion(ui.selectedProject?.dbVersion ?? '') > 141044
+ const canUsePITR = getSemanticVersion(ui.selectedProject?.dbVersion ?? '') >= 141044
return (
diff --git a/studio/components/interfaces/Billing/Billing.constants.tsx b/studio/components/interfaces/Billing/Billing.constants.tsx
index e246a093ddd..f2ce7ffc943 100644
--- a/studio/components/interfaces/Billing/Billing.constants.tsx
+++ b/studio/components/interfaces/Billing/Billing.constants.tsx
@@ -1,4 +1,4 @@
-import { IconArchive, IconDatabase, IconKey } from 'ui'
+import { IconArchive, IconCode, IconDatabase, IconKey } from 'ui'
export const CANCELLATION_REASONS = [
'Pricing',
@@ -71,4 +71,25 @@ export const USAGE_BASED_PRODUCTS = [
},
],
},
+ {
+ title: 'Functions',
+ icon:
,
+ features: [
+ {
+ key: 'total_func_count',
+ attribute: 'total_func_count',
+ title: 'Function Count',
+ units: 'absolute',
+ costPerUnit: 0.1,
+ },
+
+ {
+ key: 'total_func_invocations',
+ attribute: 'total_func_invocations',
+ title: 'Function Invocations',
+ units: 'absolute',
+ costPerUnit: 0.000002,
+ },
+ ],
+ },
]
diff --git a/studio/components/interfaces/Billing/Billing.utils.ts b/studio/components/interfaces/Billing/Billing.utils.ts
index 2c839e9459a..d6d21a9652f 100644
--- a/studio/components/interfaces/Billing/Billing.utils.ts
+++ b/studio/components/interfaces/Billing/Billing.utils.ts
@@ -1,5 +1,9 @@
import { DatabaseAddon } from './AddOns/AddOns.types'
-import { formatComputeSizes, formatPITROptions } from './AddOns/AddOns.utils'
+import {
+ formatComputeSizes,
+ formatCustomDomainOptions,
+ formatPITROptions,
+} from './AddOns/AddOns.utils'
import { StripeSubscription } from './Subscription/Subscription.types'
export const getProductPrice = (product: any) => {
@@ -11,11 +15,15 @@ export const getProductPrice = (product: any) => {
return price
}
-export const validateSubscriptionUpdatePayload = (
- selectedComputeSize: DatabaseAddon,
- selectedPITRDuration?: DatabaseAddon
-) => {
- if (selectedPITRDuration?.id !== undefined && selectedComputeSize.id === undefined) {
+export const validateSubscriptionUpdatePayload = (selectedAddons: {
+ computeSize: DatabaseAddon
+ pitrDuration: DatabaseAddon
+ customDomains: DatabaseAddon
+}) => {
+ if (
+ selectedAddons.pitrDuration?.id !== undefined &&
+ selectedAddons.computeSize.id === undefined
+ ) {
return 'To enable PITR for your project, your project must minimally be on a Small Add-on.'
}
return undefined
@@ -23,18 +31,24 @@ export const validateSubscriptionUpdatePayload = (
export const formSubscriptionUpdatePayload = (
selectedTier: any,
- selectedComputeSize: DatabaseAddon,
- selectedPITRDuration: DatabaseAddon | undefined,
+ selectedAddons: {
+ computeSize: DatabaseAddon
+ pitrDuration: DatabaseAddon
+ customDomains: DatabaseAddon
+ },
selectedPaymentMethod: string,
region: string
) => {
+ const { computeSize, pitrDuration, customDomains } = selectedAddons
const defaultPrice = selectedTier ? getProductPrice(selectedTier) : undefined
const addons =
region === 'af-south-1'
? []
- : [selectedComputeSize.prices[0].id, selectedPITRDuration?.prices?.[0].id].filter(
- (x) => x !== undefined
- )
+ : [
+ computeSize.prices[0].id,
+ pitrDuration?.prices?.[0].id,
+ customDomains?.prices?.[0].id,
+ ].filter((x) => x !== undefined)
const proration_date = Math.floor(Date.now() / 1000)
return {
...(defaultPrice && { tier: defaultPrice.id }),
@@ -50,8 +64,9 @@ export const getCurrentAddons = (
) => {
const computeSizes = formatComputeSizes(addons)
const pitrDurationOptions = formatPITROptions(addons)
+ const customDomainOptions = formatCustomDomainOptions(addons)
- const currentComputeSize =
+ const computeSize =
computeSizes.find((option: any) => {
const subscriptionComputeSize = currentSubscription?.addons.find((addon) =>
addon.supabase_prod_id.includes('_instance_')
@@ -62,7 +77,7 @@ export const getCurrentAddons = (
(option: any) => option.metadata.supabase_prod_id === 'addon_instance_micro'
) as DatabaseAddon)
- const currentPITRDuration =
+ const pitrDuration =
pitrDurationOptions.find((option: any) => {
const subscriptionComputeSize = currentSubscription?.addons.find((addon) =>
addon.supabase_prod_id.includes('_pitr_')
@@ -73,5 +88,16 @@ export const getCurrentAddons = (
(option: any) => option.metadata.supabase_prod_id === 'addon_pitr_0days'
) as DatabaseAddon)
- return { currentComputeSize, currentPITRDuration }
+ const customDomains =
+ customDomainOptions.find((option: any) => {
+ const subscriptionComputeSize = currentSubscription?.addons.find((addon) =>
+ addon.supabase_prod_id.includes('_custom_domains')
+ )
+ return option.id === subscriptionComputeSize?.prod_id
+ }) ||
+ (customDomainOptions.find(
+ (option: any) => option.metadata.supabase_prod_id === 'addon__custom_domains_disabled'
+ ) as DatabaseAddon)
+
+ return { computeSize, pitrDuration, customDomains }
}
diff --git a/studio/components/interfaces/Billing/EnterpriseUpdate.tsx b/studio/components/interfaces/Billing/EnterpriseUpdate.tsx
index 360c2f96987..504d5931f8a 100644
--- a/studio/components/interfaces/Billing/EnterpriseUpdate.tsx
+++ b/studio/components/interfaces/Billing/EnterpriseUpdate.tsx
@@ -2,14 +2,18 @@ import { FC, useState, useEffect } from 'react'
import { useRouter } from 'next/router'
import { Transition } from '@headlessui/react'
-import { useStore } from 'hooks'
+import { useStore, useFlag } from 'hooks'
import { getURL } from 'lib/helpers'
import { post, patch } from 'lib/common/fetch'
import { API_URL, PROJECT_STATUS } from 'lib/constants'
import Divider from 'components/ui/Divider'
import { DatabaseAddon } from './AddOns/AddOns.types'
-import { formatComputeSizes, formatPITROptions } from './AddOns/AddOns.utils'
+import {
+ formatComputeSizes,
+ formatCustomDomainOptions,
+ formatPITROptions,
+} from './AddOns/AddOns.utils'
import {
AddNewPaymentMethodModal,
ComputeSizeSelection,
@@ -17,6 +21,7 @@ import {
StripeSubscription,
PaymentSummaryPanel,
UpdateSuccess,
+ CustomDomainSelection,
} from './'
import { PaymentMethod, SubscriptionPreview } from './Billing.types'
import { formSubscriptionUpdatePayload, getCurrentAddons } from './Billing.utils'
@@ -36,6 +41,8 @@ const EnterpriseUpdate: FC
= ({
}) => {
const { app, ui } = useStore()
const router = useRouter()
+ const isCustomDomainsEnabled = useFlag('customDomains')
+ const isPITRSelfServeEnabled = useFlag('pitrSelfServe')
const projectId = ui.selectedProject?.id ?? -1
const projectRef = ui.selectedProject?.ref ?? 'default'
@@ -44,12 +51,30 @@ const EnterpriseUpdate: FC = ({
const { addons } = products
const computeSizes = formatComputeSizes(addons)
const pitrDurationOptions = formatPITROptions(addons)
- const { currentComputeSize, currentPITRDuration } = getCurrentAddons(currentSubscription, addons)
+ const customDomainOptions = formatCustomDomainOptions(addons)
+ const currentAddons = getCurrentAddons(currentSubscription, addons)
+
+ // [Joshen TODO] Ideally we just have a state to hold all the add ons selection, rather than individual
+ // Even better if we can just use the
{projectRegion !== 'af-south-1' && (
<>
- {pitrDurationOptions.length > 0 && (
+ {isCustomDomainsEnabled && customDomainOptions.length > 0 && (
+ <>
+
+
+ >
+ )}
+ {isPITRSelfServeEnabled && pitrDurationOptions.length > 0 && (
<>
>
@@ -190,8 +224,8 @@ const EnterpriseUpdate: FC = ({
>
@@ -208,11 +242,9 @@ const EnterpriseUpdate: FC = ({
subscriptionPreview={subscriptionPreview}
// Current subscription configuration based on DB
currentPlan={currentSubscription.tier}
- currentComputeSize={currentComputeSize}
- currentPITRDuration={currentPITRDuration}
+ currentAddons={currentAddons}
// Selected subscription configuration based on UI
- selectedComputeSize={selectedComputeSize}
- selectedPITRDuration={selectedPITRDuration}
+ selectedAddons={selectedAddons}
paymentMethods={paymentMethods}
isLoadingPaymentMethods={isLoadingPaymentMethods}
selectedPaymentMethod={selectedPaymentMethodId}
diff --git a/studio/components/interfaces/Billing/PaymentSummaryPanel/PaymentSummaryPanel.tsx b/studio/components/interfaces/Billing/PaymentSummaryPanel/PaymentSummaryPanel.tsx
index 37f77b19b67..a3134c2629e 100644
--- a/studio/components/interfaces/Billing/PaymentSummaryPanel/PaymentSummaryPanel.tsx
+++ b/studio/components/interfaces/Billing/PaymentSummaryPanel/PaymentSummaryPanel.tsx
@@ -18,12 +18,21 @@ import ConfirmPaymentModal from './ConfirmPaymentModal'
interface Props {
isRefreshingPreview: boolean
subscriptionPreview?: SubscriptionPreview
+
currentPlan: any
- currentComputeSize: DatabaseAddon
- currentPITRDuration: DatabaseAddon | undefined
+ currentAddons: {
+ computeSize: DatabaseAddon
+ pitrDuration: DatabaseAddon
+ customDomains: DatabaseAddon
+ }
+
selectedPlan?: any
- selectedComputeSize: DatabaseAddon
- selectedPITRDuration: DatabaseAddon | undefined
+ selectedAddons: {
+ computeSize: DatabaseAddon
+ pitrDuration: DatabaseAddon
+ customDomains: DatabaseAddon
+ }
+
isSpendCapEnabled: boolean
paymentMethods?: any
selectedPaymentMethod: any
@@ -45,12 +54,13 @@ const PaymentSummaryPanel: FC = ({
isRefreshingPreview,
isSpendCapEnabled,
subscriptionPreview,
+
currentPlan,
- currentComputeSize,
- currentPITRDuration,
+ currentAddons,
+
selectedPlan,
- selectedComputeSize,
- selectedPITRDuration,
+ selectedAddons,
+
paymentMethods,
selectedPaymentMethod,
isLoadingPaymentMethods,
@@ -70,9 +80,10 @@ const PaymentSummaryPanel: FC = ({
const [showConfirmModal, setShowConfirmModal] = useState(false)
- const currentPITRDays = currentPITRDuration !== undefined ? getPITRDays(currentPITRDuration) : 0
+ const currentPITRDays =
+ currentAddons.pitrDuration !== undefined ? getPITRDays(currentAddons.pitrDuration) : 0
const selectedPITRDays =
- selectedPITRDuration !== undefined ? getPITRDays(selectedPITRDuration) : 0
+ selectedAddons.pitrDuration !== undefined ? getPITRDays(selectedAddons.pitrDuration) : 0
const isEnterprise = currentPlan.supabase_prod_id === PRICING_TIER_PRODUCT_IDS.ENTERPRISE
const isChangingPlan =
@@ -81,8 +92,10 @@ const PaymentSummaryPanel: FC = ({
currentPlan.prod_id !== selectedPlan.id) ||
(currentPlan.prod_id !== STRIPE_PRODUCT_IDS.PAYG && !isSpendCapEnabled) ||
(currentPlan.prod_id === STRIPE_PRODUCT_IDS.PAYG && isSpendCapEnabled)
- const isChangingComputeSize = currentComputeSize.id !== selectedComputeSize.id
- const isChangingPITRDuration = currentPITRDuration?.id !== selectedPITRDuration?.id
+ const isChangingComputeSize = currentAddons.computeSize.id !== selectedAddons.computeSize.id
+ const isChangingPITRDuration = currentAddons.pitrDuration?.id !== selectedAddons.pitrDuration?.id
+ const isChangingCustomDomains =
+ currentAddons.customDomains?.id !== selectedAddons.customDomains?.id
// If it's enterprise we only only changing of add-ons
const hasChangesToPlan = isEnterprise
@@ -96,7 +109,7 @@ const PaymentSummaryPanel: FC = ({
}
const validateOrder = () => {
- const error = validateSubscriptionUpdatePayload(selectedComputeSize, selectedPITRDuration)
+ const error = validateSubscriptionUpdatePayload(selectedAddons)
if (error) {
return ui.setNotification({
duration: 4000,
@@ -147,45 +160,71 @@ const PaymentSummaryPanel: FC = ({
- {currentComputeSize.name}
+ {currentAddons.computeSize.name}
- ${(getProductPrice(currentComputeSize).unit_amount / 100).toFixed(2)}
+ ${(getProductPrice(currentAddons.computeSize).unit_amount / 100).toFixed(2)}
{isChangingComputeSize && (
-
{selectedComputeSize.name}
+
{selectedAddons.computeSize.name}
- ${(getProductPrice(selectedComputeSize).unit_amount / 100).toFixed(2)}
+ ${(getProductPrice(selectedAddons.computeSize).unit_amount / 100).toFixed(2)}
)}
- {currentPITRDuration?.id !== undefined && (
+ {currentAddons.pitrDuration?.id !== undefined && (
- {currentPITRDuration?.name}
+ {currentAddons.pitrDuration?.name}
- ${(getProductPrice(currentPITRDuration).unit_amount / 100).toFixed(2)}
+ ${(getProductPrice(currentAddons.pitrDuration).unit_amount / 100).toFixed(2)}
)}
{isChangingPITRDuration && (
-
{selectedPITRDuration?.name}
+
{selectedAddons.pitrDuration?.name}
- ${(getProductPrice(selectedPITRDuration).unit_amount / 100).toFixed(2)}
+ ${(getProductPrice(selectedAddons.pitrDuration).unit_amount / 100).toFixed(2)}
+
+
+ )}
+ {currentAddons.customDomains?.id !== undefined && (
+
+
+ {currentAddons.customDomains?.name}
+
+
+ ${(getProductPrice(currentAddons.customDomains).unit_amount / 100).toFixed(2)}
+
+
+ )}
+ {isChangingCustomDomains && (
+
+
{selectedAddons.customDomains?.name}
+
+ ${(getProductPrice(selectedAddons.customDomains).unit_amount / 100).toFixed(2)}
)}
@@ -198,9 +237,9 @@ const PaymentSummaryPanel: FC = ({
defaultVisibility
icon={ }
title={
- currentPITRDuration?.id === undefined
+ currentAddons.pitrDuration?.id === undefined
? 'Enabling PITR'
- : selectedPITRDuration?.id === undefined
+ : selectedAddons.pitrDuration?.id === undefined
? 'Disabling PITR'
: 'Updating PITR duration'
}
diff --git a/studio/components/interfaces/Billing/ProUpgrade.tsx b/studio/components/interfaces/Billing/ProUpgrade.tsx
index 12fea2c0c3b..5ff559adc1a 100644
--- a/studio/components/interfaces/Billing/ProUpgrade.tsx
+++ b/studio/components/interfaces/Billing/ProUpgrade.tsx
@@ -13,6 +13,7 @@ import {
PaymentSummaryPanel,
ComputeSizeSelection,
PITRDurationSelection,
+ CustomDomainSelection,
StripeSubscription,
AddNewPaymentMethodModal,
} from './'
@@ -21,7 +22,11 @@ import UpdateSuccess from './UpdateSuccess'
import { PaymentMethod, SubscriptionPreview } from './Billing.types'
import { formSubscriptionUpdatePayload, getCurrentAddons } from './Billing.utils'
import { DatabaseAddon } from './AddOns/AddOns.types'
-import { formatComputeSizes, formatPITROptions } from './AddOns/AddOns.utils'
+import {
+ formatComputeSizes,
+ formatCustomDomainOptions,
+ formatPITROptions,
+} from './AddOns/AddOns.utils'
import BackButton from 'components/ui/BackButton'
// Do not allow compute size changes for af-south-1
@@ -43,12 +48,14 @@ const ProUpgrade: FC = ({
}) => {
const { app, ui } = useStore()
const router = useRouter()
+ const isCustomDomainsEnabled = useFlag('customDomains')
const isPITRSelfServeEnabled = useFlag('pitrSelfServe')
const { addons } = products
const computeSizes = formatComputeSizes(addons)
const pitrDurationOptions = formatPITROptions(addons)
- const { currentComputeSize, currentPITRDuration } = getCurrentAddons(currentSubscription, addons)
+ const customDomainOptions = formatCustomDomainOptions(addons)
+ const currentAddons = getCurrentAddons(currentSubscription, addons)
const projectId = ui.selectedProject?.id ?? -1
const projectRef = ui.selectedProject?.ref
@@ -67,10 +74,27 @@ const ProUpgrade: FC = ({
const [showAddPaymentMethodModal, setShowAddPaymentMethodModal] = useState(false)
const [showSpendCapHelperModal, setShowSpendCapHelperModal] = useState(false)
+ // [Joshen TODO] Ideally we just have a state to hold all the add ons selection, rather than individual
+ // Even better if we can just use the
+ )
+}
+
+export default observer(CustomDomainsConfigureHostname)
diff --git a/studio/components/interfaces/Settings/General/CustomDomainConfig/CustomDomainsShimmerLoader.tsx b/studio/components/interfaces/Settings/General/CustomDomainConfig/CustomDomainsShimmerLoader.tsx
new file mode 100644
index 00000000000..3caaa3b1b2c
--- /dev/null
+++ b/studio/components/interfaces/Settings/General/CustomDomainConfig/CustomDomainsShimmerLoader.tsx
@@ -0,0 +1,15 @@
+const CustomDomainsShimmerLoader = () => {
+ return (
+
+ )
+}
+
+export default CustomDomainsShimmerLoader
diff --git a/studio/components/interfaces/Settings/General/CustomDomainConfig/DNSRecord.tsx b/studio/components/interfaces/Settings/General/CustomDomainConfig/DNSRecord.tsx
new file mode 100644
index 00000000000..9541c0abf9d
--- /dev/null
+++ b/studio/components/interfaces/Settings/General/CustomDomainConfig/DNSRecord.tsx
@@ -0,0 +1,21 @@
+import { Input } from 'ui'
+
+export type DNSRecordProps = {
+ type: string
+ name: string
+ value: string
+}
+
+const DNSRecord = ({ type, name, value }: DNSRecordProps) => {
+ return (
+
+ )
+}
+
+export default DNSRecord
diff --git a/studio/components/interfaces/Settings/General/DeleteProjectPanel/DeleteProjectPanel.tsx b/studio/components/interfaces/Settings/General/DeleteProjectPanel/DeleteProjectPanel.tsx
index b5bdafb317d..4c8c7267fdb 100644
--- a/studio/components/interfaces/Settings/General/DeleteProjectPanel/DeleteProjectPanel.tsx
+++ b/studio/components/interfaces/Settings/General/DeleteProjectPanel/DeleteProjectPanel.tsx
@@ -5,6 +5,7 @@ import { useStore } from 'hooks'
import Panel from 'components/ui/Panel'
import DeleteProjectButton from './DeleteProjectButton'
+import { FormHeader } from 'components/ui/Forms'
interface Props {}
@@ -16,7 +17,8 @@ const DeleteProjectPanel: FC = ({}) => {
return (
- Danger Zone}>
+
+
= ({ projectRef }) => {
/>
) : (
- {feature.units === 'bytes' ? formatBytes(usageValue) : ''}
+ {feature.units === 'bytes'
+ ? formatBytes(usageValue)
+ : usageValue}
)}
diff --git a/studio/components/interfaces/SignIn/SignInWithSSO.tsx b/studio/components/interfaces/SignIn/SignInWithSSO.tsx
index c81ce30af43..913aafb6500 100644
--- a/studio/components/interfaces/SignIn/SignInWithSSO.tsx
+++ b/studio/components/interfaces/SignIn/SignInWithSSO.tsx
@@ -1,12 +1,14 @@
import Link from 'next/link'
-import { Button } from 'ui'
+import { Button, IconLock } from 'ui'
const SignInWithSSO = () => {
return (
-
- Continue with SSO
-
+
+ }>
+ Continue with SSO
+
+
)
}
diff --git a/studio/components/interfaces/Support/SupportForm.tsx b/studio/components/interfaces/Support/SupportForm.tsx
index deea91401d2..f0dbaf22e0a 100644
--- a/studio/components/interfaces/Support/SupportForm.tsx
+++ b/studio/components/interfaces/Support/SupportForm.tsx
@@ -455,8 +455,8 @@ const SupportForm: FC = ({ setSentCategory }) => {
id="message"
label="Message"
placeholder="Describe the issue you're facing, along with any relevant information. Please be as detailed and specific as possible."
- limit={500}
- labelOptional="500 character limit"
+ limit={5000}
+ labelOptional="5000 character limit"
/>
diff --git a/studio/components/interfaces/TableGridEditor/SidePanelEditor/ColumnEditor/ColumnType.tsx b/studio/components/interfaces/TableGridEditor/SidePanelEditor/ColumnEditor/ColumnType.tsx
index 33ba1198cc3..a31f97e92ac 100644
--- a/studio/components/interfaces/TableGridEditor/SidePanelEditor/ColumnEditor/ColumnType.tsx
+++ b/studio/components/interfaces/TableGridEditor/SidePanelEditor/ColumnEditor/ColumnType.tsx
@@ -37,7 +37,9 @@ const ColumnType: FC
= ({
readOnly
disabled
label={showLabel ? 'Type' : ''}
- layout="horizontal"
+ layout={showLabel ? 'horizontal' : undefined}
+ className="md:gap-x-0"
+ size="small"
value={value}
descriptionText={
showLabel
diff --git a/studio/components/layouts/ProjectLayout/LayoutHeader/LayoutHeader.tsx b/studio/components/layouts/ProjectLayout/LayoutHeader/LayoutHeader.tsx
index a218a446c35..ebca922f3e1 100644
--- a/studio/components/layouts/ProjectLayout/LayoutHeader/LayoutHeader.tsx
+++ b/studio/components/layouts/ProjectLayout/LayoutHeader/LayoutHeader.tsx
@@ -63,7 +63,9 @@ const LayoutHeader = ({ customHeaderComponents, breadcrumbs = [], headerBorder =
{/* Project Dropdown */}
- {showOverUsageBadge && (
+
+ {/* [Joshen TODO] Temporarily hidden until usage endpoint is sorted out */}
+ {/* {showOverUsageBadge && (
- )}
+ )} */}
>
)}
>
diff --git a/studio/components/to-be-cleaned/Docs/Snippets.js b/studio/components/to-be-cleaned/Docs/Snippets.js
index 6e4995dc0a8..955409e15bb 100644
--- a/studio/components/to-be-cleaned/Docs/Snippets.js
+++ b/studio/components/to-be-cleaned/Docs/Snippets.js
@@ -366,7 +366,7 @@ curl -X POST '${endpoint}/rest/v1/${resourceId}' \\
-H "apikey: ${apiKey}" \\
-H "Authorization: Bearer ${apiKey}" \\
-H "Content-Type: application/json" \\
--H "Prefer: return=representation" \\
+-H "Prefer: return=minimal" \\
-d '{ "some_column": "someValue", "other_column": "otherValue" }'
`,
},
@@ -436,7 +436,7 @@ curl -X PATCH '${endpoint}/rest/v1/${resourceId}?some_column=eq.someValue' \\
-H "apikey: ${apiKey}" \\
-H "Authorization: Bearer ${apiKey}" \\
-H "Content-Type: application/json" \\
--H "Prefer: return=representation" \\
+-H "Prefer: return=minimal" \\
-d '{ "other_column": "otherValue" }'
`,
},
diff --git a/studio/components/to-be-cleaned/Storage/StorageSettings/StorageSettings.tsx b/studio/components/to-be-cleaned/Storage/StorageSettings/StorageSettings.tsx
index 6f78c2dd369..be80781933a 100644
--- a/studio/components/to-be-cleaned/Storage/StorageSettings/StorageSettings.tsx
+++ b/studio/components/to-be-cleaned/Storage/StorageSettings/StorageSettings.tsx
@@ -1,6 +1,6 @@
import useSWR from 'swr'
import { FC, useState } from 'react'
-import { Button, Form, Input, Listbox } from 'ui'
+import { Button, Form, IconClock, Input, Listbox } from 'ui'
import { useStore } from 'hooks'
import { patch, get } from 'lib/common/fetch'
@@ -173,6 +173,7 @@ const StorageConfig = ({ config, projectRef }: any) => {
{isFreeTier && (
}
primaryText="Free Plan has a fixed upload file size limit of 50 MB."
projectRef={projectRef}
secondaryText="Please upgrade to Pro plan for a configurable upload file size limit of up to 5 GB."
diff --git a/studio/components/ui/Dialogs/ConfirmDialog.js b/studio/components/ui/Dialogs/ConfirmDialog.js
index c9f8d79ee45..33e4df18d70 100644
--- a/studio/components/ui/Dialogs/ConfirmDialog.js
+++ b/studio/components/ui/Dialogs/ConfirmDialog.js
@@ -56,13 +56,20 @@ const ConfirmModal = ({
-
+
Cancel
{buttonLoadingLabel && loading
diff --git a/studio/components/ui/Forms/FormActions.tsx b/studio/components/ui/Forms/FormActions.tsx
index ff5806e0802..d5f4789ceac 100644
--- a/studio/components/ui/Forms/FormActions.tsx
+++ b/studio/components/ui/Forms/FormActions.tsx
@@ -7,6 +7,7 @@ interface Props {
helper?: React.ReactNode // Helper text to show alongside actions
disabled?: boolean
isSubmitting?: boolean
+ submitText?: string
}
const FormActions = ({
@@ -16,6 +17,7 @@ const FormActions = ({
helper,
disabled = false,
isSubmitting,
+ submitText = 'Save',
}: Props) => {
const isDisabled = isSubmitting || disabled || (!hasChanges && hasChanges !== undefined)
@@ -39,7 +41,7 @@ const FormActions = ({
disabled={isDisabled}
loading={isSubmitting}
>
- Save
+ {submitText}
diff --git a/studio/components/ui/UpgradeToPro.tsx b/studio/components/ui/UpgradeToPro.tsx
index 0266397cfdb..0dd4d6e3b46 100644
--- a/studio/components/ui/UpgradeToPro.tsx
+++ b/studio/components/ui/UpgradeToPro.tsx
@@ -1,38 +1,49 @@
-import { Button, IconClock } from 'ui'
+import { Button } from 'ui'
+import { observer } from 'mobx-react-lite'
import Link from 'next/link'
-import { FC } from 'react'
+import { FC, ReactNode } from 'react'
+import { useStore } from 'hooks'
+import { PRICING_TIER_PRODUCT_IDS } from 'lib/constants'
interface Props {
+ icon?: ReactNode
primaryText: string
projectRef: string
secondaryText: string
}
-const UpgradeToPro: FC = ({ primaryText, projectRef, secondaryText }) => (
-
-
-
-
-
-
-
-
{primaryText}
-
-
{secondaryText}
+const UpgradeToPro: FC
= ({ icon, primaryText, projectRef, secondaryText }) => {
+ const { ui } = useStore()
+ const tier = ui.selectedProject?.subscription_tier
+
+ return (
+
+
+ {icon &&
{icon}
}
+
-
-
Upgrade to Pro
-
-
-)
+ )
+}
-export default UpgradeToPro
+export default observer(UpgradeToPro)
diff --git a/studio/data/config/keys.ts b/studio/data/config/keys.ts
new file mode 100644
index 00000000000..875848a4247
--- /dev/null
+++ b/studio/data/config/keys.ts
@@ -0,0 +1,3 @@
+export const configKeys = {
+ settings: (projectRef: string | undefined) => ['projects', projectRef, 'settings'] as const,
+}
diff --git a/studio/data/config/project-settings-query.ts b/studio/data/config/project-settings-query.ts
new file mode 100644
index 00000000000..ad473e32e38
--- /dev/null
+++ b/studio/data/config/project-settings-query.ts
@@ -0,0 +1,122 @@
+import { useQuery, useQueryClient, UseQueryOptions } from '@tanstack/react-query'
+import { get } from 'lib/common/fetch'
+import { API_URL } from 'lib/constants'
+import { useCallback } from 'react'
+import { configKeys } from './keys'
+
+export type ProjectSettingsVariables = {
+ projectRef?: string
+}
+
+export type Project = {
+ id: number
+ name: string
+ ref: string
+ status: string
+ db_host: string
+ db_name: string
+ db_user: string
+ db_schema: string
+ db_port: number
+ db_ssl: boolean
+ services: Service[]
+}
+
+export type App = {
+ id: number
+ name: string
+}
+
+export type AppConfig = {
+ endpoint: string
+ db_schema: string
+ realtime_multitenant_enabled: boolean
+}
+
+export type Service = {
+ id: number
+ name: string
+ app_config: AppConfig
+ app: App
+ service_api_keys: ServiceApiKey[]
+}
+
+export type ServiceApiKey = {
+ api_key_encrypted: string
+ tags: string
+ name: string
+}
+
+export type AutoApiService = Service & {
+ endpoint: string
+ restUrl: string
+ project: Project
+ defaultApiKey: string
+ serviceApiKey: string
+}
+
+export type ProjectSettingsResponse = {
+ project: Project
+ autoApiService: AutoApiService
+}
+
+export async function getProjectSettings(
+ { projectRef }: ProjectSettingsVariables,
+ signal?: AbortSignal
+) {
+ if (!projectRef) {
+ throw new Error('projectRef is required')
+ }
+
+ const response = await get(`${API_URL}/props/project/${projectRef}/api`, {
+ signal,
+ })
+ if (response.error) {
+ throw response.error
+ }
+
+ return response as ProjectSettingsResponse
+}
+
+export type ProjectSettingsData = Awaited
>
+export type ProjectSettingsError = unknown
+
+export const useProjectSettingsQuery = (
+ { projectRef }: ProjectSettingsVariables,
+ {
+ enabled = true,
+ ...options
+ }: UseQueryOptions = {}
+) =>
+ useQuery(
+ configKeys.settings(projectRef),
+ ({ signal }) => getProjectSettings({ projectRef }, signal),
+ {
+ enabled: enabled && typeof projectRef !== 'undefined',
+ refetchInterval(data, query) {
+ if (!data) {
+ return false
+ }
+
+ const { autoApiService } = data as unknown as ProjectSettingsData
+
+ const apiKeys = autoApiService?.service_api_keys ?? []
+ const interval = apiKeys.length === 0 ? 2000 : 0
+
+ return interval
+ },
+ ...options,
+ }
+ )
+
+export const useProjectSettingsPrefetch = ({ projectRef }: ProjectSettingsVariables) => {
+ const client = useQueryClient()
+
+ return useCallback(() => {
+ if (projectRef) {
+ client.prefetchQuery(configKeys.settings(projectRef), ({ signal }) =>
+ getProjectSettings({ projectRef }, signal)
+ )
+ }
+ }, [projectRef])
+}
diff --git a/studio/data/custom-domains/custom-domains-activate-mutation.ts b/studio/data/custom-domains/custom-domains-activate-mutation.ts
new file mode 100644
index 00000000000..2fc29e5d231
--- /dev/null
+++ b/studio/data/custom-domains/custom-domains-activate-mutation.ts
@@ -0,0 +1,49 @@
+import { useMutation, UseMutationOptions, useQueryClient } from '@tanstack/react-query'
+import { post } from 'lib/common/fetch'
+import { customDomainKeys } from './keys'
+
+export type CustomDomainActivateVariables = {
+ projectRef: string
+}
+
+export async function activateCustomDomain({ projectRef }: CustomDomainActivateVariables) {
+ if (!projectRef) {
+ throw new Error('projectRef is required')
+ }
+
+ const response = await post(
+ `${process.env.NEXT_PUBLIC_API_ADMIN_URL}/projects/${projectRef}/custom-hostname/activate`,
+ {}
+ )
+ if (response.error) {
+ throw response.error
+ }
+
+ return response
+}
+
+type CustomDomainActivateData = Awaited>
+
+export const useCustomDomainActivateMutation = ({
+ onSuccess,
+ ...options
+}: Omit<
+ UseMutationOptions,
+ 'mutationFn'
+> = {}) => {
+ const queryClient = useQueryClient()
+
+ return useMutation(
+ (vars) => activateCustomDomain(vars),
+ {
+ async onSuccess(data, variables, context) {
+ const { projectRef } = variables
+
+ await queryClient.invalidateQueries(customDomainKeys.list(projectRef))
+
+ await onSuccess?.(data, variables, context)
+ },
+ ...options,
+ }
+ )
+}
diff --git a/studio/data/custom-domains/custom-domains-create-mutation.ts b/studio/data/custom-domains/custom-domains-create-mutation.ts
new file mode 100644
index 00000000000..689ed60af47
--- /dev/null
+++ b/studio/data/custom-domains/custom-domains-create-mutation.ts
@@ -0,0 +1,55 @@
+import { useMutation, UseMutationOptions, useQueryClient } from '@tanstack/react-query'
+import { post } from 'lib/common/fetch'
+import { customDomainKeys } from './keys'
+
+export type CustomDomainCreateVariables = {
+ projectRef: string
+ customDomain: string
+}
+
+export async function createCustomDomain({
+ projectRef,
+ customDomain,
+}: CustomDomainCreateVariables) {
+ if (!projectRef) {
+ throw new Error('projectRef is required')
+ }
+
+ const response = await post(
+ `${process.env.NEXT_PUBLIC_API_ADMIN_URL}/projects/${projectRef}/custom-hostname/initialize`,
+ {
+ custom_hostname: customDomain,
+ }
+ )
+ if (response.error) {
+ throw response.error
+ }
+
+ return response
+}
+
+type CustomDomainCreateData = Awaited>
+
+export const useCustomDomainCreateMutation = ({
+ onSuccess,
+ ...options
+}: Omit<
+ UseMutationOptions,
+ 'mutationFn'
+> = {}) => {
+ const queryClient = useQueryClient()
+
+ return useMutation(
+ (vars) => createCustomDomain(vars),
+ {
+ async onSuccess(data, variables, context) {
+ const { projectRef } = variables
+
+ await queryClient.invalidateQueries(customDomainKeys.list(projectRef))
+
+ await onSuccess?.(data, variables, context)
+ },
+ ...options,
+ }
+ )
+}
diff --git a/studio/data/custom-domains/custom-domains-delete-mutation.ts b/studio/data/custom-domains/custom-domains-delete-mutation.ts
new file mode 100644
index 00000000000..014ce571e4d
--- /dev/null
+++ b/studio/data/custom-domains/custom-domains-delete-mutation.ts
@@ -0,0 +1,58 @@
+import { useMutation, UseMutationOptions, useQueryClient } from '@tanstack/react-query'
+import { delete_ } from 'lib/common/fetch'
+import { getCustomDomains } from './custom-domains-query'
+import { customDomainKeys } from './keys'
+
+export type CustomDomainDeleteVariables = {
+ projectRef: string
+}
+
+export async function deleteCustomDomain({ projectRef }: CustomDomainDeleteVariables) {
+ if (!projectRef) {
+ throw new Error('projectRef is required')
+ }
+
+ const response = await delete_(
+ `${process.env.NEXT_PUBLIC_API_ADMIN_URL}/projects/${projectRef}/custom-hostname`,
+ {}
+ )
+ if (response.error) {
+ throw response.error
+ }
+
+ return response
+}
+
+type CustomDomainDeleteData = Awaited>
+
+export const useCustomDomainDeleteMutation = ({
+ onSuccess,
+ ...options
+}: Omit<
+ UseMutationOptions,
+ 'mutationFn'
+> = {}) => {
+ const queryClient = useQueryClient()
+
+ return useMutation(
+ (vars) => deleteCustomDomain(vars),
+ {
+ async onSuccess(data, variables, context) {
+ const { projectRef } = variables
+
+ // we manually setQueriesData here instead of using
+ // the standard invalidateQueries is the custom domains
+ // endpoint doesn't immediately return the new state
+ queryClient.setQueriesData(customDomainKeys.list(projectRef), () => {
+ return {
+ customDomain: null,
+ status: '0_no_hostname_configured',
+ }
+ })
+
+ await onSuccess?.(data, variables, context)
+ },
+ ...options,
+ }
+ )
+}
diff --git a/studio/data/custom-domains/custom-domains-query.ts b/studio/data/custom-domains/custom-domains-query.ts
new file mode 100644
index 00000000000..645f756b8be
--- /dev/null
+++ b/studio/data/custom-domains/custom-domains-query.ts
@@ -0,0 +1,147 @@
+import { useQuery, useQueryClient, UseQueryOptions } from '@tanstack/react-query'
+import { get } from 'lib/common/fetch'
+import { useCallback } from 'react'
+import { customDomainKeys } from './keys'
+
+export type CustomDomainsVariables = {
+ projectRef?: string
+}
+
+type CustomDomainStatus =
+ | '0_not_allowed'
+ | '0_no_hostname_configured'
+ | '1_not_started'
+ | '2_initiated'
+ | '3_challenge_verified'
+ | '4_origin_setup_completed'
+ | '5_services_reconfigured'
+
+type Settings = {
+ http2: string
+ tls_1_3: string
+ min_tls_version: string
+}
+
+type Ssl = {
+ id: string
+ type: string
+ method: string
+ status: string
+ txt_name?: string
+ txt_value?: string
+ settings: Settings
+ wildcard: boolean
+ bundle_method: string
+ certificate_authority: string
+ validation_records?: {
+ status: string
+ txt_name: string
+ txt_value: string
+ }[]
+}
+
+type OwnershipVerification = {
+ name: string
+ type: string
+ value: string
+}
+
+type OwnershipVerificationHttp = {
+ http_url: string
+ http_body: string
+}
+
+export type CustomDomainResponse = {
+ id: string
+ ssl: Ssl
+ status: string
+ hostname: string
+ created_at: string
+ custom_metadata: any
+ verification_errors?: string[]
+ custom_origin_server: string
+ ownership_verification?: OwnershipVerification
+ ownership_verification_http?: OwnershipVerificationHttp
+}
+
+export async function getCustomDomains(
+ { projectRef }: CustomDomainsVariables,
+ signal?: AbortSignal
+) {
+ if (!projectRef) {
+ throw new Error('projectRef is required')
+ }
+
+ const response = (await get(
+ `${process.env.NEXT_PUBLIC_API_ADMIN_URL}/projects/${projectRef}/custom-hostname`,
+ {
+ signal,
+ }
+ )) as {
+ data: {
+ errors: any[]
+ result: CustomDomainResponse
+ success: boolean
+ messages: any[]
+ }
+ status: CustomDomainStatus
+ error: unknown
+ }
+
+ if (response.error) {
+ // not allowed error and no hostname configured error are
+ // valid steps in the process of setting up a custom domain
+ // so we convert them to data instead of errors
+
+ const isNotAllowedError =
+ (response.error as any)?.code === 400 &&
+ (response.error as any)?.message?.includes('not allowed to set up custom domain')
+
+ if (isNotAllowedError) {
+ return {
+ customDomain: null,
+ status: '0_not_allowed',
+ } as const
+ }
+
+ const isNoHostnameConfiguredError =
+ (response.error as any)?.code === 400 &&
+ (response.error as any)?.message?.includes('custom hostname configuration')
+
+ if (isNoHostnameConfiguredError) {
+ return {
+ customDomain: null,
+ status: '0_no_hostname_configured',
+ } as const
+ }
+
+ throw response.error
+ }
+
+ return { customDomain: response?.data?.result, status: response.status }
+}
+
+export type CustomDomainsData = Awaited>
+export type CustomDomainsError = unknown
+
+export const useCustomDomainsQuery = (
+ { projectRef }: CustomDomainsVariables,
+ { enabled = true, ...options }: UseQueryOptions = {}
+) =>
+ useQuery(
+ customDomainKeys.list(projectRef),
+ ({ signal }) => getCustomDomains({ projectRef }, signal),
+ { enabled: enabled && typeof projectRef !== 'undefined', ...options }
+ )
+
+export const useCustomDomainsPrefetch = ({ projectRef }: CustomDomainsVariables) => {
+ const client = useQueryClient()
+
+ return useCallback(() => {
+ if (projectRef) {
+ client.prefetchQuery(customDomainKeys.list(projectRef), ({ signal }) =>
+ getCustomDomains({ projectRef }, signal)
+ )
+ }
+ }, [projectRef])
+}
diff --git a/studio/data/custom-domains/custom-domains-reverify-mutation.ts b/studio/data/custom-domains/custom-domains-reverify-mutation.ts
new file mode 100644
index 00000000000..8b7e2c8c671
--- /dev/null
+++ b/studio/data/custom-domains/custom-domains-reverify-mutation.ts
@@ -0,0 +1,49 @@
+import { useMutation, UseMutationOptions, useQueryClient } from '@tanstack/react-query'
+import { post } from 'lib/common/fetch'
+import { customDomainKeys } from './keys'
+
+export type CustomDomainReverifyVariables = {
+ projectRef: string
+}
+
+export async function reverifyCustomDomain({ projectRef }: CustomDomainReverifyVariables) {
+ if (!projectRef) {
+ throw new Error('projectRef is required')
+ }
+
+ const response = await post(
+ `${process.env.NEXT_PUBLIC_API_ADMIN_URL}/projects/${projectRef}/custom-hostname/reverify`,
+ {}
+ )
+ if (response.error) {
+ throw response.error
+ }
+
+ return response
+}
+
+type CustomDomainReverifyData = Awaited>
+
+export const useCustomDomainReverifyMutation = ({
+ onSuccess,
+ ...options
+}: Omit<
+ UseMutationOptions,
+ 'mutationFn'
+> = {}) => {
+ const queryClient = useQueryClient()
+
+ return useMutation(
+ (vars) => reverifyCustomDomain(vars),
+ {
+ async onSuccess(data, variables, context) {
+ const { projectRef } = variables
+
+ await queryClient.invalidateQueries(customDomainKeys.list(projectRef))
+
+ await onSuccess?.(data, variables, context)
+ },
+ ...options,
+ }
+ )
+}
diff --git a/studio/data/custom-domains/keys.ts b/studio/data/custom-domains/keys.ts
new file mode 100644
index 00000000000..e63bfeb67ca
--- /dev/null
+++ b/studio/data/custom-domains/keys.ts
@@ -0,0 +1,3 @@
+export const customDomainKeys = {
+ list: (projectRef: string | undefined) => ['projects', projectRef, 'custom-domains'] as const,
+}
diff --git a/studio/data/query-client.ts b/studio/data/query-client.ts
new file mode 100644
index 00000000000..ee9ce6f2522
--- /dev/null
+++ b/studio/data/query-client.ts
@@ -0,0 +1,21 @@
+import { QueryClient } from '@tanstack/react-query'
+import { useState } from 'react'
+
+let queryClient: QueryClient | undefined
+
+export function getQueryClient() {
+ const _queryClient = queryClient ?? new QueryClient()
+
+ // For SSG and SSR always create a new queryClient
+ if (typeof window === 'undefined') return _queryClient
+ // Create the queryClient once in the client
+ if (!queryClient) queryClient = _queryClient
+
+ return queryClient
+}
+
+export function useRootQueryClient() {
+ const [_queryClient] = useState(() => getQueryClient())
+
+ return _queryClient
+}
diff --git a/studio/lib/constants/metrics.tsx b/studio/lib/constants/metrics.tsx
index 14b79718a50..796925abace 100644
--- a/studio/lib/constants/metrics.tsx
+++ b/studio/lib/constants/metrics.tsx
@@ -144,6 +144,13 @@ export const METRICS = [
// provider: 'daily-stats',
// category: METRIC_CATEGORIES.API_AUTH,
// },
+
+ {
+ key: 'total_auth_billing_period_mau',
+ label: 'Auth Monthly Active User',
+ provider: 'daily-stats',
+ category: METRIC_CATEGORIES.API_AUTH,
+ },
{
key: 'total_auth_ingress',
label: 'Auth Ingress',
diff --git a/studio/package.json b/studio/package.json
index 21bae821867..ac126783233 100644
--- a/studio/package.json
+++ b/studio/package.json
@@ -28,7 +28,9 @@
"@supabase/postgres-meta": "^0.26.1",
"@supabase/react-data-grid": "^7.1.0-beta.7",
"@supabase/shared-types": "^0.1.29",
- "@supabase/supabase-js": "^2.1.0",
+ "@supabase/supabase-js": "^2.1.1",
+ "@tanstack/react-query": "^4.16.1",
+ "@tanstack/react-query-devtools": "^4.16.1",
"ajv": "^8.6.3",
"analytics-node": "^3.5.0",
"awesome-debounce-promise": "^2.1.0",
@@ -132,6 +134,6 @@
"storybook-dark-mode": "^1.0.4",
"tailwindcss": "^3.0.22",
"ts-jest": "^27.0.7",
- "typescript": "4.3.4"
+ "typescript": "4.8.4"
}
}
diff --git a/studio/pages/_app.tsx b/studio/pages/_app.tsx
index 358300caca2..7272e752b9f 100644
--- a/studio/pages/_app.tsx
+++ b/studio/pages/_app.tsx
@@ -24,11 +24,14 @@ import Head from 'next/head'
import { AppPropsWithLayout } from 'types'
import { useEffect, useState } from 'react'
+import { Hydrate, QueryClientProvider } from '@tanstack/react-query'
+import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
import { RootStore } from 'stores'
import { StoreProvider } from 'hooks'
import { GOTRUE_ERRORS } from 'lib/constants'
import { auth } from 'lib/gotrue'
import { dart } from 'lib/constants/prism'
+import { useRootQueryClient } from 'data/query-client'
import { PortalToast, RouteValidationWrapper, AppBannerWrapper } from 'components/interfaces/App'
import PageTelemetry from 'components/ui/PageTelemetry'
@@ -42,6 +45,7 @@ dayjs.extend(timezone)
dart(Prism)
function MyApp({ Component, pageProps }: AppPropsWithLayout) {
+ const queryClient = useRootQueryClient()
const [rootStore] = useState(() => new RootStore())
useEffect(() => {
@@ -96,21 +100,28 @@ function MyApp({ Component, pageProps }: AppPropsWithLayout) {
const getLayout = Component.getLayout ?? ((page) => page)
return (
-
-
-
- Supabase
-
-
-
-
-
- {getLayout( )}
-
-
-
-
-
+
+
+
+
+
+ Supabase
+
+
+
+
+
+
+ {getLayout( )}
+
+
+
+
+
+
+
+
+
)
}
export default MyApp
diff --git a/studio/pages/project/[ref]/database/backups/pitr.tsx b/studio/pages/project/[ref]/database/backups/pitr.tsx
index c0e74fcb7c9..2d0468532e2 100644
--- a/studio/pages/project/[ref]/database/backups/pitr.tsx
+++ b/studio/pages/project/[ref]/database/backups/pitr.tsx
@@ -13,6 +13,7 @@ import InformationBox from 'components/ui/InformationBox'
import UpgradeToPro from 'components/ui/UpgradeToPro'
import { PITRNotice, PITRSelection } from 'components/interfaces/Database/Backups/PITR'
import BackupsError from 'components/interfaces/Database/Backups/BackupsError'
+import { PRICING_TIER_PRODUCT_IDS } from 'lib/constants'
const DatabasePhysicalBackups: NextPageWithLayout = () => {
const { ui } = useStore()
@@ -51,6 +52,7 @@ const PITR = () => {
const { configuration, error, isLoading } = backups
const ref = ui.selectedProject?.ref ?? 'default'
+ const tier = ui.selectedProject?.subscription_tier
const isEnabled = configuration.walg_enabled
const isPITRSelfServeEnabled = useFlag('pitrSelfServe')
@@ -63,8 +65,12 @@ const PITR = () => {
return isPITRSelfServeEnabled ? (
) : (
{
- {projectTier !== undefined && }
+ {/* [Joshen TODO] Temporarily hidden until usage endpoint is sorted out */}
+ {/* {projectTier !== undefined && } */}
{project?.status === PROJECT_STATUS.INACTIVE &&
}
diff --git a/studio/pages/project/[ref]/settings/api.tsx b/studio/pages/project/[ref]/settings/api.tsx
index 15224b86f1e..63af221d05f 100644
--- a/studio/pages/project/[ref]/settings/api.tsx
+++ b/studio/pages/project/[ref]/settings/api.tsx
@@ -6,7 +6,6 @@ import { useStore } from 'hooks'
import { NextPageWithLayout } from 'types'
import { SettingsLayout } from 'components/layouts'
import ServiceList from 'components/interfaces/Settings/API/ServiceList'
-import { FormsContainer } from 'components/ui/Forms'
export const PageContext: any = createContext(null)
diff --git a/studio/pages/project/[ref]/settings/billing/invoices.tsx b/studio/pages/project/[ref]/settings/billing/invoices.tsx
index 29c76ba8d21..45481e4ff1b 100644
--- a/studio/pages/project/[ref]/settings/billing/invoices.tsx
+++ b/studio/pages/project/[ref]/settings/billing/invoices.tsx
@@ -57,7 +57,8 @@ const Settings: FC
= ({ project }) => {
return (
- {projectTier !== undefined &&
}
+ {/* [Joshen TODO] Temporarily hidden until usage endpoint is sorted out */}
+ {/* {projectTier !== undefined &&
} */}
Invoices
diff --git a/studio/pages/project/[ref]/settings/billing/subscription.tsx b/studio/pages/project/[ref]/settings/billing/subscription.tsx
index 34a925b6079..9744f34e911 100644
--- a/studio/pages/project/[ref]/settings/billing/subscription.tsx
+++ b/studio/pages/project/[ref]/settings/billing/subscription.tsx
@@ -58,7 +58,8 @@ const Settings: FC
= ({ project }) => {
return (
- {projectTier !== undefined &&
}
+ {/* [Joshen TODO] Temporarily hidden until usage endpoint is sorted out */}
+ {/* {projectTier !== undefined &&
} */}
{
+ const isCustomDomainsEnabled = useFlag('customDomains')
+
return (
+ {isCustomDomainsEnabled && }
)
diff --git a/studio/pages/sign-in.tsx b/studio/pages/sign-in.tsx
index d3b3b19b5ce..8080d2550e1 100644
--- a/studio/pages/sign-in.tsx
+++ b/studio/pages/sign-in.tsx
@@ -1,15 +1,20 @@
+import Link from 'next/link'
+
+import { useFlag } from 'hooks'
+import { NextPageWithLayout } from 'types'
import SignInForm from 'components/interfaces/SignIn/SignInForm'
import SignInWithGitHub from 'components/interfaces/SignIn/SignInWithGitHub'
+import SignInWithSSO from 'components/interfaces/SignIn/SignInWithSSO'
import { SignInLayout } from 'components/layouts'
-import Link from 'next/link'
-import { NextPageWithLayout } from 'types'
const SignInPage: NextPageWithLayout = () => {
+ const showSsoLogin = useFlag('mfaSso')
+
return (
<>
- {/*
*/}
+ {showSsoLogin &&
}