@@ -170,18 +171,16 @@ Create a new file at `app/auth/confirm/route.ts` and populate with the following
```ts app/auth/confirm/route.ts
import { type EmailOtpType } from '@supabase/supabase-js'
-import { cookies } from 'next/headers'
-import { NextRequest, NextResponse } from 'next/server'
-// The client you created from the Server-Side Auth instructions
+import { type NextRequest } from 'next/server'
+
import { createClient } from '@/utils/supabase/server'
+import { redirect } from 'next/navigation'
export async function GET(request: NextRequest) {
const { searchParams } = new URL(request.url)
const token_hash = searchParams.get('token_hash')
const type = searchParams.get('type') as EmailOtpType | null
const next = searchParams.get('next') ?? '/'
- const redirectTo = request.nextUrl.clone()
- redirectTo.pathname = next
if (token_hash && type) {
const supabase = await createClient()
@@ -191,13 +190,13 @@ export async function GET(request: NextRequest) {
token_hash,
})
if (!error) {
- return NextResponse.redirect(redirectTo)
+ // redirect user to specified redirect URL or root of app
+ redirect(next)
}
}
- // return the user to an error page with some instructions
- redirectTo.pathname = '/auth/auth-code-error'
- return NextResponse.redirect(redirectTo)
+ // redirect the user to an error page with some instructions
+ redirect('/auth/auth-code-error')
}
```
@@ -381,11 +380,18 @@ app.get("/auth/confirm", async function (req, res) {
To sign up the user, call [signUp()](/docs/reference/javascript/auth-signup) with their email address and password:
+You can optionally specify a URL to redirect to after the user clicks the confirmation link. This URL must be configured as a [Redirect URL](/docs/guides/auth/redirect-urls), which you can do in the [dashboard](/dashboard/project/_/auth/url-configuration) for hosted projects, or in the [configuration file](/docs/guides/cli/config#auth.additional_redirect_urls) for self-hosted projects.
+
+If you don't specify a redirect URL, the user is automatically redirected to your site URL. This defaults to `localhost:3000`, but you can also configure this.
+
```js
async function signUpNewUser() {
const { data, error } = await supabase.auth.signUp({
email: 'example@email.com',
password: 'example-password',
+ options: {
+ emailRedirectTo: 'https://example.com/welcome',
+ },
})
}
```
diff --git a/apps/docs/content/guides/auth/quickstarts/react-native.mdx b/apps/docs/content/guides/auth/quickstarts/react-native.mdx
index 4a0176049f3..220a8db979a 100644
--- a/apps/docs/content/guides/auth/quickstarts/react-native.mdx
+++ b/apps/docs/content/guides/auth/quickstarts/react-native.mdx
@@ -219,7 +219,6 @@ hideToc: true
import { useState, useEffect } from 'react'
import { supabase } from './lib/supabase'
import Auth from './components/Auth'
- import Account from './components/Account'
import { View, Text } from 'react-native'
import { Session } from '@supabase/supabase-js'
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 260a32c341e..11b24c66efd 100644
--- a/apps/docs/content/guides/auth/social-login/auth-google.mdx
+++ b/apps/docs/content/guides/auth/social-login/auth-google.mdx
@@ -439,6 +439,8 @@ Unlike the OAuth flow which requires the use of a web browser, the native Sign i
When the user provides consent, Google issues an identity token (commonly abbreviated as ID token) that is then sent to your project's Supabase Auth server. When valid, a new user session is started by issuing an access and refresh token from Supabase Auth.
+By default, Supabase Auth implements nonce validation during the authentication flow. This can be disabled in production under `Authentication > Providers > Google > Skip Nonce Check` in the Dashboard, or when developing locally by setting `auth.external..skip_nonce_check`. Only disable this if your client libraries cannot properly handle nonce verification.
+
When working with Expo, you can use the [`react-native-google-signin/google-signin` library](https://github.com/react-native-google-signin/google-signin#expo-installation) library to obtain an ID token that you can pass to supabase-js [`signInWithIdToken` method](/docs/reference/javascript/auth-signinwithidtoken).
Follow the [Expo installation docs](https://react-native-google-signin.github.io/docs/setting-up/expo) for installation and configuration instructions. See the [supabase-js reference](/docs/reference/javascript/initializing?example=react-native-options-async-storage) for instructions on initializing the supabase-js client in React Native.
diff --git a/apps/docs/content/guides/database/connecting-to-postgres.mdx b/apps/docs/content/guides/database/connecting-to-postgres.mdx
index dbf6406a713..a8e103f3451 100644
--- a/apps/docs/content/guides/database/connecting-to-postgres.mdx
+++ b/apps/docs/content/guides/database/connecting-to-postgres.mdx
@@ -1,89 +1,138 @@
---
-id: 'connecting-to-postgres'
-title: 'Connecting to your database'
-description: 'Explore the options for connecting to your Postgres database.'
-subtitle: 'Explore the options for connecting to your Postgres database.'
+title: 'Connect to your database'
+description: 'Connect to Postgres from your frontend, backend, or serverless environment'
+subtitle: 'Connect to Postgres from your frontend, backend, or serverless environment'
---
-Supabase provides several options for programmatically connecting to your Postgres database:
+## Quick summary
-1. The Data APIs
-1. Using one of the many [Client Libraries](/docs/reference)
-1. Direct connections using the built-in Postgres connection system
-1. Connection pooling for scalable connections
+How you connect to your database depends on where you're connecting from:
-## Data APIs
+- For frontend applications, use the [Data API](#data-apis-and-client-libraries)
+- For Postgres clients, use a connection string
+ - For persistent clients (for example, long-running servers or database GUIs) use the [direct connection string](#direct-connection) if your environment supports IPv6, and [Supavisor session mode](#supavisor-session-mode) if not
+ - For temporary clients (for example, serverless or edge functions) use [Supavisor transaction mode](#supavisor-transaction-mode)
-Supabase's Data APIs are the easiest way to get started if you are managing data (fetching, inserting, updating). We provide several types of API to suit your preferences:
+## Quickstarts
-- [REST](/docs/guides/api): interact with your database through a REST interface.
-- [GraphQL](/docs/guides/graphql/api): interact with your database through a GraphQL interface.
-- [Realtime](/docs/guides/realtime#realtime-api): listen to database changes over websockets.
+
-## Client libraries
+## Data APIs and client libraries
-Supabase offers [client libraries](/docs/reference) for popular programming languages. These libraries provide a convenient wrapper around the Data APIs, making it easier to interact with your database using your preferred language.
+The Data APIs allow you to interact with your database using REST or GraphQL requests. You can use these APIs to fetch and insert data from the frontend, as long as you have [RLS](/docs/guides/database/postgres/row-level-security) enabled.
-## Connecting to external libraries and tools
+- [REST](/docs/guides/api)
+- [GraphQL](/docs/guides/graphql/api)
-Beyond the [Supabase client-libraries](/docs/guides/api/rest/client-libs), Supabase provides three connection strings for direct database access, compatible with all postgres libraries, such as [Prisma](/docs/guides/database/prisma) and [Drizzle](/docs/guides/database/drizzle), as well as tools like [PSQL](/docs/guides/database/psql) and [pgAdmin](/docs/guides/database/pgadmin).
+For convenience, you can also use the Supabase client libraries, which wrap the Data APIs with a developer-friendly interface and automatically handle authentication:
-You can find these connection strings in your [Database Settings](https://supabase.com/dashboard/project/_/settings/database).
+- [JavaScript](/docs/reference/javascript)
+- [Flutter](/docs/reference/dart)
+- [Swift](/docs/reference/swift)
+- [Python](/docs/reference/python)
+- [C#](/docs/reference/csharp)
+- [Kotlin](/docs/reference/kotlin)
-### Direct connections:
+## Direct connection
-It connects directly to your Postgres instance. It is ideal for persistent servers, such as virtual machines (VMs) and long-lasting containers. Examples include AWS EC2 machines, Fly.io VMs, and DigitalOcean Droplets.
+The direct connection string connects directly to your Postgres instance. It is ideal for persistent servers, such as virtual machines (VMs) and long-lasting containers. Examples include AWS EC2 machines, Fly.io VMs, and DigitalOcean Droplets.
-Direct connections use IPv6 by default. If your environment doesn't support IPv6 or you're unsure but still want to use a direct connection, check out the [networking guide](/docs/guides/platform/ipv4-address#supabase-and-ipv6-compatibility) for more info.
+Direct connections use IPv6 by default. If your environment doesn't support IPv6, use [Supavisor session mode](#supavisor-session-mode) or get the [IPv4 addon](/docs/guides/platform/ipv4-address).
-```md
-// Example String
+The connection string looks like this:
+
+```
postgresql://postgres:[YOUR-PASSWORD]@db.apbkobhfnmcqqzqeeqss.supabase.co:5432/postgres
```
-You can find the direct connection string in the [Database settings](https://supabase.com/dashboard/project/_/settings/database) inside the dashboard:
+Get your project's direct string from the [Database Settings](/dashboard/project/_/settings/database) page:
1. Go to the `Settings` section.
2. Click `Database`.
-3. Under `Connection string`, make sure `Use connection pooling` is unchecked. Copy the URI.
+3. Under `Connection string`, make sure `Display connection pooler` is unchecked. Copy the URI.
-### Supavisor session mode (port 5432):
+## Supavisor session mode
-In Session mode, Supavisor acts as an IPv4 proxy. It allows developers in IPv4-only environments to access a direct-connection experience without needing the IPv4 add-on.
+The session mode connection string connects to your Postgres instance via a proxy. This is ideal for persistent servers when IPv4 is not supported.
-```md
-// Example String
+The connection string looks like this:
+
+```
postgres://postgres.apbkobhfnmcqqzqeeqss:[YOUR-PASSWORD]@aws-0-ca-central-1.pooler.supabase.com:5432/postgres
```
-### Transaction mode (port 6543):
+Get your project's session mode string from the [Database Settings](/dashboard/project/_/settings/database) page:
+
+1. Go to the `Settings` section.
+2. Click `Database`.
+3. Under `Connection string`, make sure `Display connection pooler` is checked and `Session mode` is selected. Copy the URI.
+
+## Supavisor transaction mode
+
+The transaction mode connection string connects to your Postgres instance via a proxy which serves as a connection pooler. This is deal for serverless or edge functions, which require many transient connections.
-Transaction mode does not support [prepared statements](https://postgresql.org/docs/current/sql-prepare.html). To avoid errors, [turn off prepared statements](https://github.com/orgs/supabase/discussions/28239) for your specific connection library.
+Transaction mode does not support [prepared statements](https://postgresql.org/docs/current/sql-prepare.html). To avoid errors, [turn off prepared statements](https://github.com/orgs/supabase/discussions/28239) for your connection library.
-Supavisor in transaction mode forms hot connections with the database and only allows clients to access them when a query is pending. It has amazing scaling capacity, and is best used with temporary servers, such as serverless/Edge Functions or auto-scaling servers.
+The connection string looks like this:
-```md
-// Example String
+```
postgres://postgres.apbkobhfnmcqqzqeeqss:[YOUR-PASSWORD]@aws-0-ca-central-1.pooler.supabase.com:6543/postgres
```
-## Connection pooling in-depth
+Get your project's transaction mode string from the [Database Settings](/dashboard/project/_/settings/database) page:
-### Application side poolers
+1. Go to the `Settings` section.
+2. Click `Database`.
+3. Under `Connection string`, make sure `Display connection pooler` is checked and `Transaction mode` is selected. Copy the URI.
+
+## More about connection pooling
+
+Connection pooling improves database performance by reusing existing connections between queries. This reduces the overhead of establishing connections and improves scalability.
+
+You can use an application-side pooler or a server-side pooler (Supabase automatically provides one called Supavisor), depending on whether your backend is persistent or serverless.
+
+### Application-side poolers
Application-side poolers are built into connection libraries and API servers, such as Prisma, SQLAlchemy, and PostgREST. They maintain several active connections with Postgres or a server-side pooler, reducing the overhead of establishing connections between queries. When deploying to static architecture, such as long-standing containers or VMs, application-side poolers are satisfactory on their own.
### Serverside poolers
-Postgres connections are like WebSocket, once established, they are preserved until the client (application server) disconnects. A server might only make a single 10 ms query, but needlessly reserve its database connection for seconds or longer.
+Postgres connections are like a WebSocket. Once established, they are preserved until the client (application server) disconnects. A server might only make a single 10 ms query, but needlessly reserve its database connection for seconds or longer.
Serverside-poolers, such as Supabase's [Supavisor](https://github.com/supabase/supavisor) in transaction mode, sit between clients and the database and can be thought of as load balancers for Postgres connections.
@@ -108,34 +157,6 @@ You can obtain your connection info and Server root certificate from your applic

-## Choosing a connection method
-
-- **Data APIs:** Best for operations supported by the Data APIs.
-- **Supavisor Pooler:**
- - **Transaction mode (port 6543):** Best for serverless/edge functions and rapidly auto-scaling servers
- - **Session mode (port 5432):** For long-lived servers, such as virtual machines (VM) and enduring containers (if IPv6 is unsupported)
-- **Direct Connections:** For long-lived servers, such as VMs and enduring containers (if IPv6 is supported or the IPv4 Add-On is enabled).
-
-## Quickstart connection guides
-
-
-
-If you'd like us to add a new quickstart guide, share your [feedback](https://supabase.com/dashboard/support/new), and we'll try to add it going forwards.
-
-
-
-### External libraries
-
-- [Prisma](/docs/guides/database/prisma)
-- [Drizzle](/docs/guides/database/drizzle)
-- [Postgres.js](/docs/guides/database/postgres-js)
-
-### External tools
-
-- [pgAdmin](/docs/guides/database/pgadmin)
-- [PSQL](/docs/guides/database/psql)
-- [DBeaver](/docs/guides/database/dbeaver)
-
## Resources
- [Connection management](/docs/guides/database/connection-management)
diff --git a/apps/docs/content/guides/database/custom-postgres-config.mdx b/apps/docs/content/guides/database/custom-postgres-config.mdx
index 599f37e9810..59a41642bdd 100644
--- a/apps/docs/content/guides/database/custom-postgres-config.mdx
+++ b/apps/docs/content/guides/database/custom-postgres-config.mdx
@@ -53,6 +53,8 @@ Some settings can only be modified by a superuser. Supabase pre-enables the [`su
| `auto_explain.log_min_duration` | Logs query plans taking longer than this duration. |
| `auto_explain.log_nested_statements` | Log nested statements' plans. |
| `log_min_messages` | Minimum severity level of messages to log. |
+| `pg_net.ttl` | Sets how long the [pg_net extension](/docs/guides/database/extensions/pg_net) saves responses |
+| `pg_net.batch_size` | Sets how many requests the [pg_net extension](/docs/guides/database/extensions/pg_net) can make per second |
| `pgaudit.*` | Configures the [PGAudit extension](https://supabase.com/docs/guides/database/extensions/pgaudit). The `log_parameter` is still restricted to protect secrets |
| `pgrst.*` | [`PostgREST` settings](https://docs.postgrest.org/en/stable/references/configuration.html#db-aggregates-enabled) |
| `plan_filter.*` | Configures the [pg_plan_filter extension](https://supabase.com/docs/guides/database/extensions/pg_plan_filter) |
diff --git a/apps/docs/content/guides/database/extensions/pgsodium.mdx b/apps/docs/content/guides/database/extensions/pgsodium.mdx
index dbddf13b51f..5c3a9d4c92b 100644
--- a/apps/docs/content/guides/database/extensions/pgsodium.mdx
+++ b/apps/docs/content/guides/database/extensions/pgsodium.mdx
@@ -8,6 +8,12 @@ Supabase DOES NOT RECOMMEND any new usage of [`pgsodium`](https://github.com/mic
The [`pgsodium`](https://github.com/michelp/pgsodium) extension is expected to go through a deprecation cycle in the near future. We will reach out to owners of impacted projects to assist with migrations away from [`pgsodium`](https://github.com/michelp/pgsodium) once the deprecation process begins.
+
+
+The [Vault extension](/docs/guides/database/vault) won’t be impacted. Its internal implementation will shift away from pgsodium, but the interface and API will remain unchanged.
+
+
+
[`pgsodium`](https://github.com/michelp/pgsodium) is a Postgres extension which provides SQL access to [`libsodium`'s](https://doc.libsodium.org/) high-level cryptographic algorithms.
Supabase previously documented two features derived from pgsodium. Namely [Server Key Management](https://github.com/michelp/pgsodium#server-key-management) and [Transparent Column Encryption](https://github.com/michelp/pgsodium#transparent-column-encryption). At this time, we do not recommend using either on the Supabase platform due to their high level of operational complexity and misconfiguration risk.
diff --git a/apps/docs/content/guides/database/extensions/postgis.mdx b/apps/docs/content/guides/database/extensions/postgis.mdx
index 9c470366db1..72b85b09aff 100644
--- a/apps/docs/content/guides/database/extensions/postgis.mdx
+++ b/apps/docs/content/guides/database/extensions/postgis.mdx
@@ -58,7 +58,7 @@ Let’s create our table. Each row represents a restaurant with its location sto
create table if not exists public.restaurants (
id int generated by default as identity primary key,
name text not null,
- location geography(POINT) not null
+ location gis.geography(POINT) not null
);
```
diff --git a/apps/docs/content/guides/database/prisma.mdx b/apps/docs/content/guides/database/prisma.mdx
index af9727e9dfe..4b88a46403a 100644
--- a/apps/docs/content/guides/database/prisma.mdx
+++ b/apps/docs/content/guides/database/prisma.mdx
@@ -184,7 +184,7 @@ If you plan to solely use Prisma instead of the Supabase Data API (PostgREST), t
-
+
If you have already modified your Supabase database, synchronize it with your migration file. Otherwise create new tables for your database
@@ -373,7 +373,7 @@ If you plan to solely use Prisma instead of the Supabase Data API (PostgREST), t
-
+
Install the prisma client and generate its model
@@ -414,7 +414,7 @@ If you plan to solely use Prisma instead of the Supabase Data API (PostgREST), t
-
+
Create a index.ts file and run it to test your connection
diff --git a/apps/docs/content/guides/functions/background-tasks.mdx b/apps/docs/content/guides/functions/background-tasks.mdx
index 7eb79415be5..fbc1f2aebf8 100644
--- a/apps/docs/content/guides/functions/background-tasks.mdx
+++ b/apps/docs/content/guides/functions/background-tasks.mdx
@@ -8,7 +8,11 @@ tocVideo: 'rSKBTJxG9VA'
Edge Function instances can process background tasks outside of the request handler. Background tasks are useful for asynchronous operations like uploading a file to Storage, updating a database, or sending events to a logging service. You can respond to the request immediately and leave the task running in the background.
-A background task can run until the Edge Function instance hits its [wall-clock limit](/docs/guides/functions/limits).
+### How long a background task can run
+
+A background task can run until the Edge Function instance hits its wall-clock limit or reaches CPU/Memory limit. Check [limits](/docs/guides/functions/limits) for current caps.
+
+### Example
Here's an example of defining a background task using a custom event.
diff --git a/apps/docs/content/guides/functions/examples/github-actions.mdx b/apps/docs/content/guides/functions/examples/github-actions.mdx
index 3298913f089..5b665d8f4c8 100644
--- a/apps/docs/content/guides/functions/examples/github-actions.mdx
+++ b/apps/docs/content/guides/functions/examples/github-actions.mdx
@@ -34,7 +34,7 @@ jobs:
PROJECT_ID: YOUR_SUPABASE_PROJECT_ID
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: supabase/setup-cli@v1
with:
diff --git a/apps/docs/content/guides/getting-started/features.mdx b/apps/docs/content/guides/getting-started/features.mdx
index 6a982ddec9a..fdc5bfda954 100644
--- a/apps/docs/content/guides/getting-started/features.mdx
+++ b/apps/docs/content/guides/getting-started/features.mdx
@@ -16,7 +16,7 @@ Every project is a full Postgres database. [Docs](/docs/guides/database).
Store vector embeddings right next to the rest of your data. [Docs](/docs/guides/ai).
-### Auto-generated Rest API via PostgREST
+### Auto-generated REST API via PostgREST
RESTful APIs are auto-generated from your database, without a single line of code. [Docs](/docs/guides/api#rest-api-overview).
@@ -66,13 +66,13 @@ Deploy read-only databases across multiple regions, for lower latency and better
Launch the Supabase stack on Fly.io edge network. [Docs](/docs/guides/platform/fly-postgres).
-### Log Drains
+### Log drains
Export Supabase logs at to 3rd party providers and external tooling. [Docs](/docs/guides/platform/log-drains).
## Studio
-### Studio Single Sign On
+### Studio Single Sign-On
Login to the Supabase dashboard via SSO. [Docs](/docs/guides/platform/sso).
@@ -118,7 +118,7 @@ Control the data each user can access with Postgres Policies. [Docs](/docs/guide
Add Captcha to your sign-in, sign-up, and password reset forms. [Docs](/docs/guides/auth/auth-captcha).
-### Server-side Auth
+### Server-Side Auth
Helpers for implementing user authentication in popular server-side languages and frameworks like Next.js, SvelteKit and Remix. [Docs](/docs/guides/auth/server-side).
@@ -183,11 +183,11 @@ Unofficial libraries are supported by the community.
Supabase Features are in 4 different states - Private Alpha, Public Alpha, Beta and Generally Available.
-### Private Alpha
+### Private alpha
Features are initially launched as a private alpha to gather feedback from the community. To join our early access program, send an email to product-ops@supabase.io.
-### Public Alpha
+### Public alpha
The alpha stage indicates that the API might change in the future, not that the service isn’t stable. Even though the [uptime Service Level Agreement](https://supabase.com/sla) does not cover products in Alpha, we do our best to have the service as stable as possible.
@@ -195,7 +195,7 @@ The alpha stage indicates that the API might change in the future, not that the
Features in Beta are tested by an external penetration tester for security issues. The API is guaranteed to be stable and there is a strict communication process for breaking changes.
-### Generally Available
+### Generally available
In addition to the Beta requirements, features in GA are covered by the [uptime SLA](https://supabase.com/sla).
diff --git a/apps/docs/content/guides/getting-started/quickstarts/redwoodjs.mdx b/apps/docs/content/guides/getting-started/quickstarts/redwoodjs.mdx
index be4ca73f67e..025a22e5ba2 100644
--- a/apps/docs/content/guides/getting-started/quickstarts/redwoodjs.mdx
+++ b/apps/docs/content/guides/getting-started/quickstarts/redwoodjs.mdx
@@ -116,7 +116,7 @@ hideToc: true
- ```prisma api/prisma/schema.prisma
+ ```prisma api/db/schema.prisma
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
diff --git a/apps/docs/content/guides/getting-started/tutorials/with-kotlin.mdx b/apps/docs/content/guides/getting-started/tutorials/with-kotlin.mdx
index 513a651444d..4f9a0527b1e 100644
--- a/apps/docs/content/guides/getting-started/tutorials/with-kotlin.mdx
+++ b/apps/docs/content/guides/getting-started/tutorials/with-kotlin.mdx
@@ -96,6 +96,8 @@ plugins {
}
```
+{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
+
### Set up Hilt for dependency injection
In the `build.gradle` (app) file, add the following:
@@ -134,6 +136,8 @@ class MainActivity : ComponentActivity() {
}
```
+{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
+
### Provide Supabase instances with Hilt
To make the app easier to test, create a `SupabaseModule.kt` file as follows:
diff --git a/apps/docs/content/guides/getting-started/tutorials/with-nextjs.mdx b/apps/docs/content/guides/getting-started/tutorials/with-nextjs.mdx
index d43d01b8ab5..277a212022f 100644
--- a/apps/docs/content/guides/getting-started/tutorials/with-nextjs.mdx
+++ b/apps/docs/content/guides/getting-started/tutorials/with-nextjs.mdx
@@ -301,7 +301,7 @@ meta="utils/supabase/middleware.ts"
## Set up a login page
-### Login and Signup form
+### Login and signup form
Create a login/signup page for your application:
diff --git a/apps/docs/content/guides/getting-started/tutorials/with-refine.mdx b/apps/docs/content/guides/getting-started/tutorials/with-refine.mdx
index 0192a305f14..f3a901e69a6 100644
--- a/apps/docs/content/guides/getting-started/tutorials/with-refine.mdx
+++ b/apps/docs/content/guides/getting-started/tutorials/with-refine.mdx
@@ -97,7 +97,7 @@ You can find the full contents of this file [here](https://raw.githubusercontent
In order for us to add login and user profile pages in this App, we have to tweak the `` component inside `App.tsx`.
-### The `` Component
+### The `` component
The `App.tsx` file initially looks like this:
diff --git a/apps/docs/content/guides/getting-started/tutorials/with-swift.mdx b/apps/docs/content/guides/getting-started/tutorials/with-swift.mdx
index 33e597d1210..fe6999a3f94 100644
--- a/apps/docs/content/guides/getting-started/tutorials/with-swift.mdx
+++ b/apps/docs/content/guides/getting-started/tutorials/with-swift.mdx
@@ -293,6 +293,8 @@ Update the entry point to the newly created `AppView`. Run in Xcode to launch yo
Every Supabase project is configured with [Storage](/docs/guides/storage) for managing large files like
photos and videos.
+{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
+
### Add PhotosPicker
Let's add support for the user to pick an image from the library and upload it.
@@ -332,6 +334,8 @@ enum TransferError: Error {
}
```
+{/* supa-mdx-lint-disable-next-line Rule001HeadingCase */}
+
#### Add PhotosPicker to profile page
```swift ProfileView.swift
diff --git a/apps/docs/content/guides/platform/compute-and-disk.mdx b/apps/docs/content/guides/platform/compute-and-disk.mdx
index 6965dba9b76..0b4e26f21c0 100644
--- a/apps/docs/content/guides/platform/compute-and-disk.mdx
+++ b/apps/docs/content/guides/platform/compute-and-disk.mdx
@@ -10,11 +10,9 @@ Every project on the Supabase Platform comes with its own dedicated Postgres ins
The following table describes the base instances, Nano (free plan) and Micro (paid plans), with additional compute instance sizes available if you need extra performance when scaling up.
-
+
-If you upgraded your Supabase organization from the Free plan to a paid plan, any projects created on the Free plan will remain on Nano instances due to the upgrade process [incurring downtime](/docs/guides/platform/compute-and-disk#upgrade-downtime).
-
-Since every project on a paid plan is already paying for a Micro instance you can upgrade to Micro at no additional charge. See [Supabase Pricing](https://supabase.com/pricing) for more information.
+In Pro organizations, Nano Compute are billed at the same price as Micro Compute. It is recommended to upgrade your Project from Nano Compute to Micro Compute when it's convenient for you. Compute sizes are not auto-upgraded because of the downtime incurred. See [Supabase Pricing](https://supabase.com/pricing) for more information.
diff --git a/apps/docs/content/guides/platform/database-size.mdx b/apps/docs/content/guides/platform/database-size.mdx
index 3ddc6cb224c..bb9174b5f9f 100644
--- a/apps/docs/content/guides/platform/database-size.mdx
+++ b/apps/docs/content/guides/platform/database-size.mdx
@@ -16,7 +16,7 @@ This SQL query will show the size of all databases in your Postgres cluster:
```sql
select
- sum(pg_database_size(pg_database.datname)) / (1024 * 1024) as db_size_mb
+ pg_size_pretty(sum(pg_database_size(pg_database.datname)))
from pg_database;
```
@@ -30,6 +30,16 @@ Depending on your billing plan, your database can go into read-only mode which c
+### Disk space usage
+
+Your database size is part of the disk usage for your Supabase project, there are many components to Postgres that consume additional disk space. One of the primary components, is the [Write Ahead Log (WAL)](https://www.postgresql.org/docs/current/wal-intro.html). Postgres will store database changes in log files that are cleared away after they are applied to the database. These same files are also used by [Read Replicas](/docs/guides/platform/read-replicas) or other replication methods.
+
+If you would like to determine the size of the WAL files stored on disk, Postgres provides `pg_ls_waldir` as a helper function; the following query can be run:
+
+```sql
+select pg_size_pretty(sum(size)) as wal_size from pg_ls_waldir();
+```
+
### Vacuum operations
Postgres does not immediately reclaim the physical space used by dead tuples (i.e., deleted rows) in the DB. They are marked as "removed" until a [vacuum operation](https://www.postgresql.org/docs/current/routine-vacuuming.html) is executed. As a result, deleting data from your database may not immediately reduce the reported disk usage. You can use the [Supabase CLI](https://supabase.com/docs/guides/cli/getting-started) `inspect db bloat` command to view all dead tuples in your database. Alternatively, you can run the [query](https://github.com/supabase/cli/blob/c9cce58025fded16b4c332747f819a44f45c3b83/internal/inspect/bloat/bloat.go#L17) found in the CLI's GitHub repo in the [SQL Editor](https://supabase.com/dashboard/project/_/sql/)
diff --git a/apps/docs/content/guides/platform/upgrading.mdx b/apps/docs/content/guides/platform/upgrading.mdx
index aef800a9d67..1bdab44de90 100644
--- a/apps/docs/content/guides/platform/upgrading.mdx
+++ b/apps/docs/content/guides/platform/upgrading.mdx
@@ -22,6 +22,11 @@ This upgrade method is currently in Beta.
+
+ For security purposes, passwords for custom roles are not backed up and, following a restore, they
+ would need to be reset. See [here](/docs/guides/platform/backups#daily-backups) for more details
+
+
pg_upgrade performs an in-place upgrade on your database. For projects larger than 1GB, pg_upgrade is generally faster than a pause+restore cycle, and the speed advantage grows with the size of the database.
1. Plan for an appropriate downtime window, and ensure you have reviewed the [caveats](#caveats) section of this document before executing the upgrade.
diff --git a/apps/docs/docs/ref/javascript/introduction.mdx b/apps/docs/docs/ref/javascript/introduction.mdx
index ac1adb04ab3..38419887755 100644
--- a/apps/docs/docs/ref/javascript/introduction.mdx
+++ b/apps/docs/docs/ref/javascript/introduction.mdx
@@ -5,3 +5,5 @@ hideTitle: true
---
This reference documents every object and method available in Supabase's isomorphic JavaScript library, `supabase-js`. You can use `supabase-js` to interact with your Postgres database, listen to database changes, invoke Deno Edge Functions, build login and user management functionality, and manage large files.
+
+To convert SQL queries to `supabase-js` calls, use the [SQL to REST API translator](/docs/guides/api/sql-to-rest).
diff --git a/apps/docs/features/app.providers.tsx b/apps/docs/features/app.providers.tsx
index dbafe0c8de6..55b37d0ee0b 100644
--- a/apps/docs/features/app.providers.tsx
+++ b/apps/docs/features/app.providers.tsx
@@ -11,6 +11,7 @@ import { QueryClientProvider } from './data/queryClient.client'
import { PageTelemetry } from './telemetry/telemetry.client'
import { ScrollRestoration } from './ui/helpers.scroll.client'
import { ThemeSandbox } from './ui/theme.client'
+import { PromoToast } from 'ui-patterns'
/**
* Global providers that wrap the entire app
@@ -25,7 +26,7 @@ function GlobalProviders({ children }: PropsWithChildren) {
- {/* */}
+
{children}
diff --git a/apps/docs/features/directives/CodeSample.ts b/apps/docs/features/directives/CodeSample.ts
index d97f0c3fe79..ab297b45e6b 100644
--- a/apps/docs/features/directives/CodeSample.ts
+++ b/apps/docs/features/directives/CodeSample.ts
@@ -48,6 +48,8 @@ import { z, type SafeParseError } from 'zod'
import { fetchWithNextOptions } from '~/features/helpers.fetch'
import { EXAMPLES_DIRECTORY } from '~/lib/docs'
+const ALLOW_LISTED_GITHUB_ORGS = ['supabase'] as [string, ...string[]]
+
const linesSchema = z.array(z.tuple([z.coerce.number(), z.coerce.number()]))
const linesValidator = z
.string()
@@ -73,7 +75,9 @@ type AdditionalMeta = {
const codeSampleExternalSchema = z.object({
external: z.coerce.boolean().refine((v) => v === true),
- org: z.string(),
+ org: z.enum(ALLOW_LISTED_GITHUB_ORGS, {
+ errorMap: () => ({ message: 'Org must be one of: ' + ALLOW_LISTED_GITHUB_ORGS.join(', ') }),
+ }),
repo: z.string(),
commit: z.string(),
path: z.string().transform((v) => (v.startsWith('/') ? v : `/${v}`)),
diff --git a/apps/docs/features/directives/utils.ts b/apps/docs/features/directives/utils.ts
index eb67d138d91..d52e1fd94cd 100644
--- a/apps/docs/features/directives/utils.ts
+++ b/apps/docs/features/directives/utils.ts
@@ -9,6 +9,7 @@ import { mdxjs } from 'micromark-extension-mdxjs'
import remarkMkDocsAdmonition from '~/lib/mdx/plugins/remarkAdmonition'
import remarkPyMdownTabs from '~/lib/mdx/plugins/remarkTabs'
import { getGitHubFileContents } from '~/lib/octokit'
+import { getGitHubFileContentsImmutableOnly } from '~/lib/octokit'
import { codeSampleRemark } from './CodeSample'
type Transformer = (ast: Root) => Root | Promise
@@ -31,6 +32,8 @@ export function preprocessMdxWithDefaults(mdx: string) {
return preprocessMdx(mdx, [
remarkMkDocsAdmonition(),
remarkPyMdownTabs(),
- codeSampleRemark({ fetchFromGitHub: getGitHubFileContents }),
+ codeSampleRemark({
+ fetchFromGitHub: getGitHubFileContentsImmutableOnly,
+ }),
])
}
diff --git a/apps/docs/lib/octokit.ts b/apps/docs/lib/octokit.ts
index c1ccf9073cb..155e6f20720 100644
--- a/apps/docs/lib/octokit.ts
+++ b/apps/docs/lib/octokit.ts
@@ -35,7 +35,7 @@ export async function getGitHubFileContents({
repo,
path,
branch,
- options: { onError },
+ options: { onError, fetch },
}: {
org: string
repo: string
@@ -63,7 +63,7 @@ export async function getGitHubFileContents({
path: path,
ref: branch,
options: {
- fetch: fetchRevalidatePerDay,
+ fetch: fetch ?? fetchRevalidatePerDay,
},
})
if (response.status !== 200 || !response.data) {
@@ -79,3 +79,80 @@ export async function getGitHubFileContents({
onError?.(err)
}
}
+
+export async function getGitHubFileContentsImmutableOnly({
+ org,
+ repo,
+ branch,
+ path,
+ options: { onError, fetch },
+}: {
+ org: string
+ repo: string
+ branch: string
+ path: string
+ options: {
+ onError: (err?: unknown) => void
+ fetch?: (info: RequestInfo, init?: RequestInit) => Promise
+ }
+}) {
+ const isImmutableCommit = await checkForImmutableCommit({
+ org,
+ repo,
+ branch,
+ })
+ if (!isImmutableCommit) {
+ throw Error('The commit is not an immutable commit SHA. Tags and branch names are not allowed.')
+ }
+
+ return getGitHubFileContents({
+ org,
+ repo,
+ branch,
+ path,
+ options: { onError, fetch },
+ })
+}
+
+async function checkForImmutableCommit({
+ org,
+ repo,
+ branch,
+ options: { fetch: _fetch = fetch } = {},
+}: {
+ org: string
+ repo: string
+ branch: string
+ options?: {
+ /**
+ *
+ * A custom fetch implementation to control Next.js caching.
+ */
+ fetch?: (info: RequestInfo, init?: RequestInit) => Promise
+ }
+}) {
+ try {
+ const response = await octokit().request('GET /repos/{owner}/{repo}/git/commits/{commit_sha}', {
+ owner: org,
+ repo: repo,
+ commit_sha: branch,
+ headers: {
+ 'X-GitHub-Api-Version': '2022-11-28',
+ },
+ options: {
+ fetch: _fetch,
+ },
+ })
+ if (response.status === 200) {
+ return true
+ } else {
+ throw Error(
+ "Checking for an immutable commit didn't throw an error, but it also didn't return a 200. Erring on the side of safety, assuming this is not an immutable commit.",
+ { cause: response }
+ )
+ }
+ } catch (err) {
+ console.error('Not an immutable commit: %o', err)
+ return false
+ }
+}
diff --git a/apps/docs/next-env.d.ts b/apps/docs/next-env.d.ts
index 40c3d68096c..725dd6f2451 100644
--- a/apps/docs/next-env.d.ts
+++ b/apps/docs/next-env.d.ts
@@ -1,5 +1,6 @@
///
///
+///
// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.
diff --git a/apps/docs/next.config.mjs b/apps/docs/next.config.mjs
index 9a9d8196565..37333dad42d 100644
--- a/apps/docs/next.config.mjs
+++ b/apps/docs/next.config.mjs
@@ -58,6 +58,7 @@ const nextConfig = {
experimental: {
outputFileTracingIncludes: {
'/api/crawlers': ['./features/docs/generated/**/*', './docs/ref/**/*'],
+ '/guides/**/*': ['./content/guides/**/*', './content/troubleshooting/**/*'],
'/reference/**/*': ['./features/docs/generated/**/*', './docs/ref/**/*'],
},
},
diff --git a/apps/docs/spec/api_v1_openapi.json b/apps/docs/spec/api_v1_openapi.json
index 75df6edc0d6..6b1c9fc67bc 100644
--- a/apps/docs/spec/api_v1_openapi.json
+++ b/apps/docs/spec/api_v1_openapi.json
@@ -130,7 +130,7 @@
"application/json": {
"schema": {
"type": "array",
- "items": { "$ref": "#/components/schemas/V1ProjectResponse" }
+ "items": { "$ref": "#/components/schemas/V1ProjectWithDatabaseResponse" }
}
}
}
@@ -146,7 +146,9 @@
"requestBody": {
"required": true,
"content": {
- "application/json": { "schema": { "$ref": "#/components/schemas/V1CreateProjectBody" } }
+ "application/json": {
+ "schema": { "$ref": "#/components/schemas/V1CreateProjectBodyDto" }
+ }
}
},
"responses": {
@@ -192,7 +194,7 @@
"required": true,
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/CreateOrganizationBodyV1" }
+ "schema": { "$ref": "#/components/schemas/CreateOrganizationV1Dto" }
}
}
},
@@ -312,7 +314,7 @@
"operationId": "v1-get-a-snippet",
"summary": "Gets a specific SQL snippet",
"parameters": [
- { "name": "id", "required": true, "in": "path", "schema": { "type": "string" } }
+ { "name": "id", "required": true, "in": "path", "schema": { "type": "uuid" } }
],
"responses": {
"200": {
@@ -338,7 +340,8 @@
"in": "path",
"description": "Project ref",
"schema": { "minLength": 20, "maxLength": 20, "type": "string" }
- }
+ },
+ { "name": "reveal", "required": true, "in": "query", "schema": { "type": "boolean" } }
],
"responses": {
"200": {
@@ -366,7 +369,8 @@
"in": "path",
"description": "Project ref",
"schema": { "minLength": 20, "maxLength": 20, "type": "string" }
- }
+ },
+ { "name": "reveal", "required": true, "in": "query", "schema": { "type": "boolean" } }
],
"requestBody": {
"required": true,
@@ -398,7 +402,8 @@
"description": "Project ref",
"schema": { "minLength": 20, "maxLength": 20, "type": "string" }
},
- { "name": "id", "required": true, "in": "path", "schema": { "type": "string" } }
+ { "name": "id", "required": true, "in": "path", "schema": { "type": "string" } },
+ { "name": "reveal", "required": true, "in": "query", "schema": { "type": "boolean" } }
],
"requestBody": {
"required": true,
@@ -417,6 +422,31 @@
"tags": ["Secrets"],
"security": [{ "bearer": [] }]
},
+ "get": {
+ "operationId": "getApiKey",
+ "summary": "[Alpha] Get API key",
+ "parameters": [
+ {
+ "name": "ref",
+ "required": true,
+ "in": "path",
+ "description": "Project ref",
+ "schema": { "minLength": 20, "maxLength": 20, "type": "string" }
+ },
+ { "name": "id", "required": true, "in": "path", "schema": { "type": "string" } },
+ { "name": "reveal", "required": true, "in": "query", "schema": { "type": "boolean" } }
+ ],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": { "schema": { "$ref": "#/components/schemas/ApiKeyResponse" } }
+ }
+ }
+ },
+ "tags": ["Secrets"],
+ "security": [{ "bearer": [] }]
+ },
"delete": {
"operationId": "deleteApiKey",
"summary": "[Alpha] Deletes an API key for the project",
@@ -428,7 +458,8 @@
"description": "Project ref",
"schema": { "minLength": 20, "maxLength": 20, "type": "string" }
},
- { "name": "id", "required": true, "in": "path", "schema": { "type": "string" } }
+ { "name": "id", "required": true, "in": "path", "schema": { "type": "string" } },
+ { "name": "reveal", "required": true, "in": "query", "schema": { "type": "boolean" } }
],
"responses": {
"200": {
@@ -940,7 +971,9 @@
"200": {
"description": "",
"content": {
- "application/json": { "schema": { "$ref": "#/components/schemas/V1ProjectResponse" } }
+ "application/json": {
+ "schema": { "$ref": "#/components/schemas/V1ProjectWithDatabaseResponse" }
+ }
}
},
"500": { "description": "Failed to retrieve project" }
@@ -2035,6 +2068,12 @@
"required": false,
"in": "query",
"schema": { "type": "string" }
+ },
+ {
+ "name": "resource_multiplier",
+ "required": false,
+ "in": "query",
+ "schema": { "type": "string" }
}
],
"requestBody": {
@@ -2178,6 +2217,12 @@
"required": false,
"in": "query",
"schema": { "type": "string" }
+ },
+ {
+ "name": "resource_multiplier",
+ "required": false,
+ "in": "query",
+ "schema": { "type": "string" }
}
],
"requestBody": {
@@ -2697,7 +2742,7 @@
},
"required": ["host", "version", "postgres_engine", "release_channel"]
},
- "V1ProjectResponse": {
+ "V1ProjectWithDatabaseResponse": {
"type": "object",
"properties": {
"id": { "type": "string", "description": "Id of your project" },
@@ -2735,33 +2780,9 @@
"type": "string"
}
},
- "required": ["id", "organization_id", "name", "region", "created_at", "status"]
+ "required": ["id", "organization_id", "name", "region", "created_at", "database", "status"]
},
- "DesiredInstanceSize": {
- "type": "string",
- "enum": [
- "micro",
- "small",
- "medium",
- "large",
- "xlarge",
- "2xlarge",
- "4xlarge",
- "8xlarge",
- "12xlarge",
- "16xlarge"
- ]
- },
- "ReleaseChannel": {
- "type": "string",
- "enum": ["internal", "alpha", "beta", "ga", "withdrawn"]
- },
- "PostgresEngine": {
- "type": "string",
- "description": "Postgres engine version. If not provided, the latest version will be used.",
- "enum": ["15"]
- },
- "V1CreateProjectBody": {
+ "V1CreateProjectBodyDto": {
"type": "object",
"properties": {
"db_pass": { "type": "string", "description": "Database password" },
@@ -2773,12 +2794,12 @@
"plan": {
"type": "string",
"enum": ["free", "pro"],
- "description": "Subscription Plan is now set on organization level and is ignored in this request",
- "example": "free",
- "deprecated": true
+ "deprecated": true,
+ "description": "Subscription Plan is now set on organization level and is ignored in this request"
},
"region": {
"type": "string",
+ "description": "Region you want your server to reside in",
"enum": [
"us-east-1",
"us-east-2",
@@ -2798,35 +2819,97 @@
"ca-central-1",
"ap-south-1",
"sa-east-1"
- ],
- "description": "Region you want your server to reside in",
- "example": "us-east-1"
+ ]
},
"kps_enabled": {
"type": "boolean",
"deprecated": true,
"description": "This field is deprecated and is ignored in this request"
},
- "desired_instance_size": { "$ref": "#/components/schemas/DesiredInstanceSize" },
+ "desired_instance_size": {
+ "type": "string",
+ "enum": [
+ "micro",
+ "small",
+ "medium",
+ "large",
+ "xlarge",
+ "2xlarge",
+ "4xlarge",
+ "8xlarge",
+ "12xlarge",
+ "16xlarge"
+ ]
+ },
"template_url": {
"type": "string",
+ "format": "uri",
"description": "Template URL used to create the project from the CLI.",
"example": "https://github.com/supabase/supabase/tree/master/examples/slack-clone/nextjs-slack-clone"
},
- "release_channel": { "$ref": "#/components/schemas/ReleaseChannel" },
- "postgres_engine": { "$ref": "#/components/schemas/PostgresEngine" }
+ "release_channel": {
+ "type": "string",
+ "enum": ["internal", "alpha", "beta", "ga", "withdrawn"],
+ "description": "Release channel. If not provided, GA will be used."
+ },
+ "postgres_engine": {
+ "type": "string",
+ "enum": ["15"],
+ "description": "Postgres engine version. If not provided, the latest version will be used."
+ }
},
- "required": ["db_pass", "name", "organization_id", "region"]
+ "required": ["db_pass", "name", "organization_id", "region"],
+ "additionalProperties": false
+ },
+ "V1ProjectResponse": {
+ "type": "object",
+ "properties": {
+ "id": { "type": "string", "description": "Id of your project" },
+ "organization_id": { "type": "string", "description": "Slug of your organization" },
+ "name": { "type": "string", "description": "Name of your project" },
+ "region": {
+ "type": "string",
+ "description": "Region of your project",
+ "example": "us-east-1"
+ },
+ "created_at": {
+ "type": "string",
+ "description": "Creation timestamp",
+ "example": "2023-03-29T16:32:59Z"
+ },
+ "status": {
+ "enum": [
+ "ACTIVE_HEALTHY",
+ "ACTIVE_UNHEALTHY",
+ "COMING_UP",
+ "GOING_DOWN",
+ "INACTIVE",
+ "INIT_FAILED",
+ "REMOVED",
+ "RESTARTING",
+ "UNKNOWN",
+ "UPGRADING",
+ "PAUSING",
+ "RESTORING",
+ "RESTORE_FAILED",
+ "PAUSE_FAILED",
+ "RESIZING"
+ ],
+ "type": "string"
+ }
+ },
+ "required": ["id", "organization_id", "name", "region", "created_at", "status"]
},
"OrganizationResponseV1": {
"type": "object",
"properties": { "id": { "type": "string" }, "name": { "type": "string" } },
"required": ["id", "name"]
},
- "CreateOrganizationBodyV1": {
+ "CreateOrganizationV1Dto": {
"type": "object",
"properties": { "name": { "type": "string" } },
- "required": ["name"]
+ "required": ["name"],
+ "additionalProperties": false
},
"OAuthTokenBody": {
"type": "object",
@@ -2945,10 +3028,14 @@
"ApiKeyResponse": {
"type": "object",
"properties": {
+ "type": {
+ "nullable": true,
+ "type": "string",
+ "enum": ["publishable", "secret", "legacy"]
+ },
"name": { "type": "string" },
"api_key": { "type": "string" },
"id": { "type": "string", "nullable": true },
- "type": { "nullable": true, "type": "object" },
"prefix": { "type": "string", "nullable": true },
"description": { "type": "string", "nullable": true },
"hash": { "type": "string", "nullable": true },
@@ -2983,6 +3070,30 @@
}
}
},
+ "DesiredInstanceSize": {
+ "type": "string",
+ "enum": [
+ "micro",
+ "small",
+ "medium",
+ "large",
+ "xlarge",
+ "2xlarge",
+ "4xlarge",
+ "8xlarge",
+ "12xlarge",
+ "16xlarge"
+ ]
+ },
+ "ReleaseChannel": {
+ "type": "string",
+ "enum": ["internal", "alpha", "beta", "ga", "withdrawn"]
+ },
+ "PostgresEngine": {
+ "type": "string",
+ "description": "Postgres engine version. If not provided, the latest version will be used.",
+ "enum": ["15"]
+ },
"CreateBranchBody": {
"type": "object",
"properties": {
@@ -4134,7 +4245,8 @@
"slug": { "type": "string", "pattern": "/^[A-Za-z0-9_-]+$/" },
"name": { "type": "string" },
"body": { "type": "string" },
- "verify_jwt": { "type": "boolean" }
+ "verify_jwt": { "type": "boolean" },
+ "resource_multiplier": { "type": "string" }
},
"required": ["slug", "name", "body"]
},
@@ -4151,7 +4263,8 @@
"verify_jwt": { "type": "boolean" },
"import_map": { "type": "boolean" },
"entrypoint_path": { "type": "string" },
- "import_map_path": { "type": "string" }
+ "import_map_path": { "type": "string" },
+ "resource_multiplier": { "type": "string" }
},
"required": ["version", "created_at", "updated_at", "id", "slug", "name", "status"]
},
@@ -4168,7 +4281,8 @@
"verify_jwt": { "type": "boolean" },
"import_map": { "type": "boolean" },
"entrypoint_path": { "type": "string" },
- "import_map_path": { "type": "string" }
+ "import_map_path": { "type": "string" },
+ "resource_multiplier": { "type": "string" }
},
"required": ["version", "created_at", "updated_at", "id", "slug", "name", "status"]
},
@@ -4177,7 +4291,8 @@
"properties": {
"name": { "type": "string" },
"body": { "type": "string" },
- "verify_jwt": { "type": "boolean" }
+ "verify_jwt": { "type": "boolean" },
+ "resource_multiplier": { "type": "string" }
}
},
"V1StorageBucketResponse": {
diff --git a/apps/docs/spec/cli_v1_commands.yaml b/apps/docs/spec/cli_v1_commands.yaml
index 553fe3008b6..e07ad7fb852 100644
--- a/apps/docs/spec/cli_v1_commands.yaml
+++ b/apps/docs/spec/cli_v1_commands.yaml
@@ -1,7 +1,7 @@
clispec: '001'
info:
id: cli
- version: 1.219.2
+ version: 1.223.10
title: Supabase CLI
language: sh
source: https://github.com/supabase/cli
@@ -3354,6 +3354,27 @@ commands:
name: --use-pgadmin
description: Use pgAdmin to generate schema diff.
default_value: 'false'
+ - id: supabase-config
+ title: supabase config
+ summary: Manage Supabase project configurations
+ tags:
+ - management-api
+ links: []
+ subcommands:
+ - supabase-config-push
+ flags: []
+ - id: supabase-config-push
+ title: supabase config push
+ summary: Pushes local config.toml to the linked project
+ tags: []
+ links: []
+ usage: supabase config push
+ subcommands: []
+ flags:
+ - id: project-ref
+ name: --project-ref
+ description: Project ref of the Supabase project.
+ default_value: ''
- id: supabase-completion
title: supabase completion
summary: Generate the autocompletion script for the specified shell
diff --git a/apps/docs/spec/cli_v1_config.yaml b/apps/docs/spec/cli_v1_config.yaml
index c1c5657b914..1ef9416164d 100644
--- a/apps/docs/spec/cli_v1_config.yaml
+++ b/apps/docs/spec/cli_v1_config.yaml
@@ -44,6 +44,9 @@ info:
- id: analytics
title: Analytics
description: Analytics settings.
+ - id: experimental
+ title: Experimental
+ description: Settings in alpha testing, subject to changes or removal at any time.
- id: local
title: Local Development
description: Local Development settings.
@@ -190,6 +193,237 @@ parameters:
- name: 'PgBouncer Configuration'
link: https://www.pgbouncer.org/config.html#default_pool_size
+ - id: 'db.settings.effective_cache_size'
+ title: 'db.settings.effective_cache_size'
+ tags: ['database']
+ required: false
+ description: |
+ Sets the planner's assumption about the effective size of the disk cache.
+ This is a query planner parameter that doesn't affect actual memory allocation.
+ links:
+ - name: 'PostgreSQL configuration'
+ link: 'https://www.postgresql.org/docs/current/runtime-config-query.html#GUC-EFFECTIVE-CACHE-SIZE'
+
+ - id: 'db.settings.logical_decoding_work_mem'
+ title: 'db.settings.logical_decoding_work_mem'
+ tags: ['database']
+ required: false
+ description: |
+ Specifies the amount of memory to be used by logical decoding, before writing data to local disk.
+ links:
+ - name: 'PostgreSQL configuration'
+ link: 'https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-LOGICAL-DECODING-WORK-MEM'
+
+ - id: 'db.settings.maintenance_work_mem'
+ title: 'db.settings.maintenance_work_mem'
+ tags: ['database']
+ required: false
+ description: |
+ Specifies the maximum amount of memory to be used by maintenance operations, such as VACUUM, CREATE INDEX, and ALTER TABLE ADD FOREIGN KEY.
+ links:
+ - name: 'PostgreSQL configuration'
+ link: 'https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM'
+
+ - id: 'db.settings.max_connections'
+ title: 'db.settings.max_connections'
+ tags: ['database']
+ required: false
+ description: |
+ Determines the maximum number of concurrent connections to the database server.
+ Note: Changing this parameter requires a database restart.
+ links:
+ - name: 'PostgreSQL configuration'
+ link: 'https://www.postgresql.org/docs/current/runtime-config-connection.html#GUC-MAX-CONNECTIONS'
+
+ - id: 'db.settings.max_locks_per_transaction'
+ title: 'db.settings.max_locks_per_transaction'
+ tags: ['database']
+ required: false
+ description: |
+ Controls the average number of object locks allocated for each transaction.
+ Note: Changing this parameter requires a database restart.
+ links:
+ - name: 'PostgreSQL configuration'
+ link: 'https://www.postgresql.org/docs/current/runtime-config-locks.html#GUC-MAX-LOCKS-PER-TRANSACTION'
+
+ - id: 'db.settings.max_parallel_maintenance_workers'
+ title: 'db.settings.max_parallel_maintenance_workers'
+ tags: ['database']
+ required: false
+ description: |
+ Sets the maximum number of parallel workers that can be started by a single utility command.
+ links:
+ - name: 'PostgreSQL configuration'
+ link: 'https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-MAX-PARALLEL-MAINTENANCE-WORKERS'
+
+ - id: 'db.settings.max_parallel_workers'
+ title: 'db.settings.max_parallel_workers'
+ tags: ['database']
+ required: false
+ description: |
+ Sets the maximum number of parallel workers that the system can support.
+ Note: Changing this parameter requires a database restart.
+ links:
+ - name: 'PostgreSQL configuration'
+ link: 'https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-MAX-PARALLEL-WORKERS'
+
+ - id: 'db.settings.max_parallel_workers_per_gather'
+ title: 'db.settings.max_parallel_workers_per_gather'
+ tags: ['database']
+ required: false
+ description: |
+ Sets the maximum number of parallel workers that can be started by a single Gather or Gather Merge node.
+ links:
+ - name: 'PostgreSQL configuration'
+ link: 'https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-MAX-PARALLEL-WORKERS-PER-GATHER'
+
+ - id: 'db.settings.max_replication_slots'
+ title: 'db.settings.max_replication_slots'
+ tags: ['database']
+ required: false
+ description: |
+ Specifies the maximum number of replication slots that the server can support.
+ Note: Changing this parameter requires a database restart.
+ links:
+ - name: 'PostgreSQL configuration'
+ link: 'https://www.postgresql.org/docs/current/runtime-config-replication.html#GUC-MAX-REPLICATION-SLOTS'
+
+ - id: 'db.settings.max_slot_wal_keep_size'
+ title: 'db.settings.max_slot_wal_keep_size'
+ tags: ['database']
+ required: false
+ description: |
+ Specifies the maximum size of WAL files that replication slots are allowed to retain in the pg_wal directory.
+ links:
+ - name: 'PostgreSQL configuration'
+ link: 'https://www.postgresql.org/docs/current/runtime-config-replication.html#GUC-MAX-SLOT-WAL-KEEP-SIZE'
+
+ - id: 'db.settings.max_standby_archive_delay'
+ title: 'db.settings.max_standby_archive_delay'
+ tags: ['database']
+ required: false
+ description: |
+ Sets the maximum delay before canceling queries when a hot standby server is processing archived WAL data.
+ links:
+ - name: 'PostgreSQL configuration'
+ link: 'https://www.postgresql.org/docs/current/runtime-config-replication.html#GUC-MAX-STANDBY-ARCHIVE-DELAY'
+
+ - id: 'db.settings.max_standby_streaming_delay'
+ title: 'db.settings.max_standby_streaming_delay'
+ tags: ['database']
+ required: false
+ description: |
+ Sets the maximum delay before canceling queries when a hot standby server is processing streamed WAL data.
+ links:
+ - name: 'PostgreSQL configuration'
+ link: 'https://www.postgresql.org/docs/current/runtime-config-replication.html#GUC-MAX-STANDBY-STREAMING-DELAY'
+
+ - id: 'db.settings.max_wal_size'
+ title: 'db.settings.max_wal_size'
+ tags: ['database']
+ required: false
+ description: |
+ Sets the maximum size of WAL files that the system will keep in the pg_wal directory.
+ links:
+ - name: 'PostgreSQL configuration'
+ link: 'https://www.postgresql.org/docs/current/runtime-config-wal.html#GUC-MAX-WAL-SIZE'
+
+ - id: 'db.settings.max_wal_senders'
+ title: 'db.settings.max_wal_senders'
+ tags: ['database']
+ required: false
+ description: |
+ Specifies the maximum number of concurrent connections from standby servers or streaming base backup clients.
+ Note: Changing this parameter requires a database restart.
+ links:
+ - name: 'PostgreSQL configuration'
+ link: 'https://www.postgresql.org/docs/current/runtime-config-replication.html#GUC-MAX-WAL-SENDERS'
+
+ - id: 'db.settings.max_worker_processes'
+ title: 'db.settings.max_worker_processes'
+ tags: ['database']
+ required: false
+ type: 'uint'
+ description: |
+ Sets the maximum number of background processes that the system can support.
+ Note: Changing this parameter requires a database restart.
+ links:
+ - name: 'PostgreSQL configuration'
+ link: 'https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-MAX-WORKER-PROCESSES'
+
+ - id: 'db.settings.session_replication_role'
+ title: 'db.settings.session_replication_role'
+ tags: ['database']
+ required: false
+ description: |
+ Controls whether triggers and rewrite rules are enabled. Valid values are: "origin", "replica", or "local".
+ links:
+ - name: 'PostgreSQL configuration'
+ link: 'https://www.postgresql.org/docs/current/runtime-config-client.html#GUC-SESSION-REPLICATION-ROLE'
+
+ - id: 'db.settings.shared_buffers'
+ title: 'db.settings.shared_buffers'
+ tags: ['database']
+ required: false
+ description: |
+ Sets the amount of memory the database server uses for shared memory buffers.
+ Note: Changing this parameter requires a database restart.
+ links:
+ - name: 'PostgreSQL configuration'
+ link: 'https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-SHARED-BUFFERS'
+
+ - id: 'db.settings.statement_timeout'
+ title: 'db.settings.statement_timeout'
+ tags: ['database']
+ required: false
+ description: |
+ Abort any statement that takes more than the specified amount of time.
+ links:
+ - name: 'PostgreSQL configuration'
+ link: 'https://www.postgresql.org/docs/current/runtime-config-client.html#GUC-STATEMENT-TIMEOUT'
+
+ - id: 'db.settings.track_commit_timestamp'
+ title: 'db.settings.track_commit_timestamp'
+ tags: ['database']
+ required: false
+ type: 'bool'
+ description: |
+ Record commit time of transactions.
+ Note: Changing this parameter requires a database restart.
+ links:
+ - name: 'PostgreSQL configuration'
+ link: 'https://www.postgresql.org/docs/current/runtime-config-replication.html#GUC-TRACK-COMMIT-TIMESTAMP'
+
+ - id: 'db.settings.wal_keep_size'
+ title: 'db.settings.wal_keep_size'
+ tags: ['database']
+ required: false
+ description: |
+ Specifies the minimum size of past log file segments kept in the pg_wal directory.
+ links:
+ - name: 'PostgreSQL configuration'
+ link: 'https://www.postgresql.org/docs/current/runtime-config-replication.html#GUC-WAL-KEEP-SIZE'
+
+ - id: 'db.settings.wal_sender_timeout'
+ title: 'db.settings.wal_sender_timeout'
+ tags: ['database']
+ required: false
+ description: |
+ Terminate replication connections that are inactive for longer than this amount of time.
+ links:
+ - name: 'PostgreSQL configuration'
+ link: 'https://www.postgresql.org/docs/current/runtime-config-replication.html#GUC-WAL-SENDER-TIMEOUT'
+
+ - id: 'db.settings.work_mem'
+ title: 'db.settings.work_mem'
+ tags: ['database']
+ required: false
+ description: |
+ Specifies the amount of memory to be used by internal sort operations and hash tables before writing to temporary disk files.
+ links:
+ - name: 'PostgreSQL configuration'
+ link: 'https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-WORK-MEM'
+
- id: 'db.pooler.max_client_conn'
title: 'db.pooler.max_client_conn'
tags: ['database']
@@ -463,6 +697,56 @@ parameters:
- name: 'Auth Server configuration'
link: 'https://supabase.com/docs/reference/auth'
+ - id: 'auth.email.secure_password_change'
+ title: 'auth.email.secure_password_change'
+ tags: ['auth']
+ required: false
+ type: 'bool'
+ default: false
+ description: |
+ If enabled, requires the user's current password to be provided when changing to a new password.
+ links:
+ - name: 'Auth Server configuration'
+ link: 'https://supabase.com/docs/reference/auth'
+
+ - id: 'auth.email.max_frequency'
+ title: 'auth.email.max_frequency'
+ tags: ['auth']
+ required: false
+ type: 'duration'
+ default: '1m'
+ description: |
+ The minimum amount of time that must pass between email requests.
+ Helps prevent email spam by limiting how frequently emails can be sent.
+ Example values: "1m", "1h", "24h"
+ links:
+ - name: 'Auth Server configuration'
+ link: 'https://supabase.com/docs/reference/auth'
+
+ - id: 'auth.email.otp_length'
+ title: 'auth.email.otp_length'
+ tags: ['auth']
+ required: false
+ default: '6'
+ description: |
+ The length of the OTP code to be sent in emails.
+ Must be between 6 and 10 digits.
+ links:
+ - name: 'Auth Server configuration'
+ link: 'https://supabase.com/docs/reference/auth'
+
+ - id: 'auth.email.otp_exp'
+ title: 'auth.email.otp_exp'
+ tags: ['auth']
+ required: false
+ default: '300'
+ description: |
+ The expiry time for an OTP code in seconds.
+ Default is 300 seconds (5 minutes).
+ links:
+ - name: 'Auth Server configuration'
+ link: 'https://supabase.com/docs/reference/auth'
+
- id: 'auth.email.smtp.host'
title: 'auth.email.smtp.host'
tags: ['auth']
@@ -780,6 +1064,38 @@ parameters:
- name: 'Auth Server configuration'
link: 'https://supabase.com/docs/reference/auth'
+ - id: 'auth.external.provider.skip_nonce_check'
+ title: 'auth.external..skip_nonce_check'
+ tags: ['auth']
+ required: false
+ description: |
+ Disables nonce validation during OIDC authentication flow for the specified provider. Enable only when client libraries cannot properly handle nonce verification. Be aware that this reduces security by allowing potential replay attacks with stolen ID tokens.
+ links:
+ - name: 'Auth Server configuration'
+ link: 'https://supabase.com/docs/reference/auth'
+
+ - id: 'auth.mfa.web_authn.enroll_enabled'
+ title: 'auth.mfa.web_authn.enroll_enabled'
+ tags: ['auth', 'local']
+ required: false
+ default: 'false'
+ description: |
+ Enable WebAuthn enrollment for multi-factor authentication.
+ links:
+ - name: 'Auth Server configuration'
+ link: 'https://supabase.com/docs/reference/auth'
+
+ - id: 'auth.mfa.web_authn.verify_enabled'
+ title: 'auth.mfa.web_authn.verify_enabled'
+ tags: ['auth', 'local']
+ required: false
+ default: 'false'
+ description: |
+ Enable WebAuthn verification for multi-factor authentication.
+ links:
+ - name: 'Auth Server configuration'
+ link: 'https://supabase.com/docs/reference/auth'
+
- id: 'functions.function_name.enabled'
title: 'functions..enabled'
tags: ['edge-functions']
@@ -821,6 +1137,20 @@ parameters:
- name: '`supabase functions` CLI subcommands'
link: 'https://supabase.com/docs/reference/cli/supabase-functions'
+ - id: 'functions.function_name.entrypoint'
+ title: 'functions..entrypoint'
+ tags: ['edge-functions']
+ required: false
+ description: |
+ Specify a custom entrypoint path for the function relative to the project root.
+ When not specified, defaults to `supabase/functions//index.ts`.
+ links:
+ - name: '`supabase functions` CLI subcommands'
+ link: 'https://supabase.com/docs/reference/cli/supabase-functions'
+ usage: |
+ [functions.my_function]
+ entrypoint = "path/to/custom/function.ts"
+
- id: 'analytics.enabled'
title: 'analytics.enabled'
tags: ['analytics']
@@ -863,3 +1193,66 @@ parameters:
links:
- name: Self-hosted Logflare Configuration
link: https://supabase.com/docs/reference/self-hosting-analytics/list-endpoints#getting-started
+
+ - id: 'experimental.webhooks.enabled'
+ title: 'experimental.webhooks.enabled'
+ tags: ['experimental']
+ required: false
+ default: 'false'
+ description: |
+ Automatically enable webhook features on each new created branch
+ Note: This is an experimental feature and may change in future releases.
+ links: []
+
+ - id: 'experimental.orioledb_version'
+ title: 'experimental.orioledb_version'
+ tags: ['experimental']
+ required: false
+ description: |
+ Configures Postgres storage engine to use OrioleDB with S3 support.
+ Note: This is an experimental feature and may change in future releases.
+ links: []
+
+ - id: 'experimental.s3_host'
+ title: 'experimental.s3_host'
+ tags: ['experimental']
+ required: false
+ default: 'env(S3_HOST)'
+ description: |
+ Configures S3 bucket URL for OrioleDB storage.
+ Format example: .s3-.amazonaws.com
+ Note: This is an experimental feature and may change in future releases.
+ links: []
+
+ - id: 'experimental.s3_region'
+ title: 'experimental.s3_region'
+ tags: ['experimental']
+ required: false
+ default: 'env(S3_REGION)'
+ description: |
+ Configures S3 bucket region for OrioleDB storage.
+ Example: us-east-1
+ Note: This is an experimental feature and may change in future releases.
+ links: []
+
+ - id: 'experimental.s3_access_key'
+ title: 'experimental.s3_access_key'
+ tags: ['experimental']
+ required: false
+ default: 'env(S3_ACCESS_KEY)'
+ description: |
+ Configures AWS_ACCESS_KEY_ID for S3 bucket access.
+ DO NOT commit your AWS access key to git. Use environment variable substitution instead.
+ Note: This is an experimental feature and may change in future releases.
+ links: []
+
+ - id: 'experimental.s3_secret_key'
+ title: 'experimental.s3_secret_key'
+ tags: ['experimental']
+ required: false
+ default: 'env(S3_SECRET_KEY)'
+ description: |
+ Configures AWS_SECRET_ACCESS_KEY for S3 bucket access.
+ DO NOT commit your AWS secret key to git. Use environment variable substitution instead.
+ Note: This is an experimental feature and may change in future releases.
+ links: []
diff --git a/apps/docs/spec/common-cli-sections.json b/apps/docs/spec/common-cli-sections.json
index 81a29efb105..6e2aaff44be 100644
--- a/apps/docs/spec/common-cli-sections.json
+++ b/apps/docs/spec/common-cli-sections.json
@@ -357,6 +357,30 @@
}
]
},
+ {
+ "type": "category",
+ "title": "Organizations",
+ "items": [
+ {
+ "id": "supabase-orgs",
+ "title": "Manage organizations",
+ "slug": "supabase-orgs",
+ "type": "cli-command"
+ },
+ {
+ "id": "supabase-orgs-create",
+ "title": "Create an organization",
+ "slug": "supabase-orgs-create",
+ "type": "cli-command"
+ },
+ {
+ "id": "supabase-orgs-list",
+ "title": "List all organizations",
+ "slug": "supabase-orgs-list",
+ "type": "cli-command"
+ }
+ ]
+ },
{
"type": "category",
"title": "Projects",
@@ -393,6 +417,24 @@
}
]
},
+ {
+ "type": "category",
+ "title": "Config",
+ "items": [
+ {
+ "id": "supabase-config",
+ "title": "Manage project configurations",
+ "slug": "supabase-config",
+ "type": "cli-command"
+ },
+ {
+ "id": "supabase-config-push",
+ "title": "Push config from a local file",
+ "slug": "supabase-config-push",
+ "type": "cli-command"
+ }
+ ]
+ },
{
"type": "category",
"title": "Branches",
@@ -441,30 +483,6 @@
}
]
},
- {
- "type": "category",
- "title": "Organizations",
- "items": [
- {
- "id": "supabase-orgs",
- "title": "Manage organizations",
- "slug": "supabase-orgs",
- "type": "cli-command"
- },
- {
- "id": "supabase-orgs-create",
- "title": "Create an organization",
- "slug": "supabase-orgs-create",
- "type": "cli-command"
- },
- {
- "id": "supabase-orgs-list",
- "title": "List all organizations",
- "slug": "supabase-orgs-list",
- "type": "cli-command"
- }
- ]
- },
{
"type": "category",
"title": "Edge Functions",
diff --git a/apps/docs/spec/examples/examples.yml b/apps/docs/spec/examples/examples.yml
index 9a35a086b5e..77249cc8fa8 100644
--- a/apps/docs/spec/examples/examples.yml
+++ b/apps/docs/spec/examples/examples.yml
@@ -194,6 +194,7 @@ functions:
- If you're using an email, you can configure whether you want the user to receive a magiclink or a OTP.
- If you're using phone, you can configure whether you want the user to receive a OTP.
- The magic link's destination URL is determined by the [`SITE_URL`](https://supabase.com/docs/guides/auth/redirect-urls). You can modify the `SITE_URL` or add additional redirect URLs in [your project](https://supabase.com/dashboard/project/_/auth/url-configuration).
+ - If you are looking to send your own OTP emails, you can use the [Auth Admin command](https://supabase.com/docs/reference/javascript/auth-admin-generatelink) or the `Send Email` [Auth Hook](https://supabase.com/docs/guides/auth/auth-hooks)
examples:
- id: sign-in-with-email.
name: Sign in with email.
diff --git a/apps/docs/spec/transforms/api_v1_openapi_deparsed.json b/apps/docs/spec/transforms/api_v1_openapi_deparsed.json
index 692ac2af2b2..e5f54471530 100644
--- a/apps/docs/spec/transforms/api_v1_openapi_deparsed.json
+++ b/apps/docs/spec/transforms/api_v1_openapi_deparsed.json
@@ -458,7 +458,15 @@
"type": "string"
}
},
- "required": ["id", "organization_id", "name", "region", "created_at", "status"]
+ "required": [
+ "id",
+ "organization_id",
+ "name",
+ "region",
+ "created_at",
+ "database",
+ "status"
+ ]
}
}
}
@@ -498,12 +506,12 @@
"plan": {
"type": "string",
"enum": ["free", "pro"],
- "description": "Subscription Plan is now set on organization level and is ignored in this request",
- "example": "free",
- "deprecated": true
+ "deprecated": true,
+ "description": "Subscription Plan is now set on organization level and is ignored in this request"
},
"region": {
"type": "string",
+ "description": "Region you want your server to reside in",
"enum": [
"us-east-1",
"us-east-2",
@@ -523,9 +531,7 @@
"ca-central-1",
"ap-south-1",
"sa-east-1"
- ],
- "description": "Region you want your server to reside in",
- "example": "us-east-1"
+ ]
},
"kps_enabled": {
"type": "boolean",
@@ -549,20 +555,23 @@
},
"template_url": {
"type": "string",
+ "format": "uri",
"description": "Template URL used to create the project from the CLI.",
"example": "https://github.com/supabase/supabase/tree/master/examples/slack-clone/nextjs-slack-clone"
},
"release_channel": {
"type": "string",
- "enum": ["internal", "alpha", "beta", "ga", "withdrawn"]
+ "enum": ["internal", "alpha", "beta", "ga", "withdrawn"],
+ "description": "Release channel. If not provided, GA will be used."
},
"postgres_engine": {
"type": "string",
- "description": "Postgres engine version. If not provided, the latest version will be used.",
- "enum": ["15"]
+ "enum": ["15"],
+ "description": "Postgres engine version. If not provided, the latest version will be used."
}
},
- "required": ["db_pass", "name", "organization_id", "region"]
+ "required": ["db_pass", "name", "organization_id", "region"],
+ "additionalProperties": false
}
}
}
@@ -597,28 +606,6 @@
"description": "Creation timestamp",
"example": "2023-03-29T16:32:59Z"
},
- "database": {
- "type": "object",
- "properties": {
- "host": {
- "type": "string",
- "description": "Database host"
- },
- "version": {
- "type": "string",
- "description": "Database version"
- },
- "postgres_engine": {
- "type": "string",
- "description": "Database engine"
- },
- "release_channel": {
- "type": "string",
- "description": "Release channel"
- }
- },
- "required": ["host", "version", "postgres_engine", "release_channel"]
- },
"status": {
"enum": [
"ACTIVE_HEALTHY",
@@ -709,7 +696,8 @@
"type": "string"
}
},
- "required": ["name"]
+ "required": ["name"],
+ "additionalProperties": false
}
}
}
@@ -1039,7 +1027,7 @@
"required": true,
"in": "path",
"schema": {
- "type": "string"
+ "type": "uuid"
}
}
],
@@ -1172,6 +1160,14 @@
"maxLength": 20,
"type": "string"
}
+ },
+ {
+ "name": "reveal",
+ "required": true,
+ "in": "query",
+ "schema": {
+ "type": "boolean"
+ }
}
],
"responses": {
@@ -1184,6 +1180,11 @@
"items": {
"type": "object",
"properties": {
+ "type": {
+ "nullable": true,
+ "type": "string",
+ "enum": ["publishable", "secret", "legacy"]
+ },
"name": {
"type": "string"
},
@@ -1194,10 +1195,6 @@
"type": "string",
"nullable": true
},
- "type": {
- "nullable": true,
- "type": "object"
- },
"prefix": {
"type": "string",
"nullable": true
@@ -1261,6 +1258,14 @@
"maxLength": 20,
"type": "string"
}
+ },
+ {
+ "name": "reveal",
+ "required": true,
+ "in": "query",
+ "schema": {
+ "type": "boolean"
+ }
}
],
"requestBody": {
@@ -1306,6 +1311,11 @@
"schema": {
"type": "object",
"properties": {
+ "type": {
+ "nullable": true,
+ "type": "string",
+ "enum": ["publishable", "secret", "legacy"]
+ },
"name": {
"type": "string"
},
@@ -1316,10 +1326,6 @@
"type": "string",
"nullable": true
},
- "type": {
- "nullable": true,
- "type": "object"
- },
"prefix": {
"type": "string",
"nullable": true
@@ -1392,6 +1398,14 @@
"schema": {
"type": "string"
}
+ },
+ {
+ "name": "reveal",
+ "required": true,
+ "in": "query",
+ "schema": {
+ "type": "boolean"
+ }
}
],
"requestBody": {
@@ -1432,6 +1446,11 @@
"schema": {
"type": "object",
"properties": {
+ "type": {
+ "nullable": true,
+ "type": "string",
+ "enum": ["publishable", "secret", "legacy"]
+ },
"name": {
"type": "string"
},
@@ -1442,9 +1461,108 @@
"type": "string",
"nullable": true
},
+ "prefix": {
+ "type": "string",
+ "nullable": true
+ },
+ "description": {
+ "type": "string",
+ "nullable": true
+ },
+ "hash": {
+ "type": "string",
+ "nullable": true
+ },
+ "secret_jwt_template": {
+ "nullable": true,
+ "allOf": [
+ {
+ "type": "object",
+ "properties": {
+ "role": {
+ "type": "string"
+ }
+ },
+ "required": ["role"]
+ }
+ ]
+ },
+ "inserted_at": {
+ "type": "string",
+ "nullable": true
+ },
+ "updated_at": {
+ "type": "string",
+ "nullable": true
+ }
+ },
+ "required": ["name", "api_key"]
+ }
+ }
+ }
+ }
+ },
+ "tags": ["Secrets"],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ },
+ "get": {
+ "operationId": "getApiKey",
+ "summary": "[Alpha] Get API key",
+ "parameters": [
+ {
+ "name": "ref",
+ "required": true,
+ "in": "path",
+ "description": "Project ref",
+ "schema": {
+ "minLength": 20,
+ "maxLength": 20,
+ "type": "string"
+ }
+ },
+ {
+ "name": "id",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "reveal",
+ "required": true,
+ "in": "query",
+ "schema": {
+ "type": "boolean"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
"type": {
"nullable": true,
- "type": "object"
+ "type": "string",
+ "enum": ["publishable", "secret", "legacy"]
+ },
+ "name": {
+ "type": "string"
+ },
+ "api_key": {
+ "type": "string"
+ },
+ "id": {
+ "type": "string",
+ "nullable": true
},
"prefix": {
"type": "string",
@@ -1516,6 +1634,14 @@
"schema": {
"type": "string"
}
+ },
+ {
+ "name": "reveal",
+ "required": true,
+ "in": "query",
+ "schema": {
+ "type": "boolean"
+ }
}
],
"responses": {
@@ -1526,6 +1652,11 @@
"schema": {
"type": "object",
"properties": {
+ "type": {
+ "nullable": true,
+ "type": "string",
+ "enum": ["publishable", "secret", "legacy"]
+ },
"name": {
"type": "string"
},
@@ -1536,10 +1667,6 @@
"type": "string",
"nullable": true
},
- "type": {
- "nullable": true,
- "type": "object"
- },
"prefix": {
"type": "string",
"nullable": true
@@ -3238,7 +3365,15 @@
"type": "string"
}
},
- "required": ["id", "organization_id", "name", "region", "created_at", "status"]
+ "required": [
+ "id",
+ "organization_id",
+ "name",
+ "region",
+ "created_at",
+ "database",
+ "status"
+ ]
}
}
}
@@ -8045,6 +8180,14 @@
"schema": {
"type": "string"
}
+ },
+ {
+ "name": "resource_multiplier",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "type": "string"
+ }
}
],
"requestBody": {
@@ -8066,6 +8209,9 @@
},
"verify_jwt": {
"type": "boolean"
+ },
+ "resource_multiplier": {
+ "type": "string"
}
},
"required": ["slug", "name", "body"]
@@ -8087,6 +8233,9 @@
},
"verify_jwt": {
"type": "boolean"
+ },
+ "resource_multiplier": {
+ "type": "string"
}
},
"required": ["slug", "name", "body"]
@@ -8137,6 +8286,9 @@
},
"import_map_path": {
"type": "string"
+ },
+ "resource_multiplier": {
+ "type": "string"
}
},
"required": [
@@ -8228,6 +8380,9 @@
},
"import_map_path": {
"type": "string"
+ },
+ "resource_multiplier": {
+ "type": "string"
}
},
"required": [
@@ -8330,6 +8485,9 @@
},
"import_map_path": {
"type": "string"
+ },
+ "resource_multiplier": {
+ "type": "string"
}
},
"required": [
@@ -8433,6 +8591,14 @@
"schema": {
"type": "string"
}
+ },
+ {
+ "name": "resource_multiplier",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "type": "string"
+ }
}
],
"requestBody": {
@@ -8450,6 +8616,9 @@
},
"verify_jwt": {
"type": "boolean"
+ },
+ "resource_multiplier": {
+ "type": "string"
}
}
}
@@ -8466,6 +8635,9 @@
},
"verify_jwt": {
"type": "boolean"
+ },
+ "resource_multiplier": {
+ "type": "string"
}
}
}
@@ -8515,6 +8687,9 @@
},
"import_map_path": {
"type": "string"
+ },
+ "resource_multiplier": {
+ "type": "string"
}
},
"required": [
@@ -10018,7 +10193,7 @@
},
"required": ["host", "version", "postgres_engine", "release_channel"]
},
- "V1ProjectResponse": {
+ "V1ProjectWithDatabaseResponse": {
"type": "object",
"properties": {
"id": {
@@ -10086,33 +10261,9 @@
"type": "string"
}
},
- "required": ["id", "organization_id", "name", "region", "created_at", "status"]
+ "required": ["id", "organization_id", "name", "region", "created_at", "database", "status"]
},
- "DesiredInstanceSize": {
- "type": "string",
- "enum": [
- "micro",
- "small",
- "medium",
- "large",
- "xlarge",
- "2xlarge",
- "4xlarge",
- "8xlarge",
- "12xlarge",
- "16xlarge"
- ]
- },
- "ReleaseChannel": {
- "type": "string",
- "enum": ["internal", "alpha", "beta", "ga", "withdrawn"]
- },
- "PostgresEngine": {
- "type": "string",
- "description": "Postgres engine version. If not provided, the latest version will be used.",
- "enum": ["15"]
- },
- "V1CreateProjectBody": {
+ "V1CreateProjectBodyDto": {
"type": "object",
"properties": {
"db_pass": {
@@ -10130,12 +10281,12 @@
"plan": {
"type": "string",
"enum": ["free", "pro"],
- "description": "Subscription Plan is now set on organization level and is ignored in this request",
- "example": "free",
- "deprecated": true
+ "deprecated": true,
+ "description": "Subscription Plan is now set on organization level and is ignored in this request"
},
"region": {
"type": "string",
+ "description": "Region you want your server to reside in",
"enum": [
"us-east-1",
"us-east-2",
@@ -10155,9 +10306,7 @@
"ca-central-1",
"ap-south-1",
"sa-east-1"
- ],
- "description": "Region you want your server to reside in",
- "example": "us-east-1"
+ ]
},
"kps_enabled": {
"type": "boolean",
@@ -10181,20 +10330,71 @@
},
"template_url": {
"type": "string",
+ "format": "uri",
"description": "Template URL used to create the project from the CLI.",
"example": "https://github.com/supabase/supabase/tree/master/examples/slack-clone/nextjs-slack-clone"
},
"release_channel": {
"type": "string",
- "enum": ["internal", "alpha", "beta", "ga", "withdrawn"]
+ "enum": ["internal", "alpha", "beta", "ga", "withdrawn"],
+ "description": "Release channel. If not provided, GA will be used."
},
"postgres_engine": {
"type": "string",
- "description": "Postgres engine version. If not provided, the latest version will be used.",
- "enum": ["15"]
+ "enum": ["15"],
+ "description": "Postgres engine version. If not provided, the latest version will be used."
}
},
- "required": ["db_pass", "name", "organization_id", "region"]
+ "required": ["db_pass", "name", "organization_id", "region"],
+ "additionalProperties": false
+ },
+ "V1ProjectResponse": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Id of your project"
+ },
+ "organization_id": {
+ "type": "string",
+ "description": "Slug of your organization"
+ },
+ "name": {
+ "type": "string",
+ "description": "Name of your project"
+ },
+ "region": {
+ "type": "string",
+ "description": "Region of your project",
+ "example": "us-east-1"
+ },
+ "created_at": {
+ "type": "string",
+ "description": "Creation timestamp",
+ "example": "2023-03-29T16:32:59Z"
+ },
+ "status": {
+ "enum": [
+ "ACTIVE_HEALTHY",
+ "ACTIVE_UNHEALTHY",
+ "COMING_UP",
+ "GOING_DOWN",
+ "INACTIVE",
+ "INIT_FAILED",
+ "REMOVED",
+ "RESTARTING",
+ "UNKNOWN",
+ "UPGRADING",
+ "PAUSING",
+ "RESTORING",
+ "RESTORE_FAILED",
+ "PAUSE_FAILED",
+ "RESIZING"
+ ],
+ "type": "string"
+ }
+ },
+ "required": ["id", "organization_id", "name", "region", "created_at", "status"]
},
"OrganizationResponseV1": {
"type": "object",
@@ -10208,14 +10408,15 @@
},
"required": ["id", "name"]
},
- "CreateOrganizationBodyV1": {
+ "CreateOrganizationV1Dto": {
"type": "object",
"properties": {
"name": {
"type": "string"
}
},
- "required": ["name"]
+ "required": ["name"],
+ "additionalProperties": false
},
"OAuthTokenBody": {
"type": "object",
@@ -10577,6 +10778,11 @@
"ApiKeyResponse": {
"type": "object",
"properties": {
+ "type": {
+ "nullable": true,
+ "type": "string",
+ "enum": ["publishable", "secret", "legacy"]
+ },
"name": {
"type": "string"
},
@@ -10587,10 +10793,6 @@
"type": "string",
"nullable": true
},
- "type": {
- "nullable": true,
- "type": "object"
- },
"prefix": {
"type": "string",
"nullable": true
@@ -10679,6 +10881,30 @@
}
}
},
+ "DesiredInstanceSize": {
+ "type": "string",
+ "enum": [
+ "micro",
+ "small",
+ "medium",
+ "large",
+ "xlarge",
+ "2xlarge",
+ "4xlarge",
+ "8xlarge",
+ "12xlarge",
+ "16xlarge"
+ ]
+ },
+ "ReleaseChannel": {
+ "type": "string",
+ "enum": ["internal", "alpha", "beta", "ga", "withdrawn"]
+ },
+ "PostgresEngine": {
+ "type": "string",
+ "description": "Postgres engine version. If not provided, the latest version will be used.",
+ "enum": ["15"]
+ },
"CreateBranchBody": {
"type": "object",
"properties": {
@@ -13596,6 +13822,9 @@
},
"verify_jwt": {
"type": "boolean"
+ },
+ "resource_multiplier": {
+ "type": "string"
}
},
"required": ["slug", "name", "body"]
@@ -13638,6 +13867,9 @@
},
"import_map_path": {
"type": "string"
+ },
+ "resource_multiplier": {
+ "type": "string"
}
},
"required": ["version", "created_at", "updated_at", "id", "slug", "name", "status"]
@@ -13680,6 +13912,9 @@
},
"import_map_path": {
"type": "string"
+ },
+ "resource_multiplier": {
+ "type": "string"
}
},
"required": ["version", "created_at", "updated_at", "id", "slug", "name", "status"]
@@ -13695,6 +13930,9 @@
},
"verify_jwt": {
"type": "boolean"
+ },
+ "resource_multiplier": {
+ "type": "string"
}
}
},
diff --git a/apps/studio/components/grid/components/header/Header.tsx b/apps/studio/components/grid/components/header/Header.tsx
index 45c69218f99..1b414f79ff1 100644
--- a/apps/studio/components/grid/components/header/Header.tsx
+++ b/apps/studio/components/grid/components/header/Header.tsx
@@ -7,7 +7,6 @@ import { toast } from 'sonner'
import { useDispatch, useTrackedState } from 'components/grid/store/Store'
import type { Filter, Sort, SupaTable } from 'components/grid/types'
-import { Markdown } from 'components/interfaces/Markdown'
import { formatTableRowsToSQL } from 'components/interfaces/TableGridEditor/TableEntity.utils'
import { useProjectContext } from 'components/layouts/ProjectLayout/ProjectContext'
import { ButtonTooltip } from 'components/ui/ButtonTooltip'
@@ -31,12 +30,22 @@ import {
} from 'ui'
import FilterPopover from './filter/FilterPopover'
import { SortPopover } from './sort'
+import Link from 'next/link'
// [Joshen] CSV exports require this guard as a fail-safe if the table is
// just too large for a browser to keep all the rows in memory before
// exporting. Either that or export as multiple CSV sheets with max n rows each
export const MAX_EXPORT_ROW_COUNT = 500000
-export const MAX_EXPORT_ROW_COUNT_MESSAGE = `Sorry! We're unable to support exporting row counts larger than ${MAX_EXPORT_ROW_COUNT.toLocaleString()} at the moment. Alternatively, you may consider using [pg_dump](https://supabase.com/docs/reference/cli/supabase-db-dump) via our CLI instead.`
+export const MAX_EXPORT_ROW_COUNT_MESSAGE = (
+ <>
+ Sorry! We're unable to support exporting row counts larger than $
+ {MAX_EXPORT_ROW_COUNT.toLocaleString()} at the moment. Alternatively, you may consider using
+
+ pg_dump
+ {' '}
+ via our CLI instead.
+ >
+)
export type HeaderProps = {
table: SupaTable
@@ -290,7 +299,9 @@ const RowHeader = ({ table, sorts, filters }: RowHeaderProps) => {
setIsExporting(true)
if (allRowsSelected && totalRows > MAX_EXPORT_ROW_COUNT) {
- toast.error()
+ toast.error(
+
+ )
return setIsExporting(false)
}
diff --git a/apps/studio/components/interfaces/App/FeaturePreview/AssistantV2Preview.tsx b/apps/studio/components/interfaces/App/FeaturePreview/AssistantV2Preview.tsx
new file mode 100644
index 00000000000..a10d9531f87
--- /dev/null
+++ b/apps/studio/components/interfaces/App/FeaturePreview/AssistantV2Preview.tsx
@@ -0,0 +1,55 @@
+import Image from 'next/image'
+
+import { useParams } from 'common'
+import { Markdown } from 'components/interfaces/Markdown'
+import { BASE_PATH } from 'lib/constants'
+import { detectOS } from 'lib/helpers'
+
+export const AssistantV2Preview = () => {
+ const os = detectOS()
+ const { ref } = useParams()
+
+ return (
+
+
+ We're changing the way our AI Assistant integrates with the dashboard by making it shared
+ and accessible universally across the whole dashboard. This hopes to make using the
+ Assistant as a supporting tool more seamless while you build your project.
+
+
+
+ The Assistant will also be automatically provided with contexts depending on where you are
+ in the dashboard to generate more relevant and higher quality outputs. You may also ask for
+ insights on your own data apart from help with SQL and Postgres!
+
+
+ We believe that this should further lower the barrier of working with databases especially
+ if you're not well acquainted with Postgres (yet!), so please do feel free to let us know
+ what you think in the attached GitHub discussion above!
+
- We're providing an additional alternative UX to creating database functions through the
- dashboard with the integration of our AI Assistant that you might have seen in the Auth
- Policies section.
-
-
-
- This preview also shares an improved Assistant interface where you may provide the Assistant
- with contexts in hopes to generate more relevant and higher quality outputs. Contexts that
- you may provide include specific schemas, and / or specific tables from your database.
-
-
- We'd hope to use this as a consistent pattern throughout the dashboard eventually if this
- feature preview proves itself to benefit most of our users, so as usual please do feel free
- to let us know what you think if the attached GitHub discussion above!
-
+
+ {isAssistantV2Enabled && (
+ {
+ const sql = generatePolicyCreateSQL(policy)
+ setAiAssistantPanel({
+ open: true,
+ sqlSnippets: [sql],
+ initialInput: `Update the policy with name "${policy.name}" in the ${policy.schema} schema on the ${policy.table} table. It should...`,
+ suggestions: {
+ title: `I can help you make a change to the policy "${policy.name}" in the ${policy.schema} schema on the ${policy.table} table, here are a few example prompts to get you started:`,
+ prompts: [
+ 'Tell me how I can improve this policy...',
+ 'Duplicate this policy for another table...',
+ 'Add extra conditions to this policy...',
+ ],
+ },
+ })
+ }}
+ >
+
+
- Enter a time within the available range to restore from. Backups
- are captured every 2 minutes, allowing you to enter a time and restore
- your database to the closest backup point. We'll match the time you
- enter to the closest backup within the 2-minute window
-
-
-
-
- {isSelectedOnEarliestDay && (
-
- Earliest backup available for this date:{' '}
- {earliestAvailableBackup.format('HH:mm:ss')}
-
- )}
- {isSelectedOnLatestDay && (
-
- Latest backup available for this date:{' '}
- {latestAvailableBackup.format('HH:mm:ss')}
-
+ Enter a time within the available range to restore from. Backups are
+ captured every 2 minutes, allowing you to enter a time and restore your
+ database to the closest backup point. We'll match the time you enter to the
+ closest backup within the 2-minute window
+
+
+
+
+ {isSelectedOnEarliestDay && (
+
+ Earliest backup available for this date:{' '}
+ {earliestAvailableBackup.format('HH:mm:ss')}
+
+ )}
+ {isSelectedOnLatestDay && (
+
+ Latest backup available for this date:{' '}
+ {latestAvailableBackup.format('HH:mm:ss')}
+
+ )}
+
+
+
+ )}
+
+
+
+
+ )
+}
diff --git a/apps/studio/components/interfaces/Database/Backups/RestoreToNewProject/AdditionalMonthlySpend.tsx b/apps/studio/components/interfaces/Database/Backups/RestoreToNewProject/AdditionalMonthlySpend.tsx
new file mode 100644
index 00000000000..d78b34b0846
--- /dev/null
+++ b/apps/studio/components/interfaces/Database/Backups/RestoreToNewProject/AdditionalMonthlySpend.tsx
@@ -0,0 +1,45 @@
+import { instanceSizeSpecs } from 'data/projects/new-project.constants'
+import { useProjectContext } from 'components/layouts/ProjectLayout/ProjectContext'
+
+export const AdditionalMonthlySpend = () => {
+ const { project } = useProjectContext()
+
+ /**
+ * New project will have the same compute size and disk size as the original project
+ */
+ function getAdditionalMonthlySpend() {
+ const currentProjectComputeSize = project?.infra_compute_size
+ if (!currentProjectComputeSize) {
+ return null
+ }
+
+ if (currentProjectComputeSize === 'nano') {
+ return null
+ }
+
+ const additionalMonthlySpend = instanceSizeSpecs[currentProjectComputeSize]
+
+ return additionalMonthlySpend
+ }
+
+ const additionalMonthlySpend = getAdditionalMonthlySpend()
+ if (!additionalMonthlySpend) {
+ return null
+ }
+
+ return (
+
+
+ The new project will have the same compute size and disk size as this project. You will be
+ able to update the compute size and disk size after the new project is created in{' '}
+
+ Project Settings > Compute and Disk
+
+
- {enableAssistantV2 && (
+ {isAssistantV2Enabled && (
{
- setAiAssistantPanel({ open: true, editor: 'functions', entity: x })
+ setAiAssistantPanel({
+ open: true,
+ initialInput: 'Update this function to do...',
+ suggestions: {
+ title:
+ 'I can help you make a change to this function, here are a few example prompts to get you started:',
+ prompts: [
+ 'Rename this function to ...',
+ 'Modify this function so that it ...',
+ 'Add a trigger for this function that calls it when ...',
+ ],
+ },
+ sqlSnippets: [x.complete_statement],
+ })
}}
>
diff --git a/apps/studio/components/interfaces/Database/Functions/FunctionsList/FunctionsList.tsx b/apps/studio/components/interfaces/Database/Functions/FunctionsList/FunctionsList.tsx
index 56b09f32faf..5b0e7b1de75 100644
--- a/apps/studio/components/interfaces/Database/Functions/FunctionsList/FunctionsList.tsx
+++ b/apps/studio/components/interfaces/Database/Functions/FunctionsList/FunctionsList.tsx
@@ -5,7 +5,7 @@ import { Search } from 'lucide-react'
import { useRouter } from 'next/router'
import { useParams } from 'common'
-import { useIsDatabaseFunctionsAssistantEnabled } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext'
+import { useIsAssistantV2Enabled } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext'
import { useProjectContext } from 'components/layouts/ProjectLayout/ProjectContext'
import ProductEmptyState from 'components/to-be-cleaned/ProductEmptyState'
import Table from 'components/to-be-cleaned/Table'
@@ -38,7 +38,7 @@ const FunctionsList = ({
const { search } = useParams()
const { project } = useProjectContext()
const { setAiAssistantPanel } = useAppStateSnapshot()
- const enableFunctionsAssistant = useIsDatabaseFunctionsAssistantEnabled()
+ const isAssistantV2Enabled = useIsAssistantV2Enabled()
const { selectedSchema, setSelectedSchema } = useQuerySchemaState()
const filterString = search ?? ''
@@ -104,10 +104,10 @@ const FunctionsList = ({
) : (