From 3562f9697df22d34258a9fc79a227a8749d94e00 Mon Sep 17 00:00:00 2001 From: Francesco Sansalvadore Date: Wed, 12 Apr 2023 19:38:18 +0200 Subject: [PATCH 01/55] feat: finish highlighting active toc label in blog post --- apps/www/components/Blog/BlogListItem.tsx | 9 +++++---- apps/www/hooks/useActiveAnchors.tsx | 14 ++++++++++---- apps/www/lib/helpers.tsx | 9 +++++++++ apps/www/pages/blog/[slug].tsx | 6 +++--- apps/www/public/rss.xml | 13 ++++++++++--- apps/www/styles/index.css | 3 +-- 6 files changed, 38 insertions(+), 16 deletions(-) diff --git a/apps/www/components/Blog/BlogListItem.tsx b/apps/www/components/Blog/BlogListItem.tsx index c08b5006db7..423c6b077be 100644 --- a/apps/www/components/Blog/BlogListItem.tsx +++ b/apps/www/components/Blog/BlogListItem.tsx @@ -1,5 +1,6 @@ import authors from 'lib/authors.json' import Image from 'next/image' +import Link from 'next/link' import React from 'react' import Author from '~/types/author' import PostTypes from '~/types/post' @@ -24,8 +25,8 @@ const BlogListItem = ({ post }: Props) => { return (
- -
+ +
{ })}
-
-
+ +
) } diff --git a/apps/www/hooks/useActiveAnchors.tsx b/apps/www/hooks/useActiveAnchors.tsx index 00a48824387..d02509c147c 100644 --- a/apps/www/hooks/useActiveAnchors.tsx +++ b/apps/www/hooks/useActiveAnchors.tsx @@ -1,10 +1,13 @@ +import { useRouter } from 'next/router' import { useEffect, useRef } from 'react' +import { isBrowser, stripEmojis } from '~/lib/helpers' const useActiveAnchors = ( anchorsQuerySelector: string = 'h2', tocQuerySelector: string = '.prose-toc a', offset: number = 200 ) => { + const router = useRouter() const anchors = useRef | null>(null) const toc = useRef | null>(null) @@ -20,10 +23,12 @@ const useActiveAnchors = ( toc.current?.forEach((link) => { link.classList.remove('toc-animate') - // TODO: escape emojis - // The problem is that MDXRemote strips out emojis on slugs - // but ReactMarkdown doesn't,instead it encodes them - const sanitizedHref = (link.getAttribute('href') ?? '').replace('#', '') + + // Need to decodeURI the href to get emojis, then strip them off and remove "--"" + // to make toc hrefs and content headings ids match + const sanitizedHref = stripEmojis( + decodeURI(link.getAttribute('href') ?? '').replace('#', '') + ).replace('--', '-') const isMatch = sanitizedHref === newActiveAnchor if (isMatch) { @@ -33,6 +38,7 @@ const useActiveAnchors = ( } useEffect(() => { + if (!isBrowser) return anchors.current = document.querySelectorAll(anchorsQuerySelector) toc.current = document.querySelectorAll(tocQuerySelector) diff --git a/apps/www/lib/helpers.tsx b/apps/www/lib/helpers.tsx index fbf8fe599dd..eb8495ca624 100644 --- a/apps/www/lib/helpers.tsx +++ b/apps/www/lib/helpers.tsx @@ -31,3 +31,12 @@ export const toPixels = (value: string | number) => { } export const isBrowser = typeof window !== 'undefined' + +export const stripEmojis = (str: string) => + str + .replace( + /([\u2700-\u27BF]|[\uE000-\uF8FF]|\uD83C[\uDC00-\uDFFF]|\uD83D[\uDC00-\uDFFF]|[\u2011-\u26FF]|\uD83E[\uDD10-\uDDFF])/g, + '' + ) + .replace(/\s+/g, ' ') + .trim() diff --git a/apps/www/pages/blog/[slug].tsx b/apps/www/pages/blog/[slug].tsx index 58eea27ee2b..27a7b28b2a2 100644 --- a/apps/www/pages/blog/[slug].tsx +++ b/apps/www/pages/blog/[slug].tsx @@ -12,7 +12,7 @@ import DefaultLayout from '~/components/Layouts/Default' import BlogLinks from '~/components/LaunchWeek/7/BlogLinks' import { generateReadingTime } from '~/lib/helpers' import ShareArticleActions from '~/components/Blog/ShareArticleActions' -// import useActiveAnchors from '~/hooks/useActiveAnchors' +import useActiveAnchors from '~/hooks/useActiveAnchors' import mdxComponents from '~/lib/mdx/mdxComponents' import { mdxSerialize } from '~/lib/mdx/mdxSerialize' import { getAllPostSlugs, getPostdata, getSortedPosts } from '~/lib/posts' @@ -56,9 +56,9 @@ export async function getStaticProps({ params }: any) { relatedPosts, blog: { slug: `${params.slug}`, - content: mdxSource, source: content, ...data, + content: mdxSource, toc: toc(content, { maxdepth: data.toc_depth ? data.toc_depth : 2 }), }, }, @@ -68,7 +68,7 @@ export async function getStaticProps({ params }: any) { function BlogPostPage(props: any) { const content = props.blog.content const authorArray = props.blog.author.split(',') - // useActiveAnchors('h2, h3, h4') + useActiveAnchors('h2, h3, h4', '.prose-toc a') const isLaunchWeek7 = props.blog.launchweek === 7 const author = [] diff --git a/apps/www/public/rss.xml b/apps/www/public/rss.xml index c8bcd42038e..ca327cabe0f 100644 --- a/apps/www/public/rss.xml +++ b/apps/www/public/rss.xml @@ -5,12 +5,19 @@ https://supabase.com Latest news from Supabase en - Mon, 10 Apr 2023 22:10:00 +0000 + Tue, 11 Apr 2023 22:10:00 +0000 - https://supabase.com/blog/edge-runtime-self-hosted-deno + https://supabase.com/blog/storage-v3-resumable-uploads + Supabase Storage v3: Resumable Uploads with support for 50GB files + https://supabase.com/blog/storage-v3-resumable-uploads + undefined + Tue, 11 Apr 2023 22:10:00 +0000 + + + https://supabase.com/blog/edge-runtime-self-hosted-deno-functions Supabase Edge Runtime: Self-hosted Deno Functions - https://supabase.com/blog/edge-runtime-self-hosted-deno + https://supabase.com/blog/edge-runtime-self-hosted-deno-functions undefined Mon, 10 Apr 2023 22:10:00 +0000 diff --git a/apps/www/styles/index.css b/apps/www/styles/index.css index 15de303b62c..916a53c1eb2 100644 --- a/apps/www/styles/index.css +++ b/apps/www/styles/index.css @@ -85,8 +85,7 @@ h6:not(.overwrite) { } .toc-animate { - transform: translate3d(3px, 0, 0) !important; - color: hsla(153, 60%, 53%, 1) !important; + @apply !translate-x-1 !text-brand-900; } .prose-toc a { From a2554df451ea4feb14f47aa9c41f9b58dc9f2607 Mon Sep 17 00:00:00 2001 From: Francesco Sansalvadore Date: Wed, 12 Apr 2023 20:13:05 +0200 Subject: [PATCH 02/55] feat: update Quote mdx component --- apps/www/components/Quote.tsx | 15 ++++++++++----- apps/www/styles/index.css | 7 +++++++ 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/apps/www/components/Quote.tsx b/apps/www/components/Quote.tsx index f55e82ac291..c20e1adcd0e 100644 --- a/apps/www/components/Quote.tsx +++ b/apps/www/components/Quote.tsx @@ -11,12 +11,17 @@ export default function Quote(props: Props) { const { children, caption, img } = props return ( -
-
-
+
+
+

{children} -

- +

+ {caption && img && ( +
+ +
+ )} +
) diff --git a/apps/www/styles/index.css b/apps/www/styles/index.css index 916a53c1eb2..711070a73fb 100644 --- a/apps/www/styles/index.css +++ b/apps/www/styles/index.css @@ -92,6 +92,13 @@ h6:not(.overwrite) { transition: all 0.07s ease-in-out; } +.quote-figure p:first-child { + margin-top: 0 !important; +} +.quote-figure p:last-child { + margin-bottom: 0 !important; +} + @media only screen and (max-width: 960px) { .h1:not(.prose *):not(.overwrite) { font-size: 2.2rem !important; From ef313c4114117624efb5ddeb9aa6ddd47542e5ec Mon Sep 17 00:00:00 2001 From: Francesco Sansalvadore Date: Thu, 13 Apr 2023 10:20:41 +0200 Subject: [PATCH 03/55] feat: style for wide mdx images --- apps/www/styles/index.css | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/apps/www/styles/index.css b/apps/www/styles/index.css index 711070a73fb..0b9958c6353 100644 --- a/apps/www/styles/index.css +++ b/apps/www/styles/index.css @@ -251,9 +251,34 @@ table { * */ .next-image--dynamic-fill { + display: block; width: 100%; + border-radius: 6px; + overflow: hidden; grid-column: 1 / -1; } +.next-image--dynamic-fill.wide { + @apply my-0 max-w-none -mx-8 w-[calc(100%_+_4rem)]; +} +@media (min-width: 560px) { + .next-image--dynamic-fill.wide { + width: calc(100% + 6rem); + margin: 0 -3rem; + } +} +@media (min-width: 1280px) { + .next-image--dynamic-fill.wide { + width: calc(100% + 10rem); + margin: 0 -5rem; + } +} +@media (min-width: 1535px) { + .next-image--dynamic-fill.wide { + width: calc(100% + 14rem); + margin: 0 -7rem; + } +} + .next-image--dynamic-fill > span { position: relative !important; } From ecb592ee9329fadf13fffa934264796bdb053af3 Mon Sep 17 00:00:00 2001 From: Francesco Sansalvadore Date: Thu, 13 Apr 2023 11:21:32 +0200 Subject: [PATCH 04/55] chore: add mdx Img component --- apps/www/lib/mdx/mdxComponents.tsx | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/apps/www/lib/mdx/mdxComponents.tsx b/apps/www/lib/mdx/mdxComponents.tsx index a54bee5c0ad..e08739ca7bb 100644 --- a/apps/www/lib/mdx/mdxComponents.tsx +++ b/apps/www/lib/mdx/mdxComponents.tsx @@ -12,6 +12,18 @@ import { Badge } from 'ui' const ignoreClass = 'ignore-on-export' +const getCaptionAlign = (align?: 'left' | 'center' | 'right') => { + switch (align) { + case 'left': + return 'text-left' + case 'right': + return 'text-right' + case 'center': + default: + return 'text-center' + } +} + export default function mdxComponents(type?: 'blog' | 'lp' | undefined) { const components = { CodeBlock, @@ -43,6 +55,22 @@ export default function mdxComponents(type?: 'blog' | 'lp' | undefined) { } return }, + Img: (props: any) => ( +
+ + + + {props.caption && ( +
+ {props.caption} +
+ )} +
+ ), code: (props: any) => {props.children}, } From f1ecdf1ec1c26fe91db05c75f2e84b05a7c425c3 Mon Sep 17 00:00:00 2001 From: Francesco Sansalvadore Date: Thu, 13 Apr 2023 11:30:56 +0200 Subject: [PATCH 05/55] chore: add example wide image --- apps/www/_blog/2023-04-07-designing-with-ai-midjourney.mdx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/www/_blog/2023-04-07-designing-with-ai-midjourney.mdx b/apps/www/_blog/2023-04-07-designing-with-ai-midjourney.mdx index 2a82e547dce..d3952629f74 100644 --- a/apps/www/_blog/2023-04-07-designing-with-ai-midjourney.mdx +++ b/apps/www/_blog/2023-04-07-designing-with-ai-midjourney.mdx @@ -33,7 +33,11 @@ After exploring a variety of text prompts, blends, and styles, we decided that m After what-seemed-like hours (okay, just a few), we were able to generate some interesting artwork that could be useful. We chose purple hues and simpler swirls - minimalist visuals that could serve as backgrounds for our tickets and landing page. -![midjourney variations](/images/blog/launch-week-7/designing-with-ai-midjourney/midjourney-variations.png) + ### Chasing Gold Behind the Scenes From ca014d9fb31c35a3097c942173886e2d2b24e129 Mon Sep 17 00:00:00 2001 From: Francesco Sansalvadore Date: Thu, 13 Apr 2023 11:33:50 +0200 Subject: [PATCH 06/55] fix: toc active on page refresh --- apps/www/hooks/useActiveAnchors.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/www/hooks/useActiveAnchors.tsx b/apps/www/hooks/useActiveAnchors.tsx index d02509c147c..9ef2a5309e0 100644 --- a/apps/www/hooks/useActiveAnchors.tsx +++ b/apps/www/hooks/useActiveAnchors.tsx @@ -38,7 +38,7 @@ const useActiveAnchors = ( } useEffect(() => { - if (!isBrowser) return + if (!isBrowser || !router.isReady) return anchors.current = document.querySelectorAll(anchorsQuerySelector) toc.current = document.querySelectorAll(tocQuerySelector) @@ -47,7 +47,7 @@ const useActiveAnchors = ( return () => { window.removeEventListener('scroll', handleScroll) } - }, []) + }, [router]) return null } From 95d615d69b4a6159a04f440bc3f6df23d05b4dfc Mon Sep 17 00:00:00 2001 From: Francesco Sansalvadore Date: Thu, 13 Apr 2023 11:38:10 +0200 Subject: [PATCH 07/55] chore: update Quote component --- apps/www/components/Quote.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/www/components/Quote.tsx b/apps/www/components/Quote.tsx index c20e1adcd0e..b643f54f0c5 100644 --- a/apps/www/components/Quote.tsx +++ b/apps/www/components/Quote.tsx @@ -21,7 +21,7 @@ export default function Quote(props: Props) {
)} -
+
) From e3f2c6794ea85cb4175ee77ae3c95491227fe133 Mon Sep 17 00:00:00 2001 From: Terry Sutton Date: Thu, 13 Apr 2023 10:44:51 -0230 Subject: [PATCH 08/55] keyboard nav for list items --- .../Command/GenerateSQL/GenerateSQL.tsx | 61 ++++++++++++++----- 1 file changed, 46 insertions(+), 15 deletions(-) diff --git a/packages/ui/src/components/Command/GenerateSQL/GenerateSQL.tsx b/packages/ui/src/components/Command/GenerateSQL/GenerateSQL.tsx index bd018484210..0f50c348df9 100644 --- a/packages/ui/src/components/Command/GenerateSQL/GenerateSQL.tsx +++ b/packages/ui/src/components/Command/GenerateSQL/GenerateSQL.tsx @@ -1,3 +1,4 @@ +import React from 'react' import { format } from 'sql-formatter' import { useCallback, useEffect, useRef, useState } from 'react' import { @@ -79,6 +80,15 @@ const GenerateSQL = () => { } } + const handleKeypress = (e, category) => { + //it triggers by pressing the enter key + if (e.keyCode === 13) { + setSelectedCategory(category) + // focus on the first item in the list after selecting a category + const firstItem = document.querySelector('.command-menu-item') + } + } + return (
e.stopPropagation()}>
{
    {SAMPLE_QUERIES.map((item, index) => ( -
  • setSelectedCategory(item.category)} - className={cn( - 'px-4 py-1 cursor-pointer text-sm hover:bg-slate-300 rounded-md', - selectedCategory === item.category && 'bg-slate-400 ' - )} - > - {item.category} +
  • +
  • ))}
@@ -194,23 +207,41 @@ const GenerateSQL = () => {
    {SAMPLE_QUERIES.find((item) => item.category === selectedCategory)?.queries.map( (query, index) => ( - { + + // { + // if (!search) { + // handleSubmit(query) + // } + // }} + // forceMount + // key={query.replace(/\s+/g, '_')} + // > + //
    + //
    + // + //
    + //

    + // + //

    + //
    + //
    ) )}
From 3fb913fb49326975c76a8e0b210d3ac57244c4d6 Mon Sep 17 00:00:00 2001 From: Tyler <18113850+dshukertjr@users.noreply.github.com> Date: Thu, 13 Apr 2023 22:21:24 +0900 Subject: [PATCH 09/55] Update 2023-04-07-launch-week-7-hackathon.mdx --- apps/www/_blog/2023-04-07-launch-week-7-hackathon.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/www/_blog/2023-04-07-launch-week-7-hackathon.mdx b/apps/www/_blog/2023-04-07-launch-week-7-hackathon.mdx index de89693f3be..8ea19a22a51 100644 --- a/apps/www/_blog/2023-04-07-launch-week-7-hackathon.mdx +++ b/apps/www/_blog/2023-04-07-launch-week-7-hackathon.mdx @@ -14,7 +14,7 @@ toc_depth: 2 With Easter just around the corner, [Launch Week](https://supabase.com/launch-week) is about to start and, as usual, we're running an async hackathon alongside it. This time it’s AI-themed! -The hackathon starts **now** and ends Monday 16th April at 11:59 pm. You can win extremely limited edition Launch Week themed mechanical keyboards and limited edition Supabase swag. +The hackathon starts **now** and ends Sunday 16th April at 11:59 pm. You can win extremely limited edition Launch Week themed mechanical keyboards and limited edition Supabase swag. For some inspiration check out the [Next.js OpenAI Doc Search template](https://github.com/supabase-community/nextjs-openai-doc-search?og=v2) released yesterday and [storing embeddings on Supabase article](https://supabase.com/blog/openai-embeddings-postgres-vector). From 860de1f43d02973ee14f6ed266e25d3eb83c626c Mon Sep 17 00:00:00 2001 From: Francesco Sansalvadore Date: Thu, 13 Apr 2023 15:31:50 +0200 Subject: [PATCH 10/55] fix: ignore all dashes in anchor matching --- apps/www/hooks/useActiveAnchors.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/www/hooks/useActiveAnchors.tsx b/apps/www/hooks/useActiveAnchors.tsx index 9ef2a5309e0..8dd569c6f5f 100644 --- a/apps/www/hooks/useActiveAnchors.tsx +++ b/apps/www/hooks/useActiveAnchors.tsx @@ -28,8 +28,8 @@ const useActiveAnchors = ( // to make toc hrefs and content headings ids match const sanitizedHref = stripEmojis( decodeURI(link.getAttribute('href') ?? '').replace('#', '') - ).replace('--', '-') - const isMatch = sanitizedHref === newActiveAnchor + ).replaceAll('-', '') + const isMatch = sanitizedHref === newActiveAnchor.replaceAll('-', '') if (isMatch) { link.classList.add('toc-animate') From 8dfcbdedaf65d07e554dcd75d80078549c894d17 Mon Sep 17 00:00:00 2001 From: Kang Ming Date: Thu, 13 Apr 2023 21:45:36 +0800 Subject: [PATCH 11/55] update auth blog --- apps/www/_blog/2023-04-13-supabase-auth-sso-pkce.mdx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/www/_blog/2023-04-13-supabase-auth-sso-pkce.mdx b/apps/www/_blog/2023-04-13-supabase-auth-sso-pkce.mdx index e5755476a8d..600c8d00f68 100644 --- a/apps/www/_blog/2023-04-13-supabase-auth-sso-pkce.mdx +++ b/apps/www/_blog/2023-04-13-supabase-auth-sso-pkce.mdx @@ -13,8 +13,9 @@ thumb: launch-week-7/day-4-supabase-auth-sso-pkce/supabase-auth-sso-pkce-og.jpg Today we're excited to announce a few new features for Supabase Auth: -1. Easily add Single Sign-On support to your projects using SAML 2.0. -2. Better support for server-side rendering and mobile apps using PKCE. +1. [Easily add Single Sign-On support to your projects using SAML 2.0](/blog/supabase-auth-sso-pkce#single-sign-on-support-using-saml-20) +2. [Better support for server-side rendering and mobile apps using PKCE](/blog/supabase-auth-sso-pkce#server-side-and-mobile-auth) +3. [Native Apple login on iOS](/blog/supabase-auth-sso-pkce#native-apple-login-on-ios) ## Single Sign-On Support using SAML 2.0 @@ -71,7 +72,7 @@ For example, you can use Row Level Security (RLS) to build multi-tenant applicat ```sql create policy "Only allow read-write access to tenants" on tablename as restrictive to authenticated using ( - tenant_id = (auth.jwt () - > 'app_metadata' - > > 'provider') + tenant_id = (auth.jwt () -> 'app_metadata' ->> 'provider') ); ``` From 4955b6fc6b6b750611d0854d1d15d0fcdcd8140b Mon Sep 17 00:00:00 2001 From: Francesco Sansalvadore Date: Thu, 13 Apr 2023 15:52:29 +0200 Subject: [PATCH 12/55] add py to Quote component --- apps/www/components/Quote.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/www/components/Quote.tsx b/apps/www/components/Quote.tsx index b643f54f0c5..2c1b1bcc48d 100644 --- a/apps/www/components/Quote.tsx +++ b/apps/www/components/Quote.tsx @@ -12,7 +12,7 @@ export default function Quote(props: Props) { return (
-
+

{children}

From 093b4db48e2bf43a59696e33c539c72be6f2a13e Mon Sep 17 00:00:00 2001 From: Terry Sutton Date: Thu, 13 Apr 2023 11:52:26 -0230 Subject: [PATCH 13/55] Add tabs and key nav to the examples page --- .../ui/src/components/Command/AiCommand.tsx | 1 + .../components/Command/Command.constants.ts | 14 +-- .../Command/GenerateSQL/GenerateSQL.tsx | 98 +++++++------------ 3 files changed, 42 insertions(+), 71 deletions(-) diff --git a/packages/ui/src/components/Command/AiCommand.tsx b/packages/ui/src/components/Command/AiCommand.tsx index 5e816dd7d53..ec6a4638ab5 100644 --- a/packages/ui/src/components/Command/AiCommand.tsx +++ b/packages/ui/src/components/Command/AiCommand.tsx @@ -1,3 +1,4 @@ +import React from 'react' import type { ChatCompletionResponseMessage, CreateChatCompletionResponse, diff --git a/packages/ui/src/components/Command/Command.constants.ts b/packages/ui/src/components/Command/Command.constants.ts index c2fcfee925a..0acab15843d 100644 --- a/packages/ui/src/components/Command/Command.constants.ts +++ b/packages/ui/src/components/Command/Command.constants.ts @@ -17,7 +17,7 @@ type SampleQueries = QueryCategory[] export const SAMPLE_QUERIES: SampleQueries = [ { - category: 'Create tables', + category: 'Tables', queries: [ 'Create a table that stores a list of cities, and insert 10 rows of sample data into it', 'Create tables (with foreign key relationships) for blog posts and comments', @@ -25,7 +25,7 @@ export const SAMPLE_QUERIES: SampleQueries = [ ], }, { - category: 'Create views', + category: 'Views', queries: [ 'Create a view that shows the total revenue for each customer', 'Create a view that shows all orders that were placed in the last week', @@ -34,7 +34,7 @@ export const SAMPLE_QUERIES: SampleQueries = [ ], }, { - category: 'Create indexes', + category: 'Indexes', queries: [ 'Create an index on the primary key column of my orders table', 'Create a partial index on the orders table:', @@ -42,7 +42,7 @@ export const SAMPLE_QUERIES: SampleQueries = [ ], }, { - category: 'Select data', + category: 'Select', queries: [ 'Retrieve a list of employees from the employees table who have a salary greater than $50,000', 'Retrieve a list of all employees with the title "Manager" from the employees table', @@ -51,7 +51,7 @@ export const SAMPLE_QUERIES: SampleQueries = [ ], }, { - category: 'Create triggers', + category: 'Triggers', queries: [ 'Create a trigger that updates the updated_at column on the orders table with the current time when the row of the orders table is updated', 'Create a trigger to add a new user to the users table when someone new registers', @@ -60,7 +60,7 @@ export const SAMPLE_QUERIES: SampleQueries = [ ], }, { - category: 'Row level security', + category: 'Row Level Security', queries: [ 'Create an RLS policy that grants only authenticated access to the profiles table', 'Create an RLS policy that grants SELECT access to the sales_rep role for the customers table, but denies access to all other roles', @@ -68,7 +68,7 @@ export const SAMPLE_QUERIES: SampleQueries = [ ], }, { - category: 'Postgres functions', + category: 'Functions', queries: [ "Create a function to add a new entry to a user's table when a new user signs up", 'Create an a function to calculate the average price of a product in a given category', diff --git a/packages/ui/src/components/Command/GenerateSQL/GenerateSQL.tsx b/packages/ui/src/components/Command/GenerateSQL/GenerateSQL.tsx index 0f50c348df9..7d89aba5bed 100644 --- a/packages/ui/src/components/Command/GenerateSQL/GenerateSQL.tsx +++ b/packages/ui/src/components/Command/GenerateSQL/GenerateSQL.tsx @@ -12,6 +12,7 @@ import { MessageRole, MessageStatus, useAiChat, + Tabs, } from 'ui' import { cn } from '../../../utils/cn' @@ -174,78 +175,47 @@ const GenerateSQL = () => { {messages.length === 0 && !hasError && (
-
-

+
+

Describe what you need and Supabase AI will try to generate the relevant SQL statements

- Here are some example prompts to try out. + Here are some example prompts to try out:

-
-
-
    - {SAMPLE_QUERIES.map((item, index) => ( -
  • - -
  • - ))} -
-
-
-
    - {SAMPLE_QUERIES.find((item) => item.category === selectedCategory)?.queries.map( - (query, index) => ( - - // { - // if (!search) { - // handleSubmit(query) - // } - // }} - // forceMount - // key={query.replace(/\s+/g, '_')} - // > - //
    - //
    - // - //
    - //

    - // - //

    - //
    - //
    - ) - )} -
-
+ + ) + )} + + ))} +

)} From ae6585d5e1ef0aa160b335262f95767436630e6c Mon Sep 17 00:00:00 2001 From: Terry Sutton Date: Thu, 13 Apr 2023 12:03:14 -0230 Subject: [PATCH 14/55] Remove unused fn --- .../src/components/Command/GenerateSQL/GenerateSQL.tsx | 9 --------- 1 file changed, 9 deletions(-) diff --git a/packages/ui/src/components/Command/GenerateSQL/GenerateSQL.tsx b/packages/ui/src/components/Command/GenerateSQL/GenerateSQL.tsx index 7d89aba5bed..9c42c3e717d 100644 --- a/packages/ui/src/components/Command/GenerateSQL/GenerateSQL.tsx +++ b/packages/ui/src/components/Command/GenerateSQL/GenerateSQL.tsx @@ -81,15 +81,6 @@ const GenerateSQL = () => { } } - const handleKeypress = (e, category) => { - //it triggers by pressing the enter key - if (e.keyCode === 13) { - setSelectedCategory(category) - // focus on the first item in the list after selecting a category - const firstItem = document.querySelector('.command-menu-item') - } - } - return (
e.stopPropagation()}>
Date: Thu, 13 Apr 2023 23:35:49 +0900 Subject: [PATCH 15/55] add Dart Edge guide --- .../guides/functions/examples/dart-edge.mdx | 192 ++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 apps/docs/pages/guides/functions/examples/dart-edge.mdx diff --git a/apps/docs/pages/guides/functions/examples/dart-edge.mdx b/apps/docs/pages/guides/functions/examples/dart-edge.mdx new file mode 100644 index 00000000000..ef0dcff01dd --- /dev/null +++ b/apps/docs/pages/guides/functions/examples/dart-edge.mdx @@ -0,0 +1,192 @@ +import Layout from '~/layouts/DefaultGuideLayout' + +export const meta = { + id: 'examples-dart-edge', + title: 'Dart Edge', + description: 'Write your functions using Dart.', +} + +[Dart Edge](https://docs.dartedge.dev/) is a project that enables Dart code to be run on different edge environments built by [Invertase](https://invertase.io/). This guide will walk you through how you can start using Dart Edge to write your backend code using Dart and run it on Supabase. + +> ⚠️ WARNING: Dart Edge is an experimental project - it's probably not ready for production usage unless you're okay with living on the 'edge'. + +## **Pre requirements** + +Make sure you have [the edge CLI](https://docs.dartedge.dev/#getting-started) installed in addition to [the Supabase CLI](https://supabase.com/docs/guides/cli#installation). + +```bash +# install the edge CLI +dart pub global activate edge +``` + +## **Setting up your first Dart Edge project** + +Create a new Dart Edge project using the `new` command on the edge CLI. This will create a familiar boilerplate for your Dart Edge project such as `main.dart` and `pubspec.yaml` file. + +```bash +edge new supabase_functions new_project +``` + +`cd` into the project and initialize a new Supabase project inside the project you just created. + +```bash +cd new_project +supabase init +``` + +Run `pub get` to install the dependencies. + +```bash +dart pub get +``` + +Open the `lib/main.dart` and look at the initial template. + +```dart +void main() { + SupabaseFunctions(fetch: (request) { + return Response("Hello from Supabase Edge Functions!"); + }); +} +``` + +`SupabaseFunctions` class has a `fetch` handler, which is expected to return a `Response` object, and has a `request` parameter, which contains information about the request such as body and headers. + +## Using Supabase Client + +Now let’s try to interact with our Supabase database. We will start by installing the dependencies. + +### Add dependencies + +Add [supabase](https://pub.dev/packages/supabase) to interact with Supabase service. + +```bash +dart pub add supabase +``` + +We also need to use a special HTTP client to HTTP requests in the edge environment. + +```bash +dart pub add edge_http_client +``` + +We also need to add the `yet_another_json_isolate` package, which is the JSON encoder/decoder that utilizes isolate. + +```bash +dart pub add yet_another_json_isolate +``` + +### Override the JSON isolate + +Since isolates are not supported in the edge, we have to override its behavior to handle JSON serialization using the main thread. + +```dart +import 'package:yet_another_json_isolate/yet_another_json_isolate.dart'; + +class EdgeIsolate implements YAJsonIsolate { + @override + Future decode(String json) { + return Future.value(jsonDecode(json)); + } + + @override + Future dispose() async {} + + @override + Future encode(Object? json) { + return Future.value(jsonEncode(json)); + } + + @override + Future initialize() async {} +} +``` + +### Initialize SupabaseClient + +At this point, you can initialize a `SupabaseClient` by passing the [EdgeHttpClient](https://pub.dev/packages/edge_http_client) and the `EdgeIsolate`. We can access the Supabase credentials through the [environment variables](https://supabase.com/docs/guides/functions/secrets) using `Deno.env.get()` method. Note that [Supabase credentials are available by default](https://supabase.com/docs/guides/functions/secrets), so no configurations are necessary. + +Combining the isolates we overrode earlier, we have the following sample functions code to query Supabase database using the Supabase client. + +```dart +import 'dart:convert'; + +import 'package:supabase_functions/supabase_functions.dart'; +import 'package:edge_http_client/edge_http_client.dart'; +import 'package:supabase/supabase.dart'; +import 'package:yet_another_json_isolate/yet_another_json_isolate.dart'; + +void main() { + final supabase = SupabaseClient( + Deno.env.get('SUPABASE_URL')!, + Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!, // Use service role key to bypass RLS + httpClient: EdgeHttpClient(), + isolate: EdgeIsolate(), + ); + + SupabaseFunctions(fetch: (request) async { + // You can query `public.users` table for example. + final List users = await supabase.from('users').select().limit(10); + return Response.json(users); + }); +} + +class EdgeIsolate implements YAJsonIsolate { + @override + Future decode(String json) { + return Future.value(jsonDecode(json)); + } + + @override + Future dispose() async {} + + @override + Future encode(Object? json) { + return Future.value(jsonEncode(json)); + } + + @override + Future initialize() async {} +} +``` + +## Run the Functions + +### Run locally + +Run the following command to compile your Dart code. This command will start a watcher that will recompile anytime you make changes to your code. + +```bash +edge build supabase_functions --dev +``` + +With docker running, start your local Supabase with the following command + +```bash +supabase start +``` + +While you have the above code running, open another terminal and run the following to start the Supabase local development environment. + +```bash +supabase functions serve dart_edge --no-verify-jwt +``` + +You should be able to access your local function here: + +[http://localhost:54321/functions/v1/dart_edge](http://localhost:54321/functions/v1/dart_edge) + +### Deploy to the Edge + +Run the following commands to compile and deploy your function on Supabase Edge functions. + +```bash +edge build supabase_functions +supabase functions deploy dart_edge +``` + +You will be asked to provide the project reference of your Supabase instance to which you want to deploy the function. You can [link your local project to your Supabase instance](https://supabase.com/docs/guides/cli/local-development#link-your-project) to avoid having to provide the Supabase reference every time you deploy. + +export const Page = ({ children }) => + +export default Page From 839339578f5f12a13ac7402dfc09caa04d867e0a Mon Sep 17 00:00:00 2001 From: Francesco Sansalvadore Date: Thu, 13 Apr 2023 16:55:10 +0200 Subject: [PATCH 16/55] move quote-figure styling to tw config --- apps/www/styles/index.css | 7 ------- packages/config/tailwind.config.js | 6 ++++++ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/apps/www/styles/index.css b/apps/www/styles/index.css index 0b9958c6353..fe2809a4a07 100644 --- a/apps/www/styles/index.css +++ b/apps/www/styles/index.css @@ -92,13 +92,6 @@ h6:not(.overwrite) { transition: all 0.07s ease-in-out; } -.quote-figure p:first-child { - margin-top: 0 !important; -} -.quote-figure p:last-child { - margin-bottom: 0 !important; -} - @media only screen and (max-width: 960px) { .h1:not(.prose *):not(.overwrite) { font-size: 2.2rem !important; diff --git a/packages/config/tailwind.config.js b/packages/config/tailwind.config.js index 9dd9d5e5a2f..e1cf73bed63 100644 --- a/packages/config/tailwind.config.js +++ b/packages/config/tailwind.config.js @@ -160,6 +160,12 @@ module.exports = ui({ figcaption: { color: 'var(--colors-scale9)', }, + 'figure.quote-figure p:first-child': { + marginTop: '0 !important', + }, + 'figure.quote-figure p:last-child': { + marginBottom: '0 !important', + }, }, }, From 57f586d7936e48dd173b182c738872469bfa1d52 Mon Sep 17 00:00:00 2001 From: Terry Sutton Date: Thu, 13 Apr 2023 12:33:58 -0230 Subject: [PATCH 17/55] Fix line length --- .../src/components/Command/GenerateSQL/GenerateSQL.tsx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/ui/src/components/Command/GenerateSQL/GenerateSQL.tsx b/packages/ui/src/components/Command/GenerateSQL/GenerateSQL.tsx index 9c42c3e717d..5206acb783f 100644 --- a/packages/ui/src/components/Command/GenerateSQL/GenerateSQL.tsx +++ b/packages/ui/src/components/Command/GenerateSQL/GenerateSQL.tsx @@ -184,8 +184,10 @@ const GenerateSQL = () => { label={sample.category} className="mt-4" > - {SAMPLE_QUERIES.find((item) => item.category === sample.category)?.queries.map( - (query) => ( +
+ {SAMPLE_QUERIES.find( + (item) => item.category === sample.category + )?.queries.map((query) => ( { @@ -202,8 +204,8 @@ const GenerateSQL = () => {

{query}

- ) - )} + ))} +
))} From 59cbcb533c420f47bd32dcf624d3181aa2a90d7d Mon Sep 17 00:00:00 2001 From: Francesco Sansalvadore Date: Thu, 13 Apr 2023 17:10:17 +0200 Subject: [PATCH 18/55] chore: add hackernews link and small tweaks --- .../www/components/LaunchWeek/7/BlogLinks.tsx | 4 ++-- .../LaunchWeek/Releases/LW7/LW7Releases.tsx | 20 ++++++++++--------- .../Releases/LW7/components/index.tsx | 9 ++++++++- apps/www/components/LaunchWeek/lw7_days.ts | 1 + 4 files changed, 22 insertions(+), 12 deletions(-) diff --git a/apps/www/components/LaunchWeek/7/BlogLinks.tsx b/apps/www/components/LaunchWeek/7/BlogLinks.tsx index 41f42400fb0..d7087d7e3b9 100644 --- a/apps/www/components/LaunchWeek/7/BlogLinks.tsx +++ b/apps/www/components/LaunchWeek/7/BlogLinks.tsx @@ -36,8 +36,8 @@ const BlogLinks = () => {
{step.title} diff --git a/apps/www/components/LaunchWeek/Releases/LW7/LW7Releases.tsx b/apps/www/components/LaunchWeek/Releases/LW7/LW7Releases.tsx index 5ce47945431..ed7d4ccc23f 100644 --- a/apps/www/components/LaunchWeek/Releases/LW7/LW7Releases.tsx +++ b/apps/www/components/LaunchWeek/Releases/LW7/LW7Releases.tsx @@ -277,7 +277,7 @@ export default function LW7Releases() { background: `radial-gradient(90% 130px at 80% 0px, #4635A7, transparent)`, }} /> -
+
{preRelease.steps[0].title} Guide
@@ -401,13 +401,13 @@ export default function LW7Releases() { -
+
{day1.steps[0].title} New
@@ -489,13 +489,13 @@ export default function LW7Releases() { -
+
{day2.steps[0].title} New
@@ -577,13 +577,13 @@ export default function LW7Releases() { -
+
{day3.steps[0].title} Updated
@@ -664,13 +664,13 @@ export default function LW7Releases() { -
+
{day4.steps[0].title} New
@@ -678,6 +678,8 @@ export default function LW7Releases() { docs={day4.steps[0].docs} blog={day4.steps[0].blog} video={day4.steps[0].video} + hackernews={day4.steps[0].hackernews} + mobileGrid /> {day4.steps[0].bg_layers && day4.steps[0].bg_layers?.map((layer, i) => diff --git a/apps/www/components/LaunchWeek/Releases/LW7/components/index.tsx b/apps/www/components/LaunchWeek/Releases/LW7/components/index.tsx index 31527f8701c..632764ee29d 100644 --- a/apps/www/components/LaunchWeek/Releases/LW7/components/index.tsx +++ b/apps/www/components/LaunchWeek/Releases/LW7/components/index.tsx @@ -175,6 +175,7 @@ export const SectionButtons = ({ github, url, hackernews, + mobileGrid, }: { blog?: string docs?: string @@ -182,9 +183,15 @@ export const SectionButtons = ({ github?: string url?: string hackernews?: string + mobileGrid?: boolean }) => { return ( -
+
{!!blog && ( Blog post diff --git a/apps/www/components/LaunchWeek/lw7_days.ts b/apps/www/components/LaunchWeek/lw7_days.ts index dedfae395c1..10ec823035c 100644 --- a/apps/www/components/LaunchWeek/lw7_days.ts +++ b/apps/www/components/LaunchWeek/lw7_days.ts @@ -222,6 +222,7 @@ const days: WeekDayProps[] = [ thumb: images['04-sso-thumb'], video: 'https://www.youtube.com/watch?v=hAwJeR6mhB0', docs: '/docs/guides/auth/sso/auth-sso-saml', + hackernews: 'https://news.ycombinator.com/item?id=35555263', bg_layers: [ { img: images['04-sso-01'], From 122979ac41ed52a49820bcca0e28aee727eb4871 Mon Sep 17 00:00:00 2001 From: Kang Ming Date: Thu, 13 Apr 2023 23:18:14 +0800 Subject: [PATCH 19/55] update blogpost --- apps/www/_blog/2023-04-13-supabase-auth-sso-pkce.mdx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/www/_blog/2023-04-13-supabase-auth-sso-pkce.mdx b/apps/www/_blog/2023-04-13-supabase-auth-sso-pkce.mdx index 600c8d00f68..c1a4dfb36ea 100644 --- a/apps/www/_blog/2023-04-13-supabase-auth-sso-pkce.mdx +++ b/apps/www/_blog/2023-04-13-supabase-auth-sso-pkce.mdx @@ -23,7 +23,7 @@ With Single Sign-On (SSO), your users can login with their company's identity pr Every developer building a B2B application eventually needs the SSO authentication flow to onboard enterprise customers. SSO is a requirement for larger Enterprise customers because it's a standard request in Enterprise Security Policies. Over the past few months, we've been [dogfooding SSO for our own Enterprise customers](https://supabase.com/docs/guides/platform/sso), and today we're releasing it for you to do the same. -Building SSO into your application isn't necessarily hard, but does come with some complexity. A lot of time can be spent understanding the nuances and details of the protocol - from dissecting the jargon to testing the implementation heavily. It took us months to build it for ourselves. With this release, you will have SSO set up and running in less than an hour so that you can focus on shipping the core features of your product. This feature is available for the [Pro-tier and above](https://supabase.com/pricing), starting today. +Building SSO into your application isn't necessarily hard, but does come with some complexity. A lot of time can be spent understanding the nuances and details of the protocol - from dissecting the jargon to testing the implementation heavily. It took us months to build it for ourselves. With this release, you will have SSO set up and running in less than an hour so that you can focus on shipping the core features of your product. This feature is available for the [Pro-tier and above](https://supabase.com/pricing), starting today. This will also be available on the self-hosted version.