Getting Started
Discover how to set up a database to an app making queries in just a few minutes.
diff --git a/apps/docs/public/humans.txt b/apps/docs/public/humans.txt
index 95817e22f6d..2231880862b 100644
--- a/apps/docs/public/humans.txt
+++ b/apps/docs/public/humans.txt
@@ -34,6 +34,7 @@ Kevin Grüneberg
Lakshmipathi G
Laura C
Leo T
+Long Hoang
Margarita Sandomirskaia
Marijana Šimag
Mark Burggraf
@@ -60,7 +61,7 @@ ____________
JOBS
-If you are interested in working with us check out the open roles here: https://about.supabase.com/careers
+If you are interested in working with us check out the open roles here: https://supabase.com/careers
___________
diff --git a/apps/www/data/Developers.json b/apps/www/data/Developers.json
index a29460f0c5b..df449e784ab 100644
--- a/apps/www/data/Developers.json
+++ b/apps/www/data/Developers.json
@@ -1,26 +1,20 @@
[
{
"text": "Documentation",
- "description": "Everything you need that makes it simple to get started.",
+ "description": "Everything you need to start building with Supabase.",
"url": "/docs",
"icon": "M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"
},
{
- "text": "API reference",
- "description": "Examples and references for using API libraries.",
- "url": "/docs/client/supabase-client",
- "icon": "M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4"
- },
- {
- "text": "Guides",
- "description": "Examples and references for using Supabase.",
- "url": "/docs/",
+ "text": "Changelog",
+ "description": "See the latest updates and product improvements.",
+ "url": "/changelog",
"icon": "M19.428 15.428a2 2 0 00-1.022-.547l-2.387-.477a6 6 0 00-3.86.517l-.318.158a6 6 0 01-3.86.517L6.05 15.21a2 2 0 00-1.806.547M8 4h8l-1 1v5.172a2 2 0 00.586 1.414l5 5c1.26 1.26.367 3.414-1.415 3.414H4.828c-1.782 0-2.674-2.154-1.414-3.414l5-5A2 2 0 009 10.172V5L8 4z"
},
{
"text": "Careers",
"description": "Join the Supabase team and get involved.",
- "url": "https://supabase.com/careers",
+ "url": "/careers",
"icon": "M21 13.255A23.931 23.931 0 0112 15c-3.183 0-6.22-.62-9-1.745M16 6V4a2 2 0 00-2-2h-4a2 2 0 00-2 2v2m4 6h.01M5 20h14a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"
}
]
diff --git a/apps/www/lib/redirects.js b/apps/www/lib/redirects.js
index 09317c8a31f..ff18f604298 100644
--- a/apps/www/lib/redirects.js
+++ b/apps/www/lib/redirects.js
@@ -1787,16 +1787,6 @@ module.exports = [
source: '/docs/guides/with-ionic-angular',
destination: '/docs/guides/getting-started/tutorials/with-ionic-angular',
},
- {
- permanent: true,
- source: '/docs/guides/examples',
- destination: '/docs/guides/resources/examples',
- },
- {
- permanent: true,
- source: '/docs/guides/examples',
- destination: '/docs/guides/resources/examples',
- },
{
permanent: true,
source: '/docs/guides/hosting/overview',
diff --git a/spec/common-self-hosting-storage-sections.json b/spec/common-self-hosting-storage-sections.json
index 323772b2a6a..cdcd9bcf537 100644
--- a/spec/common-self-hosting-storage-sections.json
+++ b/spec/common-self-hosting-storage-sections.json
@@ -135,13 +135,6 @@
"summary": "Retrieve object info",
"type": "operation"
},
- {
- "id": "retrieve-object-info",
- "title": "Retrieve object info",
- "slug": "retrieve-object-info",
- "summary": "Retrieve object info",
- "type": "operation"
- },
{
"id": "copies-an-object",
"title": "Copies an object",
diff --git a/studio/components/interfaces/Billing/EnterpriseUpdate.tsx b/studio/components/interfaces/Billing/EnterpriseUpdate.tsx
index 078cd190f42..254d83275c7 100644
--- a/studio/components/interfaces/Billing/EnterpriseUpdate.tsx
+++ b/studio/components/interfaces/Billing/EnterpriseUpdate.tsx
@@ -137,6 +137,25 @@ const EnterpriseUpdate: FC
= ({
captchaRef.current?.resetCaptcha()
}
+ const beforeConfirmPayment = async (): Promise => {
+ setIsSubmitting(true)
+ let token = captchaToken
+
+ try {
+ if (!token) {
+ const captchaResponse = await captchaRef.current?.execute({ async: true })
+ token = captchaResponse?.response ?? null
+ setCaptchaToken(token)
+ }
+ } catch (error) {
+ setIsSubmitting(false)
+ return false
+ }
+
+ setIsSubmitting(false)
+ return true
+ }
+
// Last todo to support enterprise billing on dashboard + E2E test
const onConfirmPayment = async () => {
setIsSubmitting(true)
@@ -296,6 +315,7 @@ const EnterpriseUpdate: FC = ({
onSelectAddNewPaymentMethod={() => {
setShowAddPaymentMethodModal(true)
}}
+ beforeConfirmPayment={beforeConfirmPayment}
onConfirmPayment={onConfirmPayment}
captcha={
void
onSelectAddNewPaymentMethod: () => void
+ beforeConfirmPayment: () => Promise
onConfirmPayment: () => void
isSubmitting: boolean
@@ -72,6 +73,7 @@ const PaymentSummaryPanel: FC = ({
isLoadingPaymentMethods,
onSelectPaymentMethod,
onSelectAddNewPaymentMethod,
+ beforeConfirmPayment,
onConfirmPayment,
isSubmitting,
captcha,
@@ -132,16 +134,23 @@ const PaymentSummaryPanel: FC = ({
message: error,
})
} else {
- isChangingComputeSize || (isChangingPITRDuration && selectedPITRDays === 0)
- ? setShowConfirmModal(true)
- : onConfirmPayment()
+ // [Joshen] We're validating captcha before subsequent actions as there's an issue
+ // with the hcaptcha overlay and the modal component, such that clicking on the hcaptcha closes
+ // both the hcaptcha overlay and the modal. Need to figure that out first, then we can validate
+ // the hcaptcha within onConfirmPayment()
+ const hasValidCaptcha = await beforeConfirmPayment()
+ if (hasValidCaptcha) {
+ isChangingComputeSize || (isChangingPITRDuration && selectedPITRDays === 0)
+ ? setShowConfirmModal(true)
+ : onConfirmPayment()
+ }
}
}
return (
<>
Payment Summary
@@ -296,7 +305,7 @@ const PaymentSummaryPanel: FC
= ({
)}
-
+
= ({
Select payment method
{isLoadingPaymentMethods ? (
-
+
Retrieving payment methods
) : paymentMethods.length === 0 ? (
-
+
No saved payment methods
@@ -373,11 +382,11 @@ const PaymentSummaryPanel: FC
= ({
)
})}
-
+
Add new payment method
diff --git a/studio/components/interfaces/Billing/ProUpgrade.tsx b/studio/components/interfaces/Billing/ProUpgrade.tsx
index e7f246d8b27..2f05f9a8844 100644
--- a/studio/components/interfaces/Billing/ProUpgrade.tsx
+++ b/studio/components/interfaces/Billing/ProUpgrade.tsx
@@ -158,7 +158,7 @@ const ProUpgrade: FC = ({
captchaRef.current?.resetCaptcha()
}
- const onConfirmPayment = async () => {
+ const beforeConfirmPayment = async (): Promise => {
setIsSubmitting(true)
let token = captchaToken
@@ -166,12 +166,18 @@ const ProUpgrade: FC = ({
if (!token) {
const captchaResponse = await captchaRef.current?.execute({ async: true })
token = captchaResponse?.response ?? null
+ setCaptchaToken(token)
}
} catch (error) {
setIsSubmitting(false)
- return
+ return false
}
+ setIsSubmitting(false)
+ return true
+ }
+
+ const onConfirmPayment = async () => {
const payload = formSubscriptionUpdatePayload(
currentSubscription,
selectedTier,
@@ -179,7 +185,7 @@ const ProUpgrade: FC = ({
nonChangeableAddons,
selectedPaymentMethodId,
projectRegion,
- token ?? undefined
+ captchaToken ?? undefined
)
const res = await patch(`${API_URL}/projects/${projectRef}/subscription`, payload)
resetCaptcha()
@@ -223,17 +229,17 @@ const ProUpgrade: FC = ({
enter="transition ease-out duration-300"
enterFrom="transform opacity-0 translate-x-10"
enterTo="transform opacity-100 translate-x-0"
- className="flex w-full items-start justify-between"
+ className="flex items-start justify-between w-full"
>
-
+
onSelectBack()} />
Change your project's subscription
@@ -257,14 +263,14 @@ const ProUpgrade: FC
= ({
>
)}
-
+
Enable spend cap
setShowSpendCapHelperModal(true)}
/>
@@ -342,6 +348,7 @@ const ProUpgrade: FC
= ({
onSelectAddNewPaymentMethod={() => {
setShowAddPaymentMethodModal(true)
}}
+ beforeConfirmPayment={beforeConfirmPayment}
onConfirmPayment={onConfirmPayment}
isSubmitting={isSubmitting}
captcha={
@@ -375,7 +382,7 @@ const ProUpgrade: FC = ({
header="Enabling spend cap"
onCancel={() => setShowSpendCapHelperModal(false)}
>
-
+
@@ -390,7 +397,7 @@ const ProUpgrade: FC = ({
{/* Maybe instead of a table, show something more interactive like a spend cap playground */}
{/* Maybe ideate this in Figma first but this is good enough for now */}
-
+
Item
Limit
@@ -417,7 +424,7 @@ const ProUpgrade: FC
= ({
diff --git a/studio/components/interfaces/SQLEditor/SQLEditor.constants.ts b/studio/components/interfaces/SQLEditor/SQLEditor.constants.ts
index 63ec9612ed2..de1990ca96b 100644
--- a/studio/components/interfaces/SQLEditor/SQLEditor.constants.ts
+++ b/studio/components/interfaces/SQLEditor/SQLEditor.constants.ts
@@ -812,7 +812,7 @@ create publication supabase_realtime
sql: `
-- Create a table for public profiles
create table profiles (
- id uuid references auth.users not null primary key,
+ id uuid references auth.users on delete cascade not null primary key,
updated_at timestamp with time zone,
username text unique,
full_name text,
diff --git a/studio/components/layouts/StorageLayout/StorageMenu.tsx b/studio/components/layouts/StorageLayout/StorageMenu.tsx
index dc41cdacb64..2889292f42f 100644
--- a/studio/components/layouts/StorageLayout/StorageMenu.tsx
+++ b/studio/components/layouts/StorageLayout/StorageMenu.tsx
@@ -122,8 +122,10 @@ const BucketRow = ({
- {bucket.name}
+
+
+ {bucket.name}
+
{bucket.public &&
Public}
}
diff --git a/studio/components/to-be-cleaned/Storage/StorageExplorer/FileExplorerHeader.js b/studio/components/to-be-cleaned/Storage/StorageExplorer/FileExplorerHeader.js
index 139a0be29cb..ad57ec629c1 100644
--- a/studio/components/to-be-cleaned/Storage/StorageExplorer/FileExplorerHeader.js
+++ b/studio/components/to-be-cleaned/Storage/StorageExplorer/FileExplorerHeader.js
@@ -34,7 +34,7 @@ const HeaderPathEdit = ({ loading, breadcrumbs, togglePathEdit }) => {
) : (
-
{breadcrumbs[breadcrumbs.length - 1] || ''}
+
{breadcrumbs[breadcrumbs.length - 1] || ''}
}>
Navigate
@@ -224,6 +224,7 @@ const FileExplorerHeader = ({
autoFocus
key="pathSet"
type="text"
+ size="small"
value={pathString}
onChange={onUpdatePathString}
placeholder="e.g Parent Folder/Child Folder"
diff --git a/studio/components/ui/ProductMenu/ProductMenuItem.tsx b/studio/components/ui/ProductMenu/ProductMenuItem.tsx
index 49c57997a3c..82808c4c391 100644
--- a/studio/components/ui/ProductMenu/ProductMenuItem.tsx
+++ b/studio/components/ui/ProductMenu/ProductMenuItem.tsx
@@ -31,16 +31,16 @@ const ProductMenuItem: FC
= ({
}) => {
const menuItem = (
-
-
+
{name}{' '}
{label !== undefined && (
{label}
)}
-
+
{action}
diff --git a/studio/stores/pgmeta/MetaStore.ts b/studio/stores/pgmeta/MetaStore.ts
index a8ed860a318..eef317f1397 100644
--- a/studio/stores/pgmeta/MetaStore.ts
+++ b/studio/stores/pgmeta/MetaStore.ts
@@ -154,7 +154,6 @@ export default class MetaStore implements IMetaStore {
'extensions',
'information_schema',
'net',
- 'pg_catalog',
'pgsodium',
'pgsodium_masks',
'pgbouncer',
diff --git a/studio/stores/pgmeta/SchemaStore.ts b/studio/stores/pgmeta/SchemaStore.ts
index 7a0082db225..1fd1ff89ac5 100644
--- a/studio/stores/pgmeta/SchemaStore.ts
+++ b/studio/stores/pgmeta/SchemaStore.ts
@@ -27,6 +27,14 @@ export default class SchemaStore extends PostgresMetaInterface {
this.views = []
}
+ // Dashboard to hide schemas with pg_ prefix
+ list(filter: any) {
+ const schemasFilter = (schema: PostgresSchema) =>
+ !schema.name.startsWith('pg_') && (typeof filter === 'function' ? filter(schema) : true)
+
+ return super.list(schemasFilter)
+ }
+
async loadViews(schema: string) {
const query = `
select schemaname as schema, viewname as name from pg_catalog.pg_views
diff --git a/studio/stores/pgmeta/TriggersStore.ts b/studio/stores/pgmeta/TriggersStore.ts
index 4d83608c885..91631e94f7f 100644
--- a/studio/stores/pgmeta/TriggersStore.ts
+++ b/studio/stores/pgmeta/TriggersStore.ts
@@ -20,8 +20,8 @@ export default class TriggersStore extends PostgresMetaInterface {
*/
list(filter: any) {
const triggersFilter = (h: any) =>
- h.function_schema != 'supabase_functions' &&
- h.schema != 'net' &&
+ h.function_schema !== 'supabase_functions' &&
+ h.schema !== 'net' &&
(typeof filter === 'function' ? filter(h) : true)
return super.list(triggersFilter)