diff --git a/apps/docs/content/troubleshooting/why-is-my-camelcase-name-not-working-in-postgres-functions-or-rls-policies-EJMzVd.mdx b/apps/docs/content/troubleshooting/why-is-my-camelcase-name-not-working-in-postgres-functions-or-rls-policies-EJMzVd.mdx new file mode 100644 index 0000000000000..ebebda098c86e --- /dev/null +++ b/apps/docs/content/troubleshooting/why-is-my-camelcase-name-not-working-in-postgres-functions-or-rls-policies-EJMzVd.mdx @@ -0,0 +1,10 @@ +--- +title = "Why is my camelCase name not working in Postgres functions or RLS policies?" +github_url = "https://github.com/orgs/supabase/discussions/12893" +date_created = "2023-03-08T16:26:51+00:00" +topics = ["database"] +--- + +Avoid camelCase (upper case letters) if possible when naming functions, tables, columns, and variables. You must enclose "camelCase" in double quotes when you define it or use it. YOU WILL FORGET. Use snake_case instead and make your life easier. + +Note to Prisma users, you will likely have to deal with it. diff --git a/apps/docs/features/directives/CodeSample.client.tsx b/apps/docs/features/directives/CodeSample.client.tsx index 8cde6cf1ae9ed..597a482788a76 100644 --- a/apps/docs/features/directives/CodeSample.client.tsx +++ b/apps/docs/features/directives/CodeSample.client.tsx @@ -4,6 +4,17 @@ import Link from 'next/link' import { useState, type PropsWithChildren } from 'react' import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from 'ui' +import { Admonition } from 'ui-patterns/admonition' + +export function CodeSampleDummy() { + return ( + + The $CodeSample directive with external repos is not supported in local + development because it relies on a GitHub API key. Please check the preview site to see the + final UI. + + ) +} export function CodeSampleWrapper({ children, diff --git a/apps/docs/features/directives/CodeSample.test.ts b/apps/docs/features/directives/CodeSample.test.ts index 65dd9bdb26d90..a3ae68b0e1ec2 100644 --- a/apps/docs/features/directives/CodeSample.test.ts +++ b/apps/docs/features/directives/CodeSample.test.ts @@ -14,10 +14,17 @@ const transformWithMock = codeSampleRemark({ let env: NodeJS.Process['env'] +vi.mock('~/lib/constants', () => ({ + IS_PLATFORM: true, +})) + describe('$CodeSample', () => { beforeAll(() => { env = process.env - process.env = { NODE_ENV: 'test', NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA: '1234567890' } + process.env = { + NODE_ENV: 'test', + NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA: '1234567890', + } }) afterAll(() => { diff --git a/apps/docs/features/directives/CodeSample.ts b/apps/docs/features/directives/CodeSample.ts index 47d74391b5950..ac81693a120d9 100644 --- a/apps/docs/features/directives/CodeSample.ts +++ b/apps/docs/features/directives/CodeSample.ts @@ -46,6 +46,7 @@ import { visitParents } from 'unist-util-visit-parents' import { z, type SafeParseError } from 'zod' import { fetchWithNextOptions } from '~/features/helpers.fetch' +import { IS_PLATFORM } from '~/lib/constants' import { EXAMPLES_DIRECTORY } from '~/lib/docs' const ALLOW_LISTED_GITHUB_ORGS = ['supabase', 'supabase-community'] as [string, ...string[]] @@ -141,6 +142,12 @@ async function fetchSourceCodeContent(tree: Root, deps: Dependencies) { const isExternal = getAttributeValueExpression(getAttributeValue(node, 'external')) === 'true' if (isExternal) { + if (!IS_PLATFORM) { + node.name = 'CodeSampleDummy' + node.attributes = [] + return + } + const org = getAttributeValue(node, 'org') const repo = getAttributeValue(node, 'repo') const commit = getAttributeValue(node, 'commit') diff --git a/apps/docs/features/docs/MdxBase.shared.tsx b/apps/docs/features/docs/MdxBase.shared.tsx index d90dfdca25e92..f10680b392c0a 100644 --- a/apps/docs/features/docs/MdxBase.shared.tsx +++ b/apps/docs/features/docs/MdxBase.shared.tsx @@ -35,7 +35,7 @@ import { RealtimeLimitsEstimator } from '~/components/RealtimeLimitsEstimator' import { RegionsList } from '~/components/RegionsList' import { SharedData } from '~/components/SharedData' import StepHikeCompact from '~/components/StepHikeCompact' -import { CodeSampleWrapper } from '~/features/directives/CodeSample.client' +import { CodeSampleDummy, CodeSampleWrapper } from '~/features/directives/CodeSample.client' import { Accordion, AccordionItem } from '~/features/ui/Accordion' import * as CH from '~/features/ui/CodeHike' import { ShowUntil } from '~/features/ui/ShowUntil' @@ -53,6 +53,7 @@ const components = { Button, ButtonCard, CH, + CodeSampleDummy, CodeSampleWrapper, CostWarning, CreateClientSnippet, diff --git a/apps/docs/features/docs/Troubleshooting.ui.tsx b/apps/docs/features/docs/Troubleshooting.ui.tsx index 3448846e663ba..80693679204d5 100644 --- a/apps/docs/features/docs/Troubleshooting.ui.tsx +++ b/apps/docs/features/docs/Troubleshooting.ui.tsx @@ -34,7 +34,7 @@ export async function TroubleshootingPreview({ entry }: { entry: ITroubleshootin {...attributes} >
-
+
{entry.data.errors?.length > 0 && ( - {entry.data.errors.map((error, index) => ( - <> - {formatError(error)} - {index < entry.data.errors.length - 1 && ', '} - - ))} + {entry.data.errors + .map(formatError) + .filter(Boolean) + .map((error, index) => ( + <> + {error} + {index < entry.data.errors.length - 1 ? ', ' : ''} + + ))} )}
diff --git a/apps/docs/features/docs/Troubleshooting.utils.shared.ts b/apps/docs/features/docs/Troubleshooting.utils.shared.ts index 2e87d4288501f..5e804f7623631 100644 --- a/apps/docs/features/docs/Troubleshooting.utils.shared.ts +++ b/apps/docs/features/docs/Troubleshooting.utils.shared.ts @@ -12,7 +12,7 @@ export const TROUBLESHOOTING_DATA_ATTRIBUTES = { } export function formatError(error: ITroubleshootingEntry['data']['errors'][number]) { - return `${error.http_status_code ?? ''}${!!error.http_status_code && !!error.code && ' '}${error.code ?? ''}` + return `${error.http_status_code ?? ''}${!!error.http_status_code && !!error.code ? ' ' : ''}${error.code ?? ''}` } export const troubleshootingSearchParams = { diff --git a/apps/docs/internals/generate-sitemap.ts b/apps/docs/internals/generate-sitemap.ts index 876507a471989..f1d37d6d8b5f0 100644 --- a/apps/docs/internals/generate-sitemap.ts +++ b/apps/docs/internals/generate-sitemap.ts @@ -15,7 +15,7 @@ async function generate() { const cliPages = generateCLIPages() const referencePages = await generateReferencePages() - const contentFiles = await globby(['content/**/!(_)*.mdx']) + const contentFiles = await globby(['content/guides/**/!(_)*.mdx']) const contentPages = await Promise.all( contentFiles.map(async (filePath) => { const fileContents = await fs.promises.readFile(filePath, 'utf8') @@ -30,7 +30,18 @@ async function generate() { }) ) + const troubleshootingFiles = await globby(['content/troubleshooting/**/!(_)*.mdx']) + const troubleshootingPages = await Promise.all( + troubleshootingFiles.map(async (filePath) => { + return { + link: filePath.replace(/^content/, 'guides').replace(/\.mdx$/, ''), + priority: 1, + } + }) + ) + const allPages = (contentPages as Array<{ link: string; priority?: number }>).concat( + troubleshootingPages, referencePages, cliPages ) diff --git a/apps/www/_blog/2024-12-05-supabase-queues.mdx b/apps/www/_blog/2024-12-05-supabase-queues.mdx index 83d4723c833f8..38cb1fd6e2dc0 100644 --- a/apps/www/_blog/2024-12-05-supabase-queues.mdx +++ b/apps/www/_blog/2024-12-05-supabase-queues.mdx @@ -105,7 +105,7 @@ Once your Queue is configured you can begin adding Messages. }} /> -### Adding Messages from the Dashboard +### From the Dashboard Let's create a new Basic Queue and add a Message. @@ -133,7 +133,7 @@ Let's create a new Basic Queue and add a Message. }} /> -### Adding messages from the server +### From the server If you're [connecting](/docs/guides/database/connecting-to-postgres) to your Postgres database from a server, you can add messages using SQL from any Postgres client: @@ -144,7 +144,7 @@ select * from pgmq.send( ); ``` -### Adding messages from the client +### From the client We have provided several functions that can be invoked from the [client libraries](/docs#client-libraries) if you need to add messages from a browser or mobile app. For example: @@ -214,6 +214,12 @@ From the Queues page, just click on a Queue to inspect it. From there you can cl }} /> +## Pricing + +Supabase Queues runs entirely in your database so there's no additional costs to use the functionality. + +We recommend you configure your database's Compute and Disk settings appropriately to support your Queues workload. + ## Postgres for Everything Using Postgres for your Queue system keeps your stack lean and familiar. You can add Messages to Queues within the same transaction that modifies related data, preventing inconsistencies and reducing the need for additional coordination. Postgres' robust indexing, JSONB support, and partitioning also enable scalable, high-performance queue management directly in your database. diff --git a/examples/auth/nextjs/components/AuthButton.tsx b/examples/auth/nextjs/components/AuthButton.tsx index d16f5fe88057f..ec94bfd0bd4fd 100644 --- a/examples/auth/nextjs/components/AuthButton.tsx +++ b/examples/auth/nextjs/components/AuthButton.tsx @@ -12,7 +12,7 @@ export default async function AuthButton() { const signOut = async () => { 'use server' - const supabase = createClient() + const supabase = await createClient() await supabase.auth.signOut() return redirect('/login') }