diff --git a/.cursor/rules/unit-integration-testing.mdc b/.cursor/rules/unit-integration-testing.mdc new file mode 100644 index 00000000000..e3a659a7c53 --- /dev/null +++ b/.cursor/rules/unit-integration-testing.mdc @@ -0,0 +1,6 @@ +--- +description: +globs: apps/studio/**/*.test.ts,apps/studio/**/*.test.tsx +alwaysApply: false +--- +Make sure to follow the guidelines in this file to write tests: [README.md](mdc:apps/studio/tests/README.md) diff --git a/.github/workflows/studio-unit-tests.yml b/.github/workflows/studio-unit-tests.yml index 317ea8dab14..de776aa2630 100644 --- a/.github/workflows/studio-unit-tests.yml +++ b/.github/workflows/studio-unit-tests.yml @@ -24,9 +24,12 @@ permissions: contents: read jobs: - check: + test: # Uses larger hosted runner as it significantly decreases build times runs-on: [larger-runner-4cpu] + strategy: + matrix: + test_number: [1] steps: - uses: actions/checkout@v4 @@ -50,5 +53,25 @@ jobs: env: # Default is 2 GB, increase to have less frequent OOM errors NODE_OPTIONS: '--max_old_space_size=3072' - run: pnpm run test:studio - working-directory: ./ + run: pnpm run test:ci + working-directory: ./apps/studio + + - name: Upload coverage results to Coveralls + uses: coverallsapp/github-action@master + with: + parallel: true + flag-name: studio-tests + github-token: ${{ secrets.GITHUB_TOKEN }} + path-to-lcov: ./apps/studio/coverage/lcov.info + base-path: './apps/studio' + + finish: + needs: test + if: ${{ always() }} + runs-on: ubuntu-latest + steps: + - name: Coveralls Finished + uses: coverallsapp/github-action@master + with: + parallel-finished: true + github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/ui-tests.yml b/.github/workflows/ui-tests.yml index c579d052023..6284f0cae2b 100644 --- a/.github/workflows/ui-tests.yml +++ b/.github/workflows/ui-tests.yml @@ -15,8 +15,11 @@ permissions: contents: read jobs: - build: + test: runs-on: ubuntu-latest + strategy: + matrix: + test_number: [1] steps: - uses: actions/checkout@v4 @@ -39,4 +42,25 @@ jobs: run: pnpm i - name: Run tests - run: pnpm run test:ui + run: pnpm run test:ci + working-directory: ./packages/ui + + - name: Upload coverage results to Coveralls + uses: coverallsapp/github-action@master + with: + parallel: true + flag-name: ui-tests + github-token: ${{ secrets.GITHUB_TOKEN }} + path-to-lcov: ./packages/ui/coverage/lcov.info + base-path: './packages/ui' + + finish: + needs: test + if: ${{ always() }} + runs-on: ubuntu-latest + steps: + - name: Coveralls Finished + uses: coverallsapp/github-action@master + with: + parallel-finished: true + github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index b6ce235b350..761041edaae 100644 --- a/.gitignore +++ b/.gitignore @@ -133,3 +133,8 @@ gcloud.json # sitemaps # apps/www/public/*.xml # apps/docs/public/*.xml + +# CLI version file +.temp/cli-latest + +.pnpm-store/* diff --git a/apps/design-system/content/docs/components/button.mdx b/apps/design-system/content/docs/components/button.mdx index 8b7cda6325a..53c183989c5 100644 --- a/apps/design-system/content/docs/components/button.mdx +++ b/apps/design-system/content/docs/components/button.mdx @@ -81,7 +81,7 @@ Used for actions that might have a side effect, but not as serious as a destruct #### Destructive (currently `danger`) -Used for actions that will have a serios destructive side effect, like deleting data. +Used for actions that will have a serious destructive side effect, like deleting data. prop `type` will probably be changed to `destructive` in the future. diff --git a/apps/design-system/content/docs/fragments/inner-side-menu.mdx b/apps/design-system/content/docs/fragments/inner-side-menu.mdx index 329252c1efe..41f82d9dee3 100644 --- a/apps/design-system/content/docs/fragments/inner-side-menu.mdx +++ b/apps/design-system/content/docs/fragments/inner-side-menu.mdx @@ -44,7 +44,7 @@ function app() { If you don't need the Collapsible features, you can instead use ``. This doesn't require the use of the `` parent component wrapped around it. -You can wrap the `` conponents however you like. Below we've put a `
` around them. +You can wrap the `` components however you like. Below we've put a `
` around them. ```jsx {1} Projects @@ -125,7 +125,7 @@ Use the `actions` prop to add any actions like a ` )} - + {isLoggedIn ? ( + + ) : ( + + )}
diff --git a/apps/docs/components/Navigation/NavigationMenu/TopNavDropdown.tsx b/apps/docs/components/Navigation/NavigationMenu/TopNavDropdown.tsx index 5b102255a38..7d7999c63c8 100644 --- a/apps/docs/components/Navigation/NavigationMenu/TopNavDropdown.tsx +++ b/apps/docs/components/Navigation/NavigationMenu/TopNavDropdown.tsx @@ -19,7 +19,6 @@ import { cn, themes, } from 'ui' - import MenuIconPicker from './MenuIconPicker' const menu = [ @@ -70,7 +69,7 @@ const TopNavDropdown = () => { - + {menu.map((menuSection, sectionIdx) => ( {sectionIdx !== 0 && } diff --git a/apps/docs/components/Navigation/NavigationMenu/useDropdownMenu.tsx b/apps/docs/components/Navigation/NavigationMenu/useDropdownMenu.tsx new file mode 100644 index 00000000000..ab0fb45827e --- /dev/null +++ b/apps/docs/components/Navigation/NavigationMenu/useDropdownMenu.tsx @@ -0,0 +1,80 @@ +'use client' + +import type { User } from '@supabase/supabase-js' +import { LogOut, Globe, LifeBuoy, Settings, UserIcon, Database } from 'lucide-react' +import { logOut } from 'common' + +import type { menuItem } from 'ui-patterns/AuthenticatedDropdownMenu' +import { IconGitHub } from './MenuIcons' + +const useDropdownMenu = (user: User | null) => { + const menu: menuItem[][] = [ + [ + { + label: user?.email ?? "You're logged in", + type: 'text', + icon: UserIcon, + }, + { + label: 'Account Preferences', + icon: Settings, + href: 'https://supabase.com/dashboard/account/me', + }, + { + label: 'All Projects', + icon: Database, + href: 'https://supabase.com/dashboard/projects', + }, + ], + [ + { + label: 'Supabase.com', + icon: Globe, + href: 'https://supabase.com', + otherProps: { + target: '_blank', + rel: 'noreferrer noopener', + }, + }, + { + label: 'GitHub', + icon: IconGitHub as any, + href: 'https://github.com/supabase/supabase', + otherProps: { + target: '_blank', + rel: 'noreferrer noopener', + }, + }, + { + label: 'Support', + icon: LifeBuoy, + href: 'https://supabase.com/support', + otherProps: { + target: '_blank', + rel: 'noreferrer noopener', + }, + }, + ], + [ + { + label: 'Theme', + type: 'theme', + }, + ], + [ + { + label: 'Logout', + type: 'button', + icon: LogOut, + onClick: async () => { + await logOut() + window.location.reload() + }, + }, + ], + ] + + return menu +} + +export default useDropdownMenu diff --git a/apps/docs/components/Price.tsx b/apps/docs/components/Price.tsx new file mode 100644 index 00000000000..3a58f96c69f --- /dev/null +++ b/apps/docs/components/Price.tsx @@ -0,0 +1,7 @@ +interface PriceProps { + price: string +} + +export const Price: React.FC = ({ price }) => { + return ${price} +} diff --git a/apps/docs/components/ProjectConfigVariables/ProjectConfigVariables.tsx b/apps/docs/components/ProjectConfigVariables/ProjectConfigVariables.tsx index 41250bcb1dc..565fca8b3f2 100644 --- a/apps/docs/components/ProjectConfigVariables/ProjectConfigVariables.tsx +++ b/apps/docs/components/ProjectConfigVariables/ProjectConfigVariables.tsx @@ -15,7 +15,7 @@ import CopyToClipboard from 'react-copy-to-clipboard' import { withErrorBoundary } from 'react-error-boundary' import { proxy, useSnapshot } from 'valtio' -import { useIsLoggedIn, useIsUserLoading } from 'common' +import { LOCAL_STORAGE_KEYS, useIsLoggedIn, useIsUserLoading } from 'common' import { Button_Shadcn_ as Button, Input_Shadcn_ as Input, cn } from 'ui' import { @@ -36,7 +36,7 @@ import { useOrganizationsQuery } from '~/lib/fetch/organizations' import { type SupavisorConfigData, useSupavisorConfigQuery } from '~/lib/fetch/pooler' import { useProjectApiQuery } from '~/lib/fetch/projectApi' import { isProjectPaused, type ProjectsData, useProjectsQuery } from '~/lib/fetch/projects' -import { LOCAL_STORAGE_KEYS, retrieve, storeOrRemoveNull } from '~/lib/storage' +import { retrieve, storeOrRemoveNull } from '~/lib/storage' import { useOnLogout } from '~/lib/userAuth' type ProjectOrgDataState = diff --git a/apps/docs/content/_partials/billing/pricing/pricing_branching.mdx b/apps/docs/content/_partials/billing/pricing/pricing_branching.mdx index 6aa5ca8ed90..ff9420f1ca3 100644 --- a/apps/docs/content/_partials/billing/pricing/pricing_branching.mdx +++ b/apps/docs/content/_partials/billing/pricing/pricing_branching.mdx @@ -1 +1 @@ -There is no fixed fee for a Preview branch. You only pay for the usage it incurs. With Compute costs of $0.01344 per hour, a branch running on Micro Compute size starts at $0.32 per day. +There is no fixed fee for a Preview branch. You only pay for the usage it incurs. With Compute costs of per hour, a branch running on Micro Compute size starts at per day. diff --git a/apps/docs/content/_partials/billing/pricing/pricing_edge_functions.mdx b/apps/docs/content/_partials/billing/pricing/pricing_edge_functions.mdx index 4a68dc3316a..4a6e51cb3b6 100644 --- a/apps/docs/content/_partials/billing/pricing/pricing_edge_functions.mdx +++ b/apps/docs/content/_partials/billing/pricing/pricing_edge_functions.mdx @@ -1,8 +1,9 @@ -$2 per 1 million invocations. You are only charged for usage exceeding your subscription plan's quota. + per 1 million invocations. You are only charged for usage exceeding your subscription +plan's quota. -| Plan | Quota | Over-Usage | -| ---------- | --------- | ---------------------------- | -| Free | 500,000 | - | -| Pro | 2 million | $2 per 1 million invocations | -| Team | 2 million | $2 per 1 million invocations | -| Enterprise | Custom | Custom | +| Plan | Quota | Over-Usage | +| ---------- | --------- | --------------------------------------------- | +| Free | 500,000 | - | +| Pro | 2 million | per 1 million invocations | +| Team | 2 million | per 1 million invocations | +| Enterprise | Custom | Custom | diff --git a/apps/docs/content/_partials/billing/pricing/pricing_mau.mdx b/apps/docs/content/_partials/billing/pricing/pricing_mau.mdx index c3cf0efbc1d..ed4f30f7d9c 100644 --- a/apps/docs/content/_partials/billing/pricing/pricing_mau.mdx +++ b/apps/docs/content/_partials/billing/pricing/pricing_mau.mdx @@ -1 +1,2 @@ -$0.00325 per MAU. You are only charged for usage exceeding your subscription plan's quota. + per MAU. You are only charged for usage exceeding your subscription plan's +quota. diff --git a/apps/docs/content/_partials/billing/pricing/pricing_mau_sso.mdx b/apps/docs/content/_partials/billing/pricing/pricing_mau_sso.mdx index a2a65032667..bf5d2628bd6 100644 --- a/apps/docs/content/_partials/billing/pricing/pricing_mau_sso.mdx +++ b/apps/docs/content/_partials/billing/pricing/pricing_mau_sso.mdx @@ -1 +1,2 @@ -$0.015 per SSO MAU. You are only charged for usage exceeding your subscription plan's quota. + per SSO MAU. You are only charged for usage exceeding your subscription plan's +quota. diff --git a/apps/docs/content/_partials/billing/pricing/pricing_mau_third_party.mdx b/apps/docs/content/_partials/billing/pricing/pricing_mau_third_party.mdx index fe567ae3e55..aa7576751bd 100644 --- a/apps/docs/content/_partials/billing/pricing/pricing_mau_third_party.mdx +++ b/apps/docs/content/_partials/billing/pricing/pricing_mau_third_party.mdx @@ -1 +1,2 @@ -$0.00325 per Third-Party MAU. You are only charged for usage exceeding your subscription plan's quota. + per Third-Party MAU. You are only charged for usage exceeding your subscription +plan's quota. diff --git a/apps/docs/content/_partials/billing/pricing/pricing_mfa_phone.mdx b/apps/docs/content/_partials/billing/pricing/pricing_mfa_phone.mdx index ea50511e1ca..5635b906706 100644 --- a/apps/docs/content/_partials/billing/pricing/pricing_mfa_phone.mdx +++ b/apps/docs/content/_partials/billing/pricing/pricing_mfa_phone.mdx @@ -1,7 +1,8 @@ -$0.1027 per hour ($75 per month) for the first project. $0.0137 per hour ($10 per month) for every additional project. + per hour ( per month) for the first project. per +hour ( per month) for every additional project. -| Plan | Project 1 per month | Project 2 per month | Project 3 per month | -| ---------- | ------------------- | ------------------- | ------------------- | -| Pro | $75 | $10 | $10 | -| Team | $75 | $10 | $10 | -| Enterprise | Custom | Custom | Custom | +| Plan | Project 1 per month | Project 2 per month | Project 3 per month | +| ---------- | -------------------- | -------------------- | -------------------- | +| Pro | | | | +| Team | | | | +| Enterprise | Custom | Custom | Custom | diff --git a/apps/docs/content/_partials/billing/pricing/pricing_pitr.mdx b/apps/docs/content/_partials/billing/pricing/pricing_pitr.mdx index 435f156a2c0..36b2c8801f1 100644 --- a/apps/docs/content/_partials/billing/pricing/pricing_pitr.mdx +++ b/apps/docs/content/_partials/billing/pricing/pricing_pitr.mdx @@ -1,7 +1,7 @@ Pricing depends on the recovery retention period, which determines how many days back you can restore data to any chosen point of up to seconds in granularity. -| Recovery Retention Period in Days | Hourly Price USD | Monthly Price USD | -| --------------------------------- | ---------------- | ----------------- | -| 7 | $0.137 | $100 | -| 14 | $0.274 | $200 | -| 28 | $0.55 | $400 | +| Recovery Retention Period in Days | Hourly Price USD | Monthly Price USD | +| --------------------------------- | ----------------------- | --------------------- | +| 7 | | | +| 14 | | | +| 28 | | | diff --git a/apps/docs/content/_partials/billing/pricing/pricing_realtime_connections.mdx b/apps/docs/content/_partials/billing/pricing/pricing_realtime_connections.mdx index 22a03499d3f..5e8737d0af3 100644 --- a/apps/docs/content/_partials/billing/pricing/pricing_realtime_connections.mdx +++ b/apps/docs/content/_partials/billing/pricing/pricing_realtime_connections.mdx @@ -1,8 +1,9 @@ -$10 per 1,000 peak connections. You are only charged for usage exceeding your subscription plan's quota. + per 1,000 peak connections. You are only charged for usage exceeding your subscription +plan's quota. -| Plan | Quota | Over-Usage | -| ---------- | ------ | ------------------------------ | -| Free | 200 | - | -| Pro | 500 | $10 per 1,000 peak connections | -| Team | 500 | $10 per 1,000 peak connections | -| Enterprise | Custom | Custom | +| Plan | Quota | Over-Usage | +| ---------- | ------ | ----------------------------------------------- | +| Free | 200 | - | +| Pro | 500 | per 1,000 peak connections | +| Team | 500 | per 1,000 peak connections | +| Enterprise | Custom | Custom | diff --git a/apps/docs/content/_partials/billing/pricing/pricing_realtime_messages.mdx b/apps/docs/content/_partials/billing/pricing/pricing_realtime_messages.mdx index 2e64090fd92..3cbea00db4f 100644 --- a/apps/docs/content/_partials/billing/pricing/pricing_realtime_messages.mdx +++ b/apps/docs/content/_partials/billing/pricing/pricing_realtime_messages.mdx @@ -1,8 +1,9 @@ -$2.50 per 1 million messages. You are only charged for usage exceeding your subscription plan's quota. + per 1 million messages. You are only charged for usage exceeding your subscription +plan's quota. -| Plan | Quota | Over-Usage | -| ---------- | --------- | ---------------------------- | -| Free | 2 million | - | -| Pro | 5 million | $2.50 per 1 million messages | -| Team | 5 million | $2.50 per 1 million messages | -| Enterprise | Custom | Custom | +| Plan | Quota | Over-Usage | +| ---------- | --------- | --------------------------------------------- | +| Free | 2 million | - | +| Pro | 5 million | per 1 million messages | +| Team | 5 million | per 1 million messages | +| Enterprise | Custom | Custom | diff --git a/apps/docs/content/_partials/billing/pricing/pricing_storage_image_transformations.mdx b/apps/docs/content/_partials/billing/pricing/pricing_storage_image_transformations.mdx index 0525d0e76a2..4c4d4d429db 100644 --- a/apps/docs/content/_partials/billing/pricing/pricing_storage_image_transformations.mdx +++ b/apps/docs/content/_partials/billing/pricing/pricing_storage_image_transformations.mdx @@ -1,4 +1,5 @@ -$5 per 1,000 origin images. You are only charged for usage exceeding your subscription plan's quota. + per 1,000 origin images. You are only charged for usage exceeding your subscription +plan's quota. @@ -6,8 +7,8 @@ The count resets at the start of each billing cycle. -| Plan | Quota | Over-Usage | -| ---------- | ------ | -------------------------- | -| Pro | 100 | $5 per 1,000 origin images | -| Team | 100 | $5 per 1,000 origin images | -| Enterprise | Custom | Custom | +| Plan | Quota | Over-Usage | +| ---------- | ------ | ------------------------------------------- | +| Pro | 100 | per 1,000 origin images | +| Team | 100 | per 1,000 origin images | +| Enterprise | Custom | Custom | diff --git a/apps/docs/content/_partials/billing/pricing/pricing_storage_size.mdx b/apps/docs/content/_partials/billing/pricing/pricing_storage_size.mdx index 883298c4981..6fb439f74e9 100644 --- a/apps/docs/content/_partials/billing/pricing/pricing_storage_size.mdx +++ b/apps/docs/content/_partials/billing/pricing/pricing_storage_size.mdx @@ -1,8 +1,9 @@ -$0.00002919 per GB-Hr ($0.021 per GB per month). You are only charged for usage exceeding your subscription plan's quota. + per GB-Hr ( per GB per month). You are only +charged for usage exceeding your subscription plan's quota. -| Plan | Quota in GB | Over-Usage per GB | Quota in GB-Hrs | Over-Usage per GB-Hr | -| ---------- | ----------- | ----------------- | --------------- | -------------------- | -| Free | 1 | - | 744 | - | -| Pro | 100 | $0.021 | 74,400 | $0.00002919 | -| Team | 100 | $0.021 | 74,400 | $0.00002919 | -| Enterprise | Custom | Custom | Custom | Custom | +| Plan | Quota in GB | Over-Usage per GB | Quota in GB-Hrs | Over-Usage per GB-Hr | +| ---------- | ----------- | ----------------------- | --------------- | ---------------------------- | +| Free | 1 | - | 744 | - | +| Pro | 100 | | 74,400 | | +| Team | 100 | | 74,400 | | +| Enterprise | Custom | Custom | Custom | Custom | diff --git a/apps/docs/content/guides/auth/auth-helpers/auth-ui.mdx b/apps/docs/content/guides/auth/auth-helpers/auth-ui.mdx index 7b239511062..bda36fa1ae0 100644 --- a/apps/docs/content/guides/auth/auth-helpers/auth-ui.mdx +++ b/apps/docs/content/guides/auth/auth-helpers/auth-ui.mdx @@ -9,6 +9,8 @@ sitemapPriority: 0.5 As of 7th Feb 2024, [this repository](https://github.com/supabase-community/auth-ui) is no longer maintained by the Supabase Team. At the moment, the team does not have capacity to give the expected level of care to this repository. We may revisit Auth UI in the future but regrettably have to leave it on hold for now as we focus on other priorities such as improving the Server-Side Rendering (SSR) package and advanced Auth primitives. +As an alternative you can use the [Supabase UI Library](https://supabase.com/ui) which has auth ready blocks to use in your projects. + Auth UI is a pre-built React component for authenticating users. diff --git a/apps/docs/content/guides/auth/auth-hooks/send-email-hook.mdx b/apps/docs/content/guides/auth/auth-hooks/send-email-hook.mdx index f7a08c4934d..4da5443d9cb 100644 --- a/apps/docs/content/guides/auth/auth-hooks/send-email-hook.mdx +++ b/apps/docs/content/guides/auth/auth-hooks/send-email-hook.mdx @@ -643,7 +643,7 @@ const templates = { function generateConfirmationURL(email_data) { // TODO: replace the ref with your project ref - return `https://.supabase.co/auth/v1/verify?token=${email_data.token}&type=${email_data.email_action_type}&redirect_to=${email_data.redirect_to}` + return `https://.supabase.co/auth/v1/verify?token=${email_data.token_hash}&type=${email_data.email_action_type}&redirect_to=${email_data.redirect_to}` } Deno.serve(async (req) => { @@ -755,7 +755,7 @@ const templates = { function generateConfirmationURL(email_data) { // TODO: replace the ref with your project ref - return `https://.supabase.co/auth/v1/verify?token=${email_data.token}&type=${email_data.email_action_type}&redirect_to=${email_data.redirect_to}` + return `https://.supabase.co/auth/v1/verify?token=${email_data.token_hash}&type=${email_data.email_action_type}&redirect_to=${email_data.redirect_to}` } async function sendEmailWithPostmark(user: any, email_data: any, serverToken: string): Promise { diff --git a/apps/docs/content/guides/auth/server-side/nextjs.mdx b/apps/docs/content/guides/auth/server-side/nextjs.mdx index 3f5d6fe41dd..1b3390e20a6 100644 --- a/apps/docs/content/guides/auth/server-side/nextjs.mdx +++ b/apps/docs/content/guides/auth/server-side/nextjs.mdx @@ -565,7 +565,7 @@ Fill in your `NEXT_PUBLIC_SUPABASE_URL` and `NEXT_PUBLIC_SUPABASE_ANON_KEY`: -```txt .env.local +```txt name=.env.local NEXT_PUBLIC_SUPABASE_URL= NEXT_PUBLIC_SUPABASE_ANON_KEY= ``` diff --git a/apps/docs/content/guides/auth/social-login/auth-apple.mdx b/apps/docs/content/guides/auth/social-login/auth-apple.mdx index aa2faa122e1..d7ad99022c3 100644 --- a/apps/docs/content/guides/auth/social-login/auth-apple.mdx +++ b/apps/docs/content/guides/auth/social-login/auth-apple.mdx @@ -368,7 +368,7 @@ When developing with Expo, you can test Sign in with Apple via the Expo Go app, ) { install(GoTrue) install(ComposeAuth) { - nativeAppleLogin() + appleNativeLogin() } } ``` diff --git a/apps/docs/content/guides/auth/social-login/auth-google.mdx b/apps/docs/content/guides/auth/social-login/auth-google.mdx index b5c17ba322e..361edb83d92 100644 --- a/apps/docs/content/guides/auth/social-login/auth-google.mdx +++ b/apps/docs/content/guides/auth/social-login/auth-google.mdx @@ -694,7 +694,7 @@ val supabaseClient = createSupabaseClient( supabaseUrl = "SUPABASE_URL", supabaseKey = "SUPABASE_KEY" ) { - install(GoTrue) + install(Auth) install(ComposeAuth) { nativeGoogleLogin("WEB_GOOGLE_CLIENT_ID") //Use the Web Client ID, not the Android one! } diff --git a/apps/docs/content/guides/auth/third-party/clerk.mdx b/apps/docs/content/guides/auth/third-party/clerk.mdx index 3a422696986..852eb4dedc2 100644 --- a/apps/docs/content/guides/auth/third-party/clerk.mdx +++ b/apps/docs/content/guides/auth/third-party/clerk.mdx @@ -37,15 +37,11 @@ If you are not able to use [Clerk's Connect with Supabase page](https://dashboar -```typescript -import { createClient } from '@supabase/supabase-js' - -const supabase = createClient('https://.supabase.co', 'SUPABASE_ANON_KEY', { - accessToken: () => { - return Clerk.session?.getToken() - }, -}) -``` +<$CodeSample +path="/clerk/hooks/useSupabaseClient.ts" +lines={[[6, 14]]} +hideElidedLines={true} +/> @@ -99,34 +95,23 @@ The recommended way to design RLS policies with Clerk is to use claims present i ### Example: Check user organization role -```sql -create policy "Only organization admins can insert in table" - on table_name - for insert - to authenticated - with check ( - ((select auth.jwt()->>'org_role') = 'org:admin') - and - (organization_id = (select auth.jwt()->>'org_id')) - ); -``` +<$CodeSample +path="/clerk/supabase/migrations/20250501155648_setup_database.sql" +lines={[[10, 18]]} +hideElidedLines={true} +/> -This RLS policy checks that the newly inserted row in the table has the user's declared organization ID (from the `org_id` session token claim) in the `organization_id` column. Additionally it ensures that they're an `org:admin`. +This RLS policy checks that the newly inserted row in the table has the user's declared organization ID in the `organization_id` column. Additionally it ensures that they're an `org:admin`. This way only organization admins can add rows to the table, for organizations they're a member of. ### Example: Check user has passed second factor verification -```sql -create policy "Only users that have passed second factor verification can read from table" - on table_name - for select - as restrictive - to authenticated - using ( - ((select auth.jwt()->'fva'->>1) != '-1') - ); -``` +<$CodeSample +path="/clerk/supabase/migrations/20250501155648_setup_database.sql" +lines={[[28, 35]]} +hideElidedLines={true} +/> This example uses a restrictive RLS policy checks that the [second factor verification](https://clerk.com/docs/guides/reverification) age element in the `fva` claim is not `'-1'` indicating the user has passed through second factor verification. diff --git a/apps/docs/content/guides/cron.mdx b/apps/docs/content/guides/cron.mdx index 4682251b0d7..9d4d1a1b29e 100644 --- a/apps/docs/content/guides/cron.mdx +++ b/apps/docs/content/guides/cron.mdx @@ -5,7 +5,15 @@ subtitle: 'Schedule Recurring Jobs with Cron Syntax in Postgres' Supabase Cron is a Postgres Module that simplifies scheduling recurring Jobs with cron syntax and monitoring Job runs inside Postgres. -Cron Jobs can be created via SQL or the Cron interface inside of Supabase Dashboard and can run anywhere from every second to once a year depending on your use case. +Cron Jobs can be created via SQL or the [Integrations -> Cron](https://supabase.com/dashboard/project/_/integrations) interface inside the Dashboard, and can run anywhere from every second to once a year depending on your use case. + +Manage cron jobs via the Dashboard Every Job can run SQL snippets or database functions with zero network latency or make an HTTP request, such as invoking a Supabase Edge Function, with ease. diff --git a/apps/docs/content/guides/database/extensions/timescaledb.mdx b/apps/docs/content/guides/database/extensions/timescaledb.mdx index 268a5006c80..fa75a8d0c68 100644 --- a/apps/docs/content/guides/database/extensions/timescaledb.mdx +++ b/apps/docs/content/guides/database/extensions/timescaledb.mdx @@ -35,7 +35,7 @@ Supabase projects come with [TimescaleDB Apache 2 Edition](https://docs.timescal {/* prettier-ignore */} ```sql -- Enable the "timescaledb" extension -create extension timescaledb; +create extension timescaledb with schema extensions; -- Disable the "timescaledb" extension drop extension if exists timescaledb; @@ -44,6 +44,10 @@ drop extension if exists timescaledb; +Even though the SQL code is `create extension`, this is the equivalent of "enabling the extension". To disable an extension you can call `drop extension`. + +It's good practice to create the extension within a separate schema (like `extensions`) to keep your `public` schema clean. + ## Usage To demonstrate how `timescaledb` works, let's consider a simple example where we have a table that stores temperature data from different sensors. We will create a table named "temperatures" and store data for two sensors. diff --git a/apps/docs/content/guides/deployment/branching.mdx b/apps/docs/content/guides/deployment/branching.mdx index 1f4e2a71cb1..ce14f125938 100644 --- a/apps/docs/content/guides/deployment/branching.mdx +++ b/apps/docs/content/guides/deployment/branching.mdx @@ -624,7 +624,7 @@ You can make a similar setup with a distinct project for each environment. Or ju Branching is available on the Pro Plan and above. The price is: -- Each Preview branch costs $0.32 per day +- Each Preview branch costs per day - Each Preview branch is billed until it is removed ## Troubleshooting diff --git a/apps/docs/content/guides/functions/websockets.mdx b/apps/docs/content/guides/functions/websockets.mdx index 83e134e4421..1a4762e1d22 100644 --- a/apps/docs/content/guides/functions/websockets.mdx +++ b/apps/docs/content/guides/functions/websockets.mdx @@ -236,7 +236,6 @@ To prevent that, you can update the `supabase/config.toml` with the following se ```toml [edge_runtime] policy = "per_worker" -``` +```` When running with `per_worker` policy, Function won't auto-reload on edits. You will need to manually restart it by running `supabase functions serve`. -```` diff --git a/apps/docs/content/guides/getting-started/quickstarts/nuxtjs.mdx b/apps/docs/content/guides/getting-started/quickstarts/nuxtjs.mdx index 6e19c64f2ed..bfc6a12f4cc 100644 --- a/apps/docs/content/guides/getting-started/quickstarts/nuxtjs.mdx +++ b/apps/docs/content/guides/getting-started/quickstarts/nuxtjs.mdx @@ -50,15 +50,46 @@ hideToc: true - - + + - In `app.vue`, create a Supabase client using your project URL and public API (anon) key: + Create a `.env` file and populate with your Supabase connection variables: - Replace the existing content in your `app.vue` file with the following code. + + + + + <$CodeTabs> + + ```text name=.env.local + SUPABASE_URL= + SUPABASE_ANON_KEY= + ``` + + ```ts name=nuxt.config.tsx + export default defineNuxtConfig({ + runtimeConfig: { + public: { + supabaseUrl: process.env.SUPABASE_URL, + supabaseAnonKey: process.env.SUPABASE_ANON_KEY, + }, + }, + }); + ``` + + + + + + + + + + + In `app.vue`, create a Supabase client using your config values and replace the existing content with the following code. @@ -67,7 +98,8 @@ hideToc: true ```vue name=app.vue