Merge branch 'master' into chore/swr-to-react-query-1

This commit is contained in:
Alaister Young committed 2023-01-31 20:00:43 +11:00
commit 32aa687da3
76 files changed
+29143 -23654

No files matched your search

+3 -1
View File
@@ -6,6 +6,7 @@ import { Button, IconCheck, IconCopy } from 'ui'
import js from 'react-syntax-highlighter/dist/cjs/languages/hljs/javascript'
import ts from 'react-syntax-highlighter/dist/cjs/languages/hljs/typescript'
import csharp from 'react-syntax-highlighter/dist/cjs/languages/hljs/csharp'
import py from 'react-syntax-highlighter/dist/cjs/languages/hljs/python'
import sql from 'react-syntax-highlighter/dist/cjs/languages/hljs/sql'
import bash from 'react-syntax-highlighter/dist/cjs/languages/hljs/bash'
@@ -17,7 +18,7 @@ import { useTheme } from 'common/Providers'
interface Props {
title?: string
language: 'js' | 'jsx' | 'sql' | 'py' | 'bash' | 'ts' | 'dart' | 'json'
language: 'js' | 'jsx' | 'sql' | 'py' | 'bash' | 'ts' | 'dart' | 'json' | 'csharp'
linesToHighlight?: number[]
hideCopy?: boolean
hideLineNumbers?: boolean
@@ -62,6 +63,7 @@ const CodeBlock: FC<Props> = ({
SyntaxHighlighter.registerLanguage('sql', sql)
SyntaxHighlighter.registerLanguage('bash', bash)
SyntaxHighlighter.registerLanguage('dart', dart)
SyntaxHighlighter.registerLanguage('csharp', csharp)
SyntaxHighlighter.registerLanguage('json', json)
const large = false
@@ -94,6 +94,12 @@ const home = [
href: '/reference/dart/introduction',
level: 'reference_dart',
},
{
label: 'C#',
icon: '/img/icons/menu/reference-csharp',
href: '/reference/csharp/introduction',
level: 'reference_csharp',
},
{
label: 'Python',
icon: '/img/icons/menu/reference-python',
@@ -22,6 +22,12 @@ export const REFERENCES: References = {
versions: ['v1', 'v0'],
icon: '/docs/img/libraries/flutter-icon.svg',
},
csharp: {
name: 'C#',
library: 'supabase-csharp',
versions: ['v0'],
icon: '/docs/img/libraries/c-sharp-icon.svg',
},
cli: {
name: 'CLI',
library: undefined,
@@ -739,6 +745,20 @@ export const reference = {
items: [],
icon: '/img/icons/menu/reference-dart',
},
{
name: 'supabase-csharp',
url: '/reference/csharp/start',
level: 'reference_csharp',
items: [],
icon: '/img/icons/menu/reference-csharp',
},
{
name: 'supbase-python',
url: '/reference/python/start',
level: 'reference_python',
items: [],
icon: 'docs/img/icons/javascript.svg',
},
// {
// name: 'supabase-python',
// url: '/reference/python/start',
@@ -788,6 +808,7 @@ export const reference_dart_v0 = {
url: '/guides/reference/dart',
parent: '/reference',
}
export const reference_dart_v1 = {
icon: 'reference-dart',
title: 'Flutter',
@@ -795,6 +816,14 @@ export const reference_dart_v1 = {
parent: '/reference',
}
export const reference_csharp_v0 = {
icon: 'reference-csharp',
title: 'c#',
url: 'guides/reference/csharp',
parent: '/reference',
}
export const reference_python_v2 = {
icon: 'reference-python',
title: 'Python',
@@ -895,6 +924,13 @@ export const references = [
icon: '/docs/img/icons/dart-icon.svg',
url: '/reference/dart/start',
},
{
label: 'supabase-csharp',
versions: ['v0'],
description: 'something about the reference',
icon: '/docs/img/icons/c-sharp-icon.svg',
url: '/reference/csharp/start',
},
],
},
{
@@ -12,6 +12,8 @@ import spec_dart_v1 from '~/../../spec/supabase_dart_v1.yml' assert { type: 'yml
// @ts-expect-error
import spec_dart_v0 from '~/../../spec/supabase_dart_v0.yml' assert { type: 'yml' }
// @ts-expect-error
import spec_csharp_v0 from '~/../../spec/supabase_csharp_v0.yml' assert { type: 'yml' }
// @ts-expect-error
import spec_python_v2 from '~/../../spec/supabase_py_v2.yml' assert { type: 'yml' }
// import { gen_v3 } from '~/lib/refGenerator/helpers'
@@ -50,6 +52,7 @@ export type RefIdOptions =
| 'reference_javascript_v2'
| 'reference_dart_v0'
| 'reference_dart_v1'
| 'reference_csharp_v0'
| 'reference_python_v2'
| 'reference_cli'
| 'reference_api'
@@ -60,6 +63,7 @@ export type RefIdOptions =
export type RefKeyOptions =
| 'javascript'
| 'dart'
| 'csharp'
| 'python'
| 'cli'
| 'api'
@@ -124,6 +128,10 @@ const NavigationMenu = () => {
case url.includes(`/docs/reference/dart`) && url:
menuState.setMenuLevelId('reference_dart_v1')
break
// C# v0 (latest)
case url.includes(`/docs/reference/csharp`) && url:
menuState.setMenuLevelId('reference_csharp_v0')
break
// puthon v2 (latest)
case url.includes(`/docs/reference/python`) && url:
menuState.setMenuLevelId('reference_python_v2')
@@ -181,6 +189,7 @@ const NavigationMenu = () => {
const isReference_Javascript_V2 = 'reference_javascript_v2' === level
const isReference_Dart_V0 = 'reference_dart_v0' === level
const isReference_Dart_V1 = 'reference_dart_v1' === level
const isReference_Csharp_V0 = 'reference_csharp_v0' === level
const isReference_Python_V2 = 'reference_python_v2' === level
const isReference_Cli = 'reference_cli' === level
const isReference_Api = 'reference_api' === level
@@ -237,6 +246,15 @@ const NavigationMenu = () => {
lib="dart"
spec={spec_dart_v1}
/>
<NavigationMenuRefList
key={'reference-csharp-menu-v0'}
id={'reference_csharp_v0'}
active={isReference_Csharp_V0}
commonSections={libCommonSections}
lib="csharp"
spec={spec_csharp_v0}
/>
<NavigationMenuRefList
key={'reference-python-menu-v2'}
id={'reference_python_v2'}
@@ -244,6 +262,7 @@ const NavigationMenu = () => {
commonSections={libCommonSections}
lib="python"
spec={spec_python_v2}
/>
{/* // Tools */}
<NavigationMenuRefList
@@ -122,6 +122,8 @@ const RefFunctionSection: React.FC<IRefFunctionSection> = (props) => {
? 'ts'
: example?.code?.startsWith('```dart')
? 'dart'
: example?.code?.startsWith('```c#')
? 'csharp'
: 'js'
// `
// import { createClient } from '@supabase/supabase-js'
@@ -154,7 +156,8 @@ const RefFunctionSection: React.FC<IRefFunctionSection> = (props) => {
.replace(/```/g, '')
.replace('js', '')
.replace('ts', '')
.replace('dart', ''))}
.replace('dart', '')
.replace('c#', ''))}
</CodeBlock>
{((tables && tables.length > 0) || sql) && (
+134
View File
@@ -0,0 +1,134 @@
const Nav = [
{
label: 'Getting Started',
items: [
{ name: 'Supabase C# Library', url: '/reference/csharp', items: [] },
{ name: 'Installing', url: '/reference/csharp/installing', items: [] },
{ name: 'Initializing', url: '/reference/csharp/initializing', items: [] },
],
},
{
label: 'Auth',
items: [
{ name: 'signUp()', url: '/reference/csharp/auth-signup', items: [] },
{
name: 'signInWithPassword()',
url: '/reference/csharp/auth-signinwithpassword',
items: [],
},
{ name: 'signInWithOtp()', url: '/reference/csharp/auth-signinwithotp', items: [] },
{ name: 'signInWithOAuth()', url: '/reference/csharp/auth-signinwithoauth', items: [] },
{ name: 'signOut()', url: '/reference/csharp/auth-signout', items: [] },
{ name: 'verifyOtp()', url: '/reference/csharp/auth-verifyotp', items: [] },
{ name: 'currentSession', url: '/reference/csharp/auth-currentsession', items: [] },
{ name: 'currentUser', url: '/reference/csharp/auth-currentuser', items: [] },
{ name: 'updateUser()', url: '/reference/csharp/auth-updateuser', items: [] },
{ name: 'onAuthStateChange()', url: '/reference/csharp/auth-onauthstatechange', items: [] },
{
name: 'resetPasswordForEmail()',
url: '/reference/csharp/auth-resetpasswordforemail',
items: [],
},
],
},
{
label: 'Functions',
items: [{ name: 'invoke()', url: '/reference/csharp/invoke', items: [] }],
},
{
label: 'Database',
items: [
{ name: 'Fetch data: select()', url: '/reference/csharp/select', items: [] },
{ name: 'Create data: insert()', url: '/reference/csharp/insert', items: [] },
{ name: 'Modify data: update()', url: '/reference/csharp/update', items: [] },
{ name: 'Upsert data: upsert()', url: '/reference/csharp/upsert', items: [] },
{ name: 'Delete data: delete()', url: '/reference/csharp/delete', items: [] },
{ name: 'Stored Procedures: rpc()', url: '/reference/csharp/rpc', items: [] },
{
name: 'Filters',
url: undefined,
items: [
{ name: 'Using Filters', url: '/reference/csharp/using-filters', items: [] },
{ name: 'eq()', url: '/reference/csharp/eq', items: [] },
{ name: 'neq()', url: '/reference/csharp/neq', items: [] },
{ name: 'gt()', url: '/reference/csharp/gt', items: [] },
{ name: 'gte()', url: '/reference/csharp/gte', items: [] },
{ name: 'lt()', url: '/reference/csharp/lt', items: [] },
{ name: 'lte()', url: '/reference/csharp/lte', items: [] },
{ name: 'like()', url: '/reference/csharp/like', items: [] },
{ name: 'ilike()', url: '/reference/csharp/ilike', items: [] },
{ name: 'is_()', url: '/reference/csharp/is_', items: [] },
{ name: 'in_()', url: '/reference/csharp/in_', items: [] },
{ name: 'contains()', url: '/reference/csharp/contains', items: [] },
{ name: 'containedBy()', url: '/reference/csharp/containedby', items: [] },
{ name: 'rangeGt()', url: '/reference/csharp/rangegt', items: [] },
{ name: 'rangeGte()', url: '/reference/csharp/rangegte', items: [] },
{ name: 'rangeLt()', url: '/reference/csharp/rangelt', items: [] },
{ name: 'rangeLte()', url: '/reference/csharp/rangelte', items: [] },
{ name: 'rangeAdjacent()', url: '/reference/csharp/rangeadjacent', items: [] },
{ name: 'overlaps()', url: '/reference/csharp/overlaps', items: [] },
{ name: 'textSearch()', url: '/reference/csharp/textsearch', items: [] },
{ name: 'match()', url: '/reference/csharp/match', items: [] },
{ name: 'not()', url: '/reference/csharp/not', items: [] },
{ name: 'or()', url: '/reference/csharp/or', items: [] },
{ name: 'filter()', url: '/reference/csharp/filter', items: [] },
],
},
{
name: 'Modifiers',
url: undefined,
items: [
{ name: 'Using Modifiers', url: '/reference/csharp/using-modifiers', items: [] },
{ name: 'order()', url: '/reference/csharp/order', items: [] },
{ name: 'limit()', url: '/reference/csharp/limit', items: [] },
{ name: 'range()', url: '/reference/csharp/range', items: [] },
{ name: 'single()', url: '/reference/csharp/single', items: [] },
],
},
],
},
{
label: 'Realtime',
items: [
{ name: 'stream()', url: '/reference/csharp/stream', items: [] },
{ name: 'on().subscribe()', url: '/reference/csharp/subscribe', items: [] },
{ name: 'removeChannel()', url: '/reference/csharp/removechannel', items: [] },
{ name: 'removeAllChannels()', url: '/reference/csharp/removeallchannels', items: [] },
{ name: 'getChannels()', url: '/reference/csharp/getchannels', items: [] },
],
},
{
label: 'Storage',
items: [
{ name: 'createBucket()', url: '/reference/csharp/storage-createbucket', items: [] },
{ name: 'getBucket()', url: '/reference/csharp/storage-getbucket', items: [] },
{ name: 'listBuckets()', url: '/reference/csharp/storage-listbuckets', items: [] },
{ name: 'updateBucket()', url: '/reference/csharp/storage-updatebucket', items: [] },
{ name: 'deleteBucket()', url: '/reference/csharp/storage-deletebucket', items: [] },
{ name: 'emptyBucket()', url: '/reference/csharp/storage-emptybucket', items: [] },
{ name: 'from.upload()', url: '/reference/csharp/storage-from-upload', items: [] },
{ name: 'from.download()', url: '/reference/csharp/storage-from-download', items: [] },
{ name: 'from.list()', url: '/reference/csharp/storage-from-list', items: [] },
{ name: 'from.update()', url: '/reference/csharp/storage-from-update', items: [] },
{ name: 'from.move()', url: '/reference/csharp/storage-from-move', items: [] },
{ name: 'from.remove()', url: '/reference/csharp/storage-from-remove', items: [] },
{
name: 'from.createSignedUrl()',
url: '/reference/csharp/storage-from-createsignedurl',
items: [],
},
{
name: 'from.createSignedUrls()',
url: '/reference/csharp/storage-from-createsignedurls',
items: [],
},
{
name: 'from.getPublicUrl()',
url: '/reference/csharp/storage-from-getpublicurl',
items: [],
},
],
},
]
export default Nav
@@ -13,6 +13,9 @@ const nonGeneratedReferencePages = [
'docs/reference/dart/initializing',
'docs/reference/dart/v0/upgrade-guide',
'docs/reference/dart/v0',
'docs/reference/csharp',
'docs/reference/csharp/installing',
'docs/reference/csharp/initializing',
'docs/reference/api',
'docs/reference/api/release-notes',
'docs/reference/cli',
@@ -0,0 +1,67 @@
---
id: initializing
title: 'Initializing'
slug: initializing
custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml
---
### Initializing a new Client
<RefSubLayout.EducationRow>
<RefSubLayout.Details>
Initializing a new client is pretty straightforward. Find your project url and public key from the
admin panel and pass it into your client initialization function.
</RefSubLayout.Details>
<RefSubLayout.Examples>
<Tabs
size="small"
type="underlined"
defaultActiveId="csharp-init-standard">
<TabPanel id="csharp-init-standard" label="Standard">
```csharp
var url = Environment.GetEnvironmentVariable("SUPABASE_URL");
var key = Environment.GetEnvironmentVariable("SUPABASE_KEY");
var options = new Supabase.SupabaseOptions
{
AutoConnectRealtime = true
};
var supabase = new Supabase.Client(url, key, options);
await supabase.InitializeAsync();
```
</TabPanel>
<TabPanel id="csharp-init-maui" label="Dependency Injection (Maui-like)">
```csharp
public static MauiApp CreateMauiApp()
{
// ...
var builder = MauiApp.CreateBuilder();
var url = Environment.GetEnvironmentVariable("SUPABASE_URL");
var key = Environment.GetEnvironmentVariable("SUPABASE_KEY");
var options = new SupabaseOptions
{
AutoRefreshToken = true,
AutoConnectRealtime = true,
SessionHandler = new SupabaseSessionHandler()
};
// Note the creation as a singleton.
builder.Services.AddSingleton(provider => new Supabase.Client(url, key, options));
}
```
</TabPanel>
</Tabs>
</RefSubLayout.Examples>
</RefSubLayout.EducationRow>
+33
View File
@@ -0,0 +1,33 @@
---
id: installing
title: 'Installing & Initialization'
slug: installing
custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml
---
### Install from NuGet
<RefSubLayout.EducationRow>
<RefSubLayout.Details>
You can install Supabase package from [nuget.org](https://www.nuget.org/packages/supabase-csharp/)
</RefSubLayout.Details>
<RefSubLayout.Examples>
<Tabs
size="small"
type="underlined"
defaultActiveId="csharp">
<TabPanel id="csharp" label="Terminal">
```sh Terminal
dotnet add package supabase-csharp
```
</TabPanel>
</Tabs>
</RefSubLayout.Examples>
</RefSubLayout.EducationRow>
@@ -0,0 +1,20 @@
---
id: introduction
title: Introduction
hideTitle: true
---
<div className="flex items-start gap-6 not-prose" id="introduction">
<img src="/docs/img/icons/menu/reference-csharp.svg" className="w-8 h-8 rounded" />
<div className="flex flex-col gap-2">
<h1 className="text-3xl text-scale-1200 m-0">C# Client Library</h1>
<h2 className="text-base font-mono text-scale-1100">supabase-csharp</h2>
</div>
</div>
<div className="max-w-xl">
This reference documents every object and method available in Supabase's C#
library, [supabase-csharp](https://www.nuget.org/packages/supabase-csharp). You can
use supabase-csharp to interact with your Postgres database, listen to database changes, invoke
Deno Edge Functions, build login and user management functionality, and manage large files.
</div>
+173
View File
@@ -0,0 +1,173 @@
---
id: release-notes
title: Release Notes
---
## 0.7.0 - 2023-01-16
- Update dependency: postgrest-csharp@3.1.0
- [Minor] Breaking API Change: `PrimaryKey` attribute defaults to `shouldInsert: false` as most uses will have the Database generate the primary key.
- Merged [#60](https://github.com/supabase-community/postgrest-csharp/pull/60) which Added linq support for `Select`, `Where`, `OnConflict`, `Columns`, `Order`, `Update`, `Set`, and `Delete`
## 0.6.2 - 2022-11-22
- Update dependency: postgrest-csharp@3.0.4
- `GetHeaders` is now passed to `ModeledResponse` and `BaseModel` so that the default `Update` and `Delete` methods use the latest credentials
- `GetHeaders` is used in `Rpc` calls (re: [#39](https://github.com/supabase-community/supabase-csharp/issues/39))
## 0.6.1 - 2022-11-12
- [Hotfix] `GetHeaders` was not passing properly to `SupabaseTable` and `Gotrue.Api`
## 0.6.0 - 2022-11-12
[BREAKING CHANGES]
- `Client` is no longer a singleton, singleton interactions (if desired) are left to the developer to implement.
- `Client` supports injection of dependent clients after initialization via property:
- `Auth`
- `Functions`
- `Realtime`
- `Postgrest`
- `Storage`
- `SupabaseModel` contains no logic but remains for backwards compatibility. (Marked `Obsolete`)
- `ClientOptions.ShouldInitializeRealtime` was removed (no longer auto initialized)
- `ClientOptions` now references an `ISupabaseSessionHandler` which specifies expected functionality for session persistence on Gotrue (replaces `ClientOptions.SessionPersistor`, `ClientOptions.SessionRetriever`, and `ClientOptions.SessionDestroyer`).
- `supabase-csharp` and all child libraries now have support `nullity`
Other Changes:
- Update dependency: functions-csharp@1.2.1
- Update dependency: gotrue-csharp@3.0.2
- Update dependency: postgrest-csharp@3.0.2
- Update dependency: realtime-csharp@4.0.1
- Update dependency: supabase-storage-csharp@1.2.3
- Update dependency: supabase-core@0.0.2
Big thank you to [@veleek](https://github.com/veleek) for his insight into these changes.
Re: [#35](https://github.com/supabase-community/supabase-csharp/issues/35), [#34](https://github.com/supabase-community/supabase-csharp/issues/34), [#23](https://github.com/supabase-community/supabase-csharp/issues/23), [#36](https://github.com/supabase-community/supabase-csharp/pull/36)
## 0.5.3 - 2022-10-11
- Update dependency: postgrest-csharp@2.1.0
- [Minor] Breaking API change: Remove `BaseModel.PrimaryKeyValue` and `BaseModel.PrimaryKeyColumn` in favor of a `PrimaryKey` dictionary with support for composite keys.
- Re: [#48](https://github.com/supabase-community/postgrest-csharp/issues/48) - Add support for derived models on `ReferenceAttribute`
- Re: [#49](https://github.com/supabase-community/postgrest-csharp/issues/49) - Added `Match(T model)`
## 0.5.2 - 2022-9-13
- Update dependency: postgrest-csharp@2.0.12
- Merged [#47](https://github.com/supabase-community/postgrest-csharp/pull/49) which added cancellation token support to `Table<T>` methods. Thanks [@devpikachu](https://github.com/devpikachu)!
## 0.5.1 - 2022-8-1
- Update dependency: postgrest-csharp@2.0.11
- Update dependency: supabase-storage-csharp@1.1.1
## 0.5.0 - 2022-7-17
- Update dependency: postgrest-csharp@2.0.9
- Update dependency: realtime-csharp@3.0.1
- Update dependency: supabase-storage-csharp@1.1.0
- API Change [Breaking/Minor] Library no longer uses `WebClient` and instead leverages `HttpClient`. Progress events on `Upload` and `Download` are now handled with `EventHandler<float>` instead of `WebClient` EventHandlers.
## 0.4.4 - 2022-5-24
- Update dependency: gotrue-csharp@2.4.5
- Update dependency: postgrest-csharp@2.0.8
## 0.4.3 - 2022-5-13
- Update dependency: gotrue-csharp@2.4.4
## 0.4.2 - 2022-4-30
- Update dependency: gotrue-csharp@2.4.3
## 0.4.1 - 2022-4-23
- Update dependency: gotrue-csharp@2.4.2
## 0.4.0 - 2022-4-12
- Add support for functions-csharp@1.0.1, giving access to invoking Supabase's edge functions.
- Update dependency: gotrue-csharp@2.4.1
## 0.3.5 - 2022-4-11
- Update dependency: postgres-csharp@2.0.7
## 0.3.4 - 2022-03-28
- Update dependency: gotrue-csharp@2.4.0
## 0.3.3 - 2022-02-27
- Update dependency: gotrue-csharp@2.3.6
- Update dependency: supabase-storage-csharp@1.0.2
## 0.3.2 - 2022-02-18
- Update dependency: realtime-csharp@3.0.0
- Exchange existing websocket client: [WebSocketSharp](https://github.com/sta/websocket-sharp) for [Marfusios/websocket-client](https://github.com/Marfusios/websocket-client) which adds support for Blazor WASM apps.
Ref: [#14](https://github.com/supabase-community/realtime-csharp/pull/14)
## 0.3.1 - 2022-01-20
- Update dependency: gotrue-csharp@2.3.5
- [#23](https://github.com/supabase-community/gotrue-csharp/pull/23) Added `redirect_url` option for MagicLink sign in (Thanks [@MisterJimson](https://github.com/MisterJimson))
- [#21](https://github.com/supabase-community/gotrue-csharp/pull/21) Added SignOut method to Stateless Client (Thanks [@fplaras](https://github.com/fplaras))
## 0.3.0 - 2021-12-30
- Update dependency: postgrest-csharp@2.0.6
- Add support for `NullValueHandling` to be specified on a `Column` Attribute and for it to be honored on Inserts and Updates. Defaults to: `NullValueHandling.Include`.
- Implements [#38](https://github.com/supabase-community/postgrest-csharp/issues/38)
- Update dependency: realtime-csharp@2.0.8
- Implement Upstream Realtime RLS Error Broadcast Handler
- Implements [#12](https://github.com/supabase-community/realtime-csharp/issues/12)
- `SocketResponse` now exposes a method: `OldModel`, that hydrates the `OldRecord` property into a model.
## 0.2.12 - 2021-12-29
- Update dependency: gotrue-csharp@2.3.3
- `SignUp` will return a `Session` with a _populated `User` object_ on an unconfirmed signup.
- Fixes [#19](https://github.com/supabase-community/gotrue-csharp/issues/19)
- Developers who were using a `null` check on `Session.User` will need to adjust accordingly.
- Update dependency: postgrest-csharp@2.0.5
- Fix for [#37](https://github.com/supabase-community/postgrest-csharp/issues/37) - Return Type `minimal` would fail to resolve because of incorrect `Accept` headers. Added header and test to verify for future.
- Fix for [#36](https://github.com/supabase-community/postgrest-csharp/issues/36) - Inserting/Upserting bulk records would fail while doing an unnecessary generic coercion.
## 0.2.11 - 2021-12-24
- Update dependency: gotrue-csharp@2.3.2 (changes CreateUser parameters to conform to `AdminUserAttributes`)
- See [#15](https://github.com/supabase-community/supabase-csharp/issues/15)
- See [#16](https://github.com/supabase-community/supabase-csharp/issues/16)
- Update dependency: realtime-csharp@2.0.7
- See [#13](https://github.com/supabase-community/supabase-csharp/issues/13)
## 0.2.10 - 2021-12-23
- Update dependency: gotrue-csharp@2.3.0 (adds metadata support for user signup, see [#14](https://github.com/supabase/community/issues/14))
## 0.2.9 - 2021-12-9
- Separate Storage client from Supabase repo and into `storage-csharp`, `supabase-csharp` now references new repo.
## 0.2.8 - 2021-12-4
- Update gotrue-csharp to 2.2.4
- Adds support for `ListUsers` (paginate, sort, filter), `GetUserById`, `CreateUser`, and `UpdateById`
## 0.2.7 - 2021-12-2
- Update gotrue-csharp to 2.2.3
- Adds support for sending password resets to users.
## 0.2.6 - 2021-11-29
- Support for [#12](https://github.com/supabase-community/supabase-csharp/issues/12)
- Update realtime-csharp to 2.0.6
- Update gotrue-csharp to 2.2.2
- Add `StatelessClient` re:[#7](https://github.com/supabase-community/supabase-csharp/issues/7)
@@ -0,0 +1,6 @@
---
id: release-notes
title: Release Notes
---
## dart v0 this is the release notes file.
Whitespace-only changes.
@@ -0,0 +1,67 @@
---
id: initializing
title: 'Initializing'
slug: initializing
custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml
---
### Initializing a new Client
<RefSubLayout.EducationRow>
<RefSubLayout.Details>
Initializing a new client is pretty straightforward. Find your project url and public key from the
admin panel and pass it into your client initialization function.
</RefSubLayout.Details>
<RefSubLayout.Examples>
<Tabs
size="small"
type="underlined"
defaultActiveId="csharp-init-standard">
<TabPanel id="csharp-init-standard" label="Standard">
```csharp
var url = Environment.GetEnvironmentVariable("SUPABASE_URL");
var key = Environment.GetEnvironmentVariable("SUPABASE_KEY");
var options = new Supabase.SupabaseOptions
{
AutoConnectRealtime = true
};
var supabase = new Supabase.Client(url, key, options);
await supabase.InitializeAsync();
```
</TabPanel>
<TabPanel id="csharp-init-maui" label="Dependency Injection (Maui-like)">
```csharp
public static MauiApp CreateMauiApp()
{
// ...
var builder = MauiApp.CreateBuilder();
var url = Environment.GetEnvironmentVariable("SUPABASE_URL");
var key = Environment.GetEnvironmentVariable("SUPABASE_KEY");
var options = new SupabaseOptions
{
AutoRefreshToken = true,
AutoConnectRealtime = true,
SessionHandler = new SupabaseSessionHandler()
};
// Note the creation as a singleton.
builder.Services.AddSingleton(provider => new Supabase.Client(url, key, options));
}
```
</TabPanel>
</Tabs>
</RefSubLayout.Examples>
</RefSubLayout.EducationRow>
@@ -0,0 +1,33 @@
---
id: installing
title: 'Installing & Initialization'
slug: installing
custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml
---
### Install from NuGet
<RefSubLayout.EducationRow>
<RefSubLayout.Details>
You can install Supabase package from [nuget.org](https://www.nuget.org/packages/supabase-csharp/)
</RefSubLayout.Details>
<RefSubLayout.Examples>
<Tabs
size="small"
type="underlined"
defaultActiveId="csharp">
<TabPanel id="csharp" label="Terminal">
```sh Terminal
dotnet add package supabase-csharp
```
</TabPanel>
</Tabs>
</RefSubLayout.Examples>
</RefSubLayout.EducationRow>
@@ -0,0 +1,20 @@
---
id: introduction
title: Introduction
hideTitle: true
---
<div className="flex items-start gap-6 not-prose" id="introduction">
<img src="/docs/img/icons/menu/reference-csharp.svg" className="w-8 h-8 rounded" />
<div className="flex flex-col gap-2">
<h1 className="text-3xl text-scale-1200 m-0">C# Client Library</h1>
<h2 className="text-base font-mono text-scale-1100">supabase-csharp</h2>
</div>
</div>
<div className="max-w-xl">
This reference documents every object and method available in Supabase's C#
library, [supabase-csharp](https://www.nuget.org/packages/supabase-csharp). You can
use supabase-csharp to interact with your Postgres database, listen to database changes, invoke
Deno Edge Functions, build login and user management functionality, and manage large files.
</div>
@@ -0,0 +1,6 @@
---
id: release-notes
title: Release Notes
---
## dart v0 this is the release notes file.
+1 -1
View File
@@ -19,7 +19,7 @@ const Layout: FC<Props> = (props: Props) => {
return (
<>
<Head>
<title>{props.meta?.title} | Supabase</title>
<title>{props.meta?.title} | Supabase Docs</title>
<meta name="description" content={props.meta?.description} />
<meta content="width=device-width, initial-scale=1" name="viewport" />
<link rel="icon" href="/docs/favicon.ico" />
+5 -1
View File
@@ -29,7 +29,7 @@ const levelsData = {
},
functions: {
icon: '/docs/img/icons/menu/functions',
name: 'Functions',
name: 'Edge Functions',
},
realtime: {
icon: '/docs/img/icons/menu/realtime',
@@ -75,6 +75,10 @@ const levelsData = {
icon: '/docs/img/icons/menu/reference-dart',
name: 'Dart Reference v0.0',
},
reference_csharp_v0: {
icon: '/docs/img/icons/menu/reference-csharp',
name: 'C# Reference v0.0',
},
reference_python_v2: {
icon: '/docs/img/icons/menu/reference-python',
name: 'Python Reference v2.0',
+8 -2
View File
@@ -65,12 +65,19 @@ const Layout: FC<Props> = (props) => {
return (
<>
<NextSeo
title={`${props.meta?.title} | Supabase`}
title={`${props.meta?.title} | Supabase Docs`}
description={props.meta?.description ? props.meta?.description : props.meta?.title}
canonical={`https://supabase.com/docs${asPath}`}
openGraph={{
title: props.meta?.title,
description: props.meta?.description,
url: `https://supabase.com/docs${asPath}`,
type: 'article',
article: {
publishedTime: new Date().toISOString(),
modifiedTime: new Date().toISOString(),
authors: ['Supabase'],
},
images: [
{
url: `https://obuldanrptloktxcffvn.functions.supabase.co/og-images?site=docs${
@@ -82,7 +89,6 @@ const Layout: FC<Props> = (props) => {
],
}}
/>
<div className={['grid grid-cols-12 relative gap-4'].join(' ')}>
<div
className={[
+1 -1
View File
@@ -3,7 +3,7 @@ import type { NextRequest } from 'next/server'
import isbot from 'isbot'
export function middleware(request: NextRequest) {
const specs = ['javascript', 'dart']
const specs = ['javascript', 'dart', 'csharp']
let version = ''
if (request.url.includes('/v1/')) {
+7 -3
View File
@@ -9,7 +9,7 @@
"lint": "next lint",
"build:sitemap": "node ./internals/generate-sitemap.mjs",
"postbuild": "ts-node ./scripts/build-search.ts && node ./internals/generate-sitemap.mjs",
"generate:all": "npm-run-all --parallel gen:api gen:cli gen:gotrue gen:storage gen:supabase-dart:v0 gen:supabase-dart:v1 gen:supabase-js:v1 gen:supabase-js:v2 gen:realtime",
"generate:all": "npm-run-all --parallel gen:api gen:cli gen:gotrue gen:storage gen:supabase-dart:v0 gen:supabase-dart:v1 gen:supabase-csharp:v0 gen:supabase-js:v1 gen:supabase-js:v2 gen:realtime",
"gen:api": "npm-run-all gen:api:usage",
"gen:api:usage": "ts-node ./generator/index.ts gen --type api --url https://api.supabase.com --input ../../spec/transforms/api_v0_openapi_deparsed.json --output ./docs/reference/api/generated/usage.mdx",
"gen:cli": "npm-run-all gen:cli:commands gen:cli:config",
@@ -25,6 +25,8 @@
"gen:supabase-dart:v0:ref": "ts-node ./generator/index.ts gen --type legacy --input ../../spec/supabase_dart_v0.yml --output ./docs/reference/dart/v0/generated",
"gen:supabase-dart:v1": "npm-run-all gen:supabase-dart:v1:ref",
"gen:supabase-dart:v1:ref": "ts-node ./generator/index.ts gen --type legacy --input ../../spec/supabase_dart_v1.yml --output ./docs/reference/dart/generated",
"gen:supabase-csharp:v0": "npm-run-all gen:supabase-csharp:v0:ref",
"gen:supabase-csharp:v0:ref": "ts-node ./generator/index.ts gen --type legacy --input ../../spec/supabase_csharp_v0.yml --output ./docs/reference/csharp/generated",
"gen:supabase-js:v1": "npm-run-all gen:supabase-js:v1:ref",
"gen:supabase-js:v1:ref": "ts-node ./generator/index.ts gen --type legacy --input ../../spec/supabase_js_v1.yml --output ./docs/reference/javascript/v1/generated",
"gen:supabase-js:v2": "npm-run-all gen:supabase-js:v2:ref",
@@ -42,6 +44,7 @@
"@radix-ui/react-accordion": "^1.0.1",
"algoliasearch": "^4.14.2",
"babel": "^6.23.0",
"clsx": "^1.2.1",
"common": "*",
"config": "*",
"gray-matter": "^4.0.3",
@@ -63,6 +66,7 @@
"react-intersection-observer": "^9.4.0",
"react-markdown": "^8.0.3",
"react-syntax-highlighter": "^15.3.1",
"rehype-slug": "^5.1.0",
"remark": "^14.0.2",
"remark-admonitions": "^1.2.1",
"remark-gfm": "^3.0.1",
@@ -72,10 +76,10 @@
"valtio": "^1.7.6"
},
"devDependencies": {
"dotenv": "^16.0.3",
"@types/node": "^17.0.12",
"@types/react": "17.0.39",
"config": "*",
"dotenv": "^16.0.3",
"ejs": "^3.1.8",
"eslint": "8.9.0",
"globby": "^12.0.2",
@@ -89,4 +93,4 @@
"tsconfig": "*",
"typescript": "^4.5.3"
}
}
}
+1
View File
@@ -55,6 +55,7 @@ GraphQL in Supabase works through [pg_graphql](https://supabase.com/blog/pg-grap
Supabase provides a Realtime API using [Realtime](https://github.com/supabase/realtime). You can use this to listen to database changes over websockets.
Realtime leverages PostgreSQL's built-in logical replication. You can manage your Realtime API simply by managing Postgres publications.
Go to your project's [Replication section](https://app.supabase.com/project/_/database/replication) to get started.
## Getting started
+1 -1
View File
@@ -2,7 +2,7 @@ import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'index',
title: 'Auth Helpers',
title: 'Auth Helpers Overview',
description: 'A collection of framework-specific Auth utilities for working with Supabase.',
sidebar_label: 'Overview',
}
@@ -594,7 +594,7 @@ export const config = {
To make these helpers more flexible as well as more maintainable and easier to upgrade for new versions of Next.js, we're stripping them down to the most useful part which is managing the cookies and giving you an authenticated supabase-js client in any environment (client, server, middleware/edge).
Therefore we're marking the `withApiAuth`, `withPageAuth`, and `withMiddlewareAuth` higher order functions as deprectaed and they will be removed in the next **minor** release (v0.6.X).
Therefore we're marking the `withApiAuth`, `withPageAuth`, and `withMiddlewareAuth` higher order functions as deprecated and they will be removed in the next **minor** release (v0.6.X).
Please follow the steps below to update your API routes, pages, and middleware handlers. Thanks!
@@ -97,7 +97,7 @@ If the trigger fails however, it could block the user sign ups - so make sure th
For example:
```sql
-- inserts a row into public.users
-- inserts a row into public.profiles
create function public.handle_new_user()
returns trigger
language plpgsql
@@ -2,7 +2,7 @@ import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'extensions',
title: 'Overview',
title: 'Postgres Extensions Overview',
description: 'Using Postgres extensions.',
}
+3 -3
View File
@@ -3,16 +3,16 @@ import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'functions-cors',
title: 'CORS (Cross-Origin Resource Sharing)',
description: 'Add CORS headers to invoke functions from the browser.',
description: 'Add CORS headers to invoke Edge Functions from the browser.',
}
To invoke the functions from the browser, you need to handle [CORS Preflight](https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request) requests.
To invoke edge functions from the browser, you need to handle [CORS Preflight](https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request) requests.
See the [example on GitHub](https://github.com/supabase/supabase/blob/master/examples/edge-functions/supabase/functions/browser-with-cors/index.ts).
### Recommended setup
We recommend adding a `corst.ts` file within a [`_shared` folder](/docs/guides/functions/quickstart#organizing-your-edge-functions) which makes it easy to reuse the CORS headers across functions:
We recommend adding a `cors.ts` file within a [`_shared` folder](/docs/guides/functions/quickstart#organizing-your-edge-functions) which makes it easy to reuse the CORS headers across functions:
```ts cors.ts
export const corsHeaders = {
@@ -2,8 +2,8 @@ import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'functions-debugging',
title: 'Debugging Functions',
description: 'Debug functions in production.',
title: 'Debugging Edge Functions',
description: 'Debug Edge Functions in production.',
}
You can debug your deployed Edge Functions using the ["Functions" section](https://app.supabase.com/project/_/functions) of the Dashboard. There are two debugging tools available:
@@ -8,7 +8,7 @@ export const meta = {
<div class="video-container">
<iframe
src="https://www.youtube-nocookie.com/embed/6OMVWiiycLs"
src="https://www.youtube-nocookie.com/embed/l2KlzGrhB6w"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
@@ -3,7 +3,7 @@ import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'functions-local-development',
title: 'Local Development',
description: 'Run your functions locally.',
description: 'Run your Edge Functions locally.',
}
You can run your Edge Function locally using [`supabase functions serve`](/docs/reference/cli/usage#supabase-functions-serve):
@@ -15,9 +15,9 @@ supabase functions serve hello-world # start the Function watcher
The `functions serve` command has hot-reloading capabilities. It will watch for any changes to your files and restart the Deno server.
### Invoking functions locally
### Invoking Edge Functions locally
While serving your local Function, you can invoke it using curl:
While serving your local Edge Function, you can invoke it using curl:
```bash
curl --request POST 'http://localhost:54321/functions/v1/hello-world' \
@@ -44,7 +44,7 @@ const { data, error } = await supabase.functions.invoke('hello-world', {
You should see the response `{ "message":"Hello Functions!" }`.
If you execute Function with a different payload the response will change. <br />
If you execute the function with a different payload the response will change. <br />
Modify the `--data '{"name":"Functions"}'` line to `--data '{"name":"World"}'` and try invoking the command again!
<Admonition type="note">
@@ -28,7 +28,7 @@ Follow the steps to prepare your Supabase project on your local machine.
- Link to your Remote Project using the command `supabase link --project-ref your-project-ref`. [Docs](/docs/reference/cli/usage#supabase-link).
- Optional: Setup your environment: Follow [this setup guide](https://deno.land/manual/getting_started/setup_your_environment) to integrate the Deno language server with your editor.
## Create a function
## Create an Edge Function
Let's create a new Edge Function called `hello-world` inside your project:
@@ -2,17 +2,17 @@ import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'schedule-functions',
title: 'Schedule Functions',
description: 'Schedule Functions with pg_cron.',
title: 'Schedule Edge Functions',
description: 'Schedule Edge Functions with pg_cron.',
}
The hosted Supabase Platform supports the [`pg_cron` extension](/docs/guides/database/extensions/pgcron), a simple cron-based job scheduler for PostgreSQL that runs inside the database.
In combination with the [`pg_net` extension](/docs/guides/database/extensions/pgnet), this allows us to invoke functions periodically on a set schedule.
In combination with the [`pg_net` extension](/docs/guides/database/extensions/pgnet), this allows us to invoke Edge Functions periodically on a set schedule.
## Examples
### Invoke Function every minute
### Invoke an Edge Function every minute
Make a POST request to a Supabase Edge Function every minute:
@@ -50,7 +50,7 @@ VITE_SUPABASE_URL=YOUR_SUPABASE_URL
VITE_SUPABASE_ANON_KEY=YOUR_SUPABASE_ANON_KEY
```
Now that we have the API credentials in place, let's create a helper file to initialize the Supabase client. These variables will be exposed
With the API credentials in place, create an `src/supabase.js` helper file to initialize the Supabase client. These variables are exposed
on the browser, and that's completely fine since we have [Row Level Security](/docs/guides/auth#row-level-security) enabled on our Database.
```js title=src/supabase.js
@@ -66,7 +66,7 @@ Optionally, update [src/style.css](https://raw.githubusercontent.com/supabase/su
### Set up a Login component
Let's set up a Vue component to manage logins and sign ups. We'll use Magic Links, so users can sign in with their email without using passwords.
Set up an `src/components/Auth.vue` component to manage logins and sign ups. We'll use Magic Links, so users can sign in with their email without using passwords.
```html title=/src/components/Auth.vue
<script setup>
@@ -118,7 +118,7 @@ Let's set up a Vue component to manage logins and sign ups. We'll use Magic Link
### Account page
After a user is signed in we can allow them to edit their profile details and manage their account.
Let's create a new component for that called `Account.vue`.
Create a new `src/components/Account.vue` component to handle this.
```html title=src/components/Account.vue
<script setup>
@@ -277,7 +277,7 @@ Every Supabase project is configured with [Storage](/docs/guides/storage) for ma
### Create an upload widget
Let's create an avatar for the user so that they can upload a profile photo. We can start by creating a new component:
Create a new `src/components/Avatar.vue` component that allows users to upload profile photos:
```html title=src/components/Avatar.vue
<script setup>
@@ -361,7 +361,7 @@ Let's create an avatar for the user so that they can upload a profile photo. We
### Add the new widget
And then we can add the widget to the Account page:
And then we can add the widget to the Account page in `src/components/Account.vue`:
```html title=src/components/Account.vue
<script>
+1 -2
View File
@@ -38,8 +38,7 @@ export default function Config() {
<div className="mt-8">
<div>
<Heading tag="h2" parseAnchors={false} customAnchor={parameter.id}>
<span className="mr-2">$</span>
{parameter.title}
<code>{parameter.title}</code>
</Heading>
<div className="grid">
<div className="border-b pb-8" key={parameter.id}>
@@ -0,0 +1,21 @@
import clientLibsCommonSections from '~/../../spec/common-client-libs-sections.json'
// @ts-expect-error
import spec from '~/../../spec/supabase_csharp_v0.yml' assert { type: 'yml' }
import RefSectionHandler from '~/components/reference/RefSectionHandler'
import { flattenSections } from '~/lib/helpers'
import handleRefGetStaticPaths from '~/lib/mdx/handleRefStaticPaths'
import handleRefStaticProps from '~/lib/mdx/handleRefStaticProps'
const sections = flattenSections(clientLibsCommonSections)
export default function JSReference(props) {
return <RefSectionHandler sections={sections} spec={spec} pageProps={props} type="client-lib" />
}
export async function getStaticProps() {
return handleRefStaticProps(sections, '/csharp')
}
export function getStaticPaths() {
return handleRefGetStaticPaths()
}
@@ -0,0 +1,44 @@
import clientLibsCommonSections from '~/../../spec/common-client-libs-sections.json'
import typeSpec from '~/../../spec/enrichments/tsdoc_v2/combined.json'
// @ts-expect-error
import spec from '~/../../spec/supabase_csharp_v0.yml' assert { type: 'yml' }
import RefSectionHandler from '~/components/reference/RefSectionHandler'
import { flattenSections } from '~/lib/helpers'
import handleRefGetStaticPaths from '~/lib/mdx/handleRefStaticPaths'
import handleRefStaticProps from '~/lib/mdx/handleRefStaticProps'
import { useRouter } from 'next/router'
import RefSEO from '~/components/reference/RefSEO'
const sections = flattenSections(clientLibsCommonSections)
export default function JSReference(props) {
const router = useRouter()
const slug = router.query.slug[0]
const filteredSection = sections.filter((section) => section.id === slug)
const pageTitle = filteredSection[0]?.title
? `${filteredSection[0]?.title} | Supabase`
: 'Supabase'
return (
<>
<RefSEO title={pageTitle} />
<RefSectionHandler
sections={filteredSection}
spec={spec}
typeSpec={typeSpec}
pageProps={props}
type="client-lib"
/>
</>
)
}
export async function getStaticProps() {
return handleRefStaticProps(sections, '/csharp')
}
export function getStaticPaths() {
return handleRefGetStaticPaths()
}
@@ -0,0 +1,21 @@
import clientLibsCommonSections from '~/../../spec/common-client-libs-sections.json'
// @ts-expect-error
import spec from '~/../../spec/supabase_csharp_v0.yml' assert { type: 'yml' }
import RefSectionHandler from '~/components/reference/RefSectionHandler'
import { flattenSections } from '~/lib/helpers'
import handleRefGetStaticPaths from '~/lib/mdx/handleRefStaticPaths'
import handleRefStaticProps from '~/lib/mdx/handleRefStaticProps'
const sections = flattenSections(clientLibsCommonSections)
export default function JSReference(props) {
return <RefSectionHandler sections={sections} spec={spec} pageProps={props} type="client-lib" />
}
export async function getStaticProps() {
return handleRefStaticProps(sections, '/csharp/v0')
}
export function getStaticPaths() {
return handleRefGetStaticPaths()
}
@@ -0,0 +1,43 @@
import clientLibsCommonSections from '~/../../spec/common-client-libs-sections.json'
import typeSpec from '~/../../spec/enrichments/tsdoc_v2/combined.json'
// @ts-expect-error
import spec from '~/../../spec/supabase_csharp_v0.yml' assert { type: 'yml' }
import RefSectionHandler from '~/components/reference/RefSectionHandler'
import { flattenSections } from '~/lib/helpers'
import handleRefGetStaticPaths from '~/lib/mdx/handleRefStaticPaths'
import handleRefStaticProps from '~/lib/mdx/handleRefStaticProps'
import { useRouter } from 'next/router'
import RefSEO from '~/components/reference/RefSEO'
const sections = flattenSections(clientLibsCommonSections)
export default function JSReference(props) {
const router = useRouter()
const slug = router.query.slug[0]
const filteredSection = sections.filter((section) => section.id === slug)
const pageTitle = filteredSection[0]?.title
? `${filteredSection[0]?.title} | Supabase`
: 'Supabase'
return (
<>
<RefSEO title={pageTitle} />
<RefSectionHandler
sections={filteredSection}
spec={spec}
typeSpec={typeSpec}
pageProps={props}
type="client-lib"
/>
</>
)
}
export async function getStaticProps() {
return handleRefStaticProps(sections, '/csharp/v0')
}
export function getStaticPaths() {
return handleRefGetStaticPaths()
}
@@ -14,7 +14,7 @@ const sections = flattenSections(clientLibsCommonSections)
export default function JSReference(props) {
const router = useRouter()
const slug = router.query.slug[0]
const filteredSection = sections.filter((section) => section.id === slug)
const filteredSection = sections.filter((section) => section.slug === slug)
const pageTitle = filteredSection[0]?.title
? `${filteredSection[0]?.title} | Supabase`
@@ -14,7 +14,7 @@ const sections = flattenSections(clientLibsCommonSections)
export default function JSReference(props) {
const router = useRouter()
const slug = router.query.slug[0]
const filteredSection = sections.filter((section) => section.id === slug)
const filteredSection = sections.filter((section) => section.slug === slug)
const pageTitle = filteredSection[0]?.title
? `${filteredSection[0]?.title} | Supabase`
@@ -14,7 +14,7 @@ const sections = flattenSections(clientLibsCommonSections)
export default function JSReference(props) {
const router = useRouter()
const slug = router.query.slug[0]
const filteredSection = sections.filter((section) => section.id === slug)
const filteredSection = sections.filter((section) => section.slug === slug)
const pageTitle = filteredSection[0]?.title
? `${filteredSection[0]?.title} | Supabase`
@@ -13,7 +13,7 @@ const sections = flattenSections(clientLibsCommonSections)
export default function JSReference(props) {
const router = useRouter()
const slug = router.query.slug[0]
const filteredSection = sections.filter((section) => section.id === slug)
const filteredSection = sections.filter((section) => section.slug === slug)
const pageTitle = filteredSection[0]?.title
? `${filteredSection[0]?.title} | Supabase`
Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 2500 2500" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<path d="M174.672,1866.26L173.916,1866.7C191.548,1898.57 218.67,1925.69 254.607,1946.71C428.869,2047.74 1012.68,2382.03 1129.3,2451.19C1135.77,2454.98 1142.22,2458.47 1148.65,2461.66C1221.03,2498 1291.94,2496.48 1364.59,2453.9C1657.51,2284.39 1951.11,2116.23 2244.04,1947.39C2280.65,1926.37 2307.1,1899.92 2324.72,1867.38C2341.57,1836.39 2350.38,1800.72 2350.49,1760.36C2350.49,1759.87 2350.49,1759.38 2350.49,1758.89L2350.49,739.086C2350.49,697.725 2341.68,660.432 2323.37,629.239L2323.37,629.241L2323.37,629.239C2305.74,598.05 2279.29,572.284 2244.04,551.942C1951.11,383.104 1657.51,214.269 1364.59,45.431C1285.26,0 1209.32,1.357 1130.66,47.464C1014.03,115.95 429.546,450.91 255.963,551.942C184.087,593.303 149.507,657.042 149.507,739.765L149.507,1759.57C149.507,1799.77 158.113,1835.33 174.672,1866.26Z" style="fill:white;fill-rule:nonzero;"/>
<path d="M1566.65,1427.32C1504.27,1537.84 1385.61,1613.11 1249.32,1613.11C1113.71,1613.11 995.729,1539.2 933.347,1429.35C902.834,1375.79 885.203,1314.76 885.203,1248.99C885.203,1047.6 1047.94,884.869 1249.32,884.869C1383.58,884.869 1500.88,958.099 1563.94,1066.59L1881.95,883.512C1755.16,665.179 1519.19,518.039 1248.64,518.039C844.519,518.039 517.696,845.542 517.696,1248.99C517.696,1381.21 552.953,1505.97 614.658,1613.11C740.776,1832.12 978.098,1979.94 1249.32,1979.94C1521.23,1979.94 1758.55,1831.44 1884.66,1611.07L1566.65,1427.32ZM1968.74,1076.08L1896.19,1076.08L1896.19,1426.64L1968.74,1426.64L1968.74,1076.08ZM2129.44,1076.08L2056.89,1076.08L2056.89,1426.64L2129.44,1426.64L2129.44,1076.08Z" style="fill-rule:nonzero;"/>
<g>
<path d="M2188.43,1135.07L1837.88,1135.07L1837.88,1207.63L2188.43,1207.63L2188.43,1135.07ZM2188.43,1295.1L1837.88,1295.1L1837.88,1367.65L2188.43,1367.65L2188.43,1295.1Z" style="fill-rule:nonzero;"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="2202" height="2476"><defs><linearGradient id="b" x1="22.367%" x2="87.411%" y1="78.665%" y2="25.105%"><stop offset="0%" stop-color="#ADADAD" stop-opacity=".5"/><stop offset="100%" stop-opacity=".5"/></linearGradient><path id="a" d="M981.153 35.355c78.66-46.107 154.6-47.464 233.93-2.033 292.92 168.838 586.52 337.673 879.45 506.511 35.25 20.342 61.7 46.108 79.33 77.297l.546.938c17.94 31.001 26.574 67.962 26.574 108.909v1021.274c-.11 40.36-8.92 76.03-25.77 107.02-17.62 32.54-44.07 58.99-80.68 80.01-292.93 168.84-586.53 337-879.45 506.51-72.65 42.58-143.56 44.1-215.94 7.76-6.43-3.19-12.88-6.68-19.35-10.47-116.62-69.16-700.431-403.45-874.693-504.48-35.937-21.02-63.059-48.14-80.691-80.01l.756-.44C8.606 1823.221 0 1787.661 0 1747.461V727.656c0-82.723 34.58-146.462 106.456-187.823C280.039 438.801 864.523 103.841 981.153 35.355Zm117.98 470.575c-404.121 0-730.944 327.503-730.944 730.951 0 132.22 35.257 256.98 96.962 364.12 126.118 219.01 363.44 366.83 634.662 366.83 271.91 0 509.23-148.5 635.34-368.87l-318.01-183.75c-62.38 110.52-181.04 185.79-317.33 185.79-135.61 0-253.591-73.91-315.973-183.76-30.513-53.56-48.144-114.59-48.144-180.36 0-201.39 162.737-364.121 364.117-364.121 134.26 0 251.56 73.23 314.62 181.721l318.01-183.078c-126.79-218.333-362.76-365.473-633.31-365.473Zm720.1 558.041h-72.55v58.99h-58.31v72.56h58.31v87.47h-58.31v72.55h58.31v58.99h72.55l-.001-58.99h88.15l.001 58.99h72.55v-58.99h58.99v-72.55h-58.99v-87.47h58.99v-72.56h-58.99v-58.99h-72.55l-.001 58.99h-88.15l.001-58.99Zm88.149 131.55v87.47h-88.15v-87.47h88.15Z"/></defs><g fill="none" fill-rule="nonzero" transform="translate(.507 .109)"><use xlink:href="#a" fill="#4C4C4C"/><use xlink:href="#a" fill="url(#b)"/></g></svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 2500 2500" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<path d="M174.672,1866.26L173.916,1866.7C191.548,1898.57 218.67,1925.69 254.607,1946.71C428.869,2047.74 1012.68,2382.03 1129.3,2451.19C1135.77,2454.98 1142.22,2458.47 1148.65,2461.66C1221.03,2498 1291.94,2496.48 1364.59,2453.9C1657.51,2284.39 1951.11,2116.23 2244.04,1947.39C2280.65,1926.37 2307.1,1899.92 2324.72,1867.38C2341.57,1836.39 2350.38,1800.72 2350.49,1760.36C2350.49,1759.87 2350.49,1759.38 2350.49,1758.89L2350.49,739.086C2350.49,697.725 2341.68,660.432 2323.37,629.239L2323.37,629.241L2323.37,629.239C2305.74,598.05 2279.29,572.284 2244.04,551.942C1951.11,383.104 1657.51,214.269 1364.59,45.431C1285.26,0 1209.32,1.357 1130.66,47.464C1014.03,115.95 429.546,450.91 255.963,551.942C184.087,593.303 149.507,657.042 149.507,739.765L149.507,1759.57C149.507,1799.77 158.113,1835.33 174.672,1866.26Z" style="fill:white;fill-rule:nonzero;"/>
<path d="M1566.65,1427.32C1504.27,1537.84 1385.61,1613.11 1249.32,1613.11C1113.71,1613.11 995.729,1539.2 933.347,1429.35C902.834,1375.79 885.203,1314.76 885.203,1248.99C885.203,1047.6 1047.94,884.869 1249.32,884.869C1383.58,884.869 1500.88,958.099 1563.94,1066.59L1881.95,883.512C1755.16,665.179 1519.19,518.039 1248.64,518.039C844.519,518.039 517.696,845.542 517.696,1248.99C517.696,1381.21 552.953,1505.97 614.658,1613.11C740.776,1832.12 978.098,1979.94 1249.32,1979.94C1521.23,1979.94 1758.55,1831.44 1884.66,1611.07L1566.65,1427.32ZM1968.74,1076.08L1896.19,1076.08L1896.19,1426.64L1968.74,1426.64L1968.74,1076.08ZM2129.44,1076.08L2056.89,1076.08L2056.89,1426.64L2129.44,1426.64L2129.44,1076.08Z" style="fill-rule:nonzero;"/>
<g>
<path d="M2188.43,1135.07L1837.88,1135.07L1837.88,1207.63L2188.43,1207.63L2188.43,1135.07ZM2188.43,1295.1L1837.88,1295.1L1837.88,1367.65L2188.43,1367.65L2188.43,1295.1Z" style="fill-rule:nonzero;"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

+1
View File
@@ -100,6 +100,7 @@ function Blog(props: any) {
]}
/>
<DefaultLayout>
<h1 className="sr-only">Supabase blog</h1>
<div className="overflow-hidden py-12">
<div className="container mx-auto mt-16 px-8 sm:px-16 xl:px-20">
<div className="mx-auto ">
+4 -4
View File
@@ -37,11 +37,11 @@ function TagBlogsPage(props: Props) {
<DefaultLayout>
<div className="container mx-auto px-8 py-16 sm:px-16 xl:px-20">
<div className="text-scale-1000 flex space-x-1">
<p className="cursor-pointer">
<h1 className="cursor-pointer">
<Link href="/blog">Blog</Link>
</p>
<p>/</p>
<p>{`${tag}`}</p>
<span className="px-2">/</span>
<span>{`${tag}`}</span>
</h1>
</div>
<ol className="grid grid-cols-12 gap-8 py-16 lg:gap-16">
{blogs.map((blog: PostTypes, idx: number) => (
+5 -3
View File
@@ -101,9 +101,11 @@ const CareerPage: NextPage = ({ jobs, contributors }: any) => {
<DefaultLayout>
<div className="text-scale-1200">
<div className="container relative mx-auto px-6 py-10 lg:pt-12 lg:px-16 xl:px-20 text-center space-y-4">
<span className="text-sm text-brand-900 md:text-base">Careers</span>
<h1 className="text-sm text-brand-900 md:text-base">
<span className="sr-only">Supabase </span>Careers
</h1>
<h2 className="text-3xl md:text-4xl xl:text-5xl lg:max-w-2xl xl:max-w-3xl lg:mx-auto tracking-[-1.5px]">
We’re on a mission to build the best developer platform
We're on a mission to build the best developer platform
</h2>
<p className="text-sm md:text-base text-scale-1000 max-w-sm sm:max-w-md md:max-w-lg mx-auto">
Explore remote possibilities and join our team to help us achieve it.
@@ -321,7 +323,7 @@ const CareerPage: NextPage = ({ jobs, contributors }: any) => {
<div
className={`${
Styles[`contributors-${i}`]
} absolute w-12 h-12 md:w-14 md:h-14 lg:w-16 lg:h-16 rounded-full border-[1.5px] border-scale-600 z-10
} absolute w-12 h-12 md:w-14 md:h-14 lg:w-16 lg:h-16 rounded-full border-[1.5px] border-scale-600 z-10
transition-all hover:scale-105 drop-shadow-sm hover:drop-shadow-md
`}
key={i}
+3 -3
View File
@@ -124,13 +124,13 @@ In addition to internal security reviews, we use various tools to scan our code
<div className="container mx-auto pb-24 pt-1 px-8 sm:px-16 xl:px-20">
<div className="max-w-xl">
<h3 className="text-3xl">Security Portal</h3>
<h3 className="text-3xl">Request for our SOC2 documents</h3>
Access more of Supabase’s security information on our Security Portal, such as penetration testing and audit reports.
As a database company, being SOC2 compliant is important when handling sensitive customer data. Access more of Supabase’s security information by requesting for our latest SOC2 documents below.
<Link passHref href="https://security.supabase.com">
<Button type="default" size="medium" as="a" className="no-underline" target="_blank">
Security Portal
Get SOC2 documents
</Button>
</Link>
</div>
@@ -5,9 +5,16 @@
<link>https://supabase.com/blog</link>
<description>Latest Postgres news from Paul Copplestone at Supabase</description>
<language>en</language>
<lastBuildDate>Mon, 27 Jun 2022 02:02:30 +0000</lastBuildDate>
<lastBuildDate>Fri, 09 Dec 2022 03:03:30 +0000</lastBuildDate>
<atom:link href="https://supabase.com/planetpg-paul_copplestone-rss.xml" rel="self" type="application/rss+xml"/>
<item>
<guid>https://supabase.com/blog/postgres-crdt</guid>
<title>pg_crdt - an experimental CRDT extension for Postgres</title>
<link>https://supabase.com/blog/postgres-crdt</link>
<description>Embedding Yjs and Automerge into Postgres for collaborative applications.</description>
<pubDate>Fri, 09 Dec 2022 03:03:30 +0000</pubDate>
</item>
<item>
<guid>https://supabase.com/blog/partial-postgresql-data-dumps-with-rls</guid>
<title>Partial data dumps using Postgres Row Level Security</title>
<link>https://supabase.com/blog/partial-postgresql-data-dumps-with-rls</link>
+1 -1
View File
@@ -9,7 +9,7 @@ version: "3.8"
services:
studio:
container_name: supabase-studio
image: supabase/studio:20230127-123d704
image: supabase/studio:20230127-6bfd87b
restart: unless-stopped
healthcheck:
test: [ "CMD", "node", "-e", "require('http').get('http://localhost:3000/api/profile', (r) => {if (r.statusCode !== 200) throw new Error(r.statusCode)})" ]
+18 -1
View File
@@ -49,6 +49,7 @@
"@radix-ui/react-accordion": "^1.0.1",
"algoliasearch": "^4.14.2",
"babel": "^6.23.0",
"clsx": "^1.2.1",
"common": "*",
"config": "*",
"gray-matter": "^4.0.3",
@@ -70,6 +71,7 @@
"react-intersection-observer": "^9.4.0",
"react-markdown": "^8.0.3",
"react-syntax-highlighter": "^15.3.1",
"rehype-slug": "^5.1.0",
"remark": "^14.0.2",
"remark-admonitions": "^1.2.1",
"remark-gfm": "^3.0.1",
@@ -417,6 +419,14 @@
"url": "https://github.com/sponsors/epoberezkin"
}
},
"apps/docs/node_modules/clsx": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz",
"integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==",
"engines": {
"node": ">=6"
}
},
"apps/docs/node_modules/eslint": {
"version": "8.9.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.9.0.tgz",
@@ -45499,7 +45509,7 @@
"@sinclair/typebox": "^0.25.1",
"pg": "^8.7.1",
"pg-format": "^1.0.4",
"pgsql-parser": "^13.3.0",
"pgsql-parser": "13.4.0",
"postgres-array": "^3.0.1",
"prettier": "^2.6.0",
"prettier-plugin-sql": "^0.12.1"
@@ -50577,6 +50587,7 @@
"@types/react": "17.0.39",
"algoliasearch": "^4.14.2",
"babel": "^6.23.0",
"clsx": "^1.2.1",
"common": "*",
"config": "*",
"dotenv": "^16.0.3",
@@ -50606,6 +50617,7 @@
"react-intersection-observer": "^9.4.0",
"react-markdown": "^8.0.3",
"react-syntax-highlighter": "^15.3.1",
"rehype-slug": "^5.1.0",
"remark": "^14.0.2",
"remark-admonitions": "^1.2.1",
"remark-gfm": "^3.0.1",
@@ -50807,6 +50819,11 @@
"uri-js": "^4.2.2"
}
},
"clsx": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz",
"integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg=="
},
"eslint": {
"version": "8.9.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.9.0.tgz",
+1 -2
View File
@@ -1151,8 +1151,7 @@
"created_at": { "type": "number" },
"updated_at": { "type": "number" },
"verify_jwt": { "type": "boolean" },
"import_map": { "type": "boolean" },
"body": { "type": "string" }
"import_map": { "type": "boolean" }
},
"required": ["id", "slug", "name", "status", "version", "created_at", "updated_at"]
},
-1
View File
@@ -346,7 +346,6 @@ parameters:
title: 'functions.<function_name>.import_map'
tags: ['edge-functions']
required: false
default: 'true'
description: |
Specify the Deno import map file to use for the Function.
+2 -8
View File
@@ -16,7 +16,8 @@
"title": "Initializing",
"id": "initializing",
"slug": "initializing",
"type": "function"
"type": "markdown",
"libs": ["csharp"]
},
{
"title": "Typescript Support",
@@ -39,7 +40,6 @@
},
{
"title": "Database",
"items": [
{
"id": "select",
@@ -90,7 +90,6 @@
"slug": "using-filters",
"product": "database",
"type": "function",
"items": [
{
"id": "eq",
@@ -286,7 +285,6 @@
"product": "database",
"parent": "modifiers",
"type": "function",
"items": [
{
"id": "db-modifiers-select",
@@ -358,7 +356,6 @@
},
{
"title": "Auth",
"items": [
{
"id": "auth-api",
@@ -653,7 +650,6 @@
},
{
"title": "Functions",
"items": [
{
"id": "invoke",
@@ -666,7 +662,6 @@
},
{
"title": "Realtime",
"items": [
{
"id": "stream",
@@ -729,7 +724,6 @@
},
{
"title": "Storage",
"items": [
{
"id": "create-bucket",
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+92 -68
View File
@@ -13,14 +13,14 @@
"flags": {},
"children": [
{
"id": 402,
"id": 403,
"name": "StorageApiError",
"kind": 128,
"kindString": "Class",
"flags": {},
"children": [
{
"id": 403,
"id": 404,
"name": "constructor",
"kind": 512,
"kindString": "Constructor",
@@ -34,14 +34,14 @@
],
"signatures": [
{
"id": 404,
"id": 405,
"name": "new StorageApiError",
"kind": 16384,
"kindString": "Constructor signature",
"flags": {},
"parameters": [
{
"id": 405,
"id": 406,
"name": "message",
"kind": 32768,
"kindString": "Parameter",
@@ -52,7 +52,7 @@
}
},
{
"id": 406,
"id": 407,
"name": "status",
"kind": 32768,
"kindString": "Parameter",
@@ -65,24 +65,24 @@
],
"type": {
"type": "reference",
"id": 402,
"id": 403,
"name": "StorageApiError"
},
"overwrites": {
"type": "reference",
"id": 399,
"id": 400,
"name": "StorageError.constructor"
}
}
],
"overwrites": {
"type": "reference",
"id": 398,
"id": 399,
"name": "StorageError.constructor"
}
},
{
"id": 407,
"id": 408,
"name": "status",
"kind": 1024,
"kindString": "Property",
@@ -100,7 +100,7 @@
}
},
{
"id": 408,
"id": 409,
"name": "toJSON",
"kind": 2048,
"kindString": "Method",
@@ -114,7 +114,7 @@
],
"signatures": [
{
"id": 409,
"id": 410,
"name": "toJSON",
"kind": 4096,
"kindString": "Call signature",
@@ -122,14 +122,14 @@
"type": {
"type": "reflection",
"declaration": {
"id": 410,
"id": 411,
"name": "__type",
"kind": 65536,
"kindString": "Type literal",
"flags": {},
"children": [
{
"id": 412,
"id": 413,
"name": "message",
"kind": 1024,
"kindString": "Property",
@@ -148,7 +148,7 @@
"defaultValue": "..."
},
{
"id": 411,
"id": 412,
"name": "name",
"kind": 1024,
"kindString": "Property",
@@ -167,7 +167,7 @@
"defaultValue": "..."
},
{
"id": 413,
"id": 414,
"name": "status",
"kind": 1024,
"kindString": "Property",
@@ -190,7 +190,7 @@
{
"title": "Properties",
"kind": 1024,
"children": [412, 411, 413]
"children": [413, 412, 414]
}
]
}
@@ -203,17 +203,17 @@
{
"title": "Constructors",
"kind": 512,
"children": [403]
"children": [404]
},
{
"title": "Properties",
"kind": 1024,
"children": [407]
"children": [408]
},
{
"title": "Methods",
"kind": 2048,
"children": [408]
"children": [409]
}
],
"sources": [
@@ -226,7 +226,7 @@
"extendedTypes": [
{
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
]
@@ -606,7 +606,7 @@
],
"type": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
}
@@ -815,7 +815,7 @@
],
"type": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
}
@@ -1024,7 +1024,7 @@
],
"type": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
}
@@ -1248,7 +1248,7 @@
],
"type": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
}
@@ -1412,7 +1412,7 @@
],
"type": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
}
@@ -1668,7 +1668,7 @@
],
"type": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
}
@@ -1731,14 +1731,14 @@
]
},
{
"id": 397,
"id": 398,
"name": "StorageError",
"kind": 128,
"kindString": "Class",
"flags": {},
"children": [
{
"id": 398,
"id": 399,
"name": "constructor",
"kind": 512,
"kindString": "Constructor",
@@ -1752,14 +1752,14 @@
],
"signatures": [
{
"id": 399,
"id": 400,
"name": "new StorageError",
"kind": 16384,
"kindString": "Constructor signature",
"flags": {},
"parameters": [
{
"id": 400,
"id": 401,
"name": "message",
"kind": 32768,
"kindString": "Parameter",
@@ -1772,7 +1772,7 @@
],
"type": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
},
"overwrites": {
@@ -1791,7 +1791,7 @@
{
"title": "Constructors",
"kind": 512,
"children": [398]
"children": [399]
}
],
"sources": [
@@ -1812,25 +1812,25 @@
"extendedBy": [
{
"type": "reference",
"id": 402,
"id": 403,
"name": "StorageApiError"
},
{
"type": "reference",
"id": 415,
"id": 416,
"name": "StorageUnknownError"
}
]
},
{
"id": 415,
"id": 416,
"name": "StorageUnknownError",
"kind": 128,
"kindString": "Class",
"flags": {},
"children": [
{
"id": 416,
"id": 417,
"name": "constructor",
"kind": 512,
"kindString": "Constructor",
@@ -1844,14 +1844,14 @@
],
"signatures": [
{
"id": 417,
"id": 418,
"name": "new StorageUnknownError",
"kind": 16384,
"kindString": "Constructor signature",
"flags": {},
"parameters": [
{
"id": 418,
"id": 419,
"name": "message",
"kind": 32768,
"kindString": "Parameter",
@@ -1862,7 +1862,7 @@
}
},
{
"id": 419,
"id": 420,
"name": "originalError",
"kind": 32768,
"kindString": "Parameter",
@@ -1875,24 +1875,24 @@
],
"type": {
"type": "reference",
"id": 415,
"id": 416,
"name": "StorageUnknownError"
},
"overwrites": {
"type": "reference",
"id": 399,
"id": 400,
"name": "StorageError.constructor"
}
}
],
"overwrites": {
"type": "reference",
"id": 398,
"id": 399,
"name": "StorageError.constructor"
}
},
{
"id": 420,
"id": 421,
"name": "originalError",
"kind": 1024,
"kindString": "Property",
@@ -1914,12 +1914,12 @@
{
"title": "Constructors",
"kind": 512,
"children": [416]
"children": [417]
},
{
"title": "Properties",
"kind": 1024,
"children": [420]
"children": [421]
}
],
"sources": [
@@ -1932,7 +1932,7 @@
"extendedTypes": [
{
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
]
@@ -2633,6 +2633,30 @@
"kindString": "Interface",
"flags": {},
"children": [
{
"id": 394,
"name": "format",
"kind": 1024,
"kindString": "Property",
"flags": {
"isOptional": true
},
"comment": {
"shortText": "Specify the format of the image requested.",
"text": "When using 'origin' we force the format to be the same as the original image,\nbypassing automatic browser optimisation such as webp conversion\n"
},
"sources": [
{
"fileName": "src/lib/types.ts",
"line": 98,
"character": 2
}
],
"type": {
"type": "literal",
"value": "origin"
}
},
{
"id": 392,
"name": "height",
@@ -2720,7 +2744,7 @@
{
"title": "Properties",
"kind": 1024,
"children": [392, 393, 391]
"children": [394, 392, 393, 391]
}
],
"sources": [
@@ -2732,7 +2756,7 @@
]
},
{
"id": 394,
"id": 395,
"name": "isStorageError",
"kind": 64,
"kindString": "Function",
@@ -2746,14 +2770,14 @@
],
"signatures": [
{
"id": 395,
"id": 396,
"name": "isStorageError",
"kind": 4096,
"kindString": "Call signature",
"flags": {},
"parameters": [
{
"id": 396,
"id": 397,
"name": "error",
"kind": 32768,
"kindString": "Parameter",
@@ -2770,7 +2794,7 @@
"asserts": false,
"targetType": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
}
@@ -2782,7 +2806,7 @@
{
"title": "Classes",
"kind": 128,
"children": [402, 266, 397, 415]
"children": [403, 266, 398, 416]
},
{
"title": "Interfaces",
@@ -2792,7 +2816,7 @@
{
"title": "Functions",
"kind": 64,
"children": [394]
"children": [395]
}
],
"sources": [
@@ -3175,7 +3199,7 @@
],
"type": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
}
@@ -3374,7 +3398,7 @@
],
"type": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
}
@@ -3573,7 +3597,7 @@
],
"type": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
}
@@ -3740,7 +3764,7 @@
],
"type": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
}
@@ -3894,7 +3918,7 @@
],
"type": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
}
@@ -4140,7 +4164,7 @@
],
"type": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
}
@@ -4578,7 +4602,7 @@
],
"type": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
}
@@ -4875,7 +4899,7 @@
],
"type": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
}
@@ -5206,7 +5230,7 @@
],
"type": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
}
@@ -5426,7 +5450,7 @@
],
"type": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
}
@@ -5822,7 +5846,7 @@
],
"type": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
}
@@ -6035,7 +6059,7 @@
],
"type": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
}
@@ -6208,7 +6232,7 @@
],
"type": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
}
@@ -6502,7 +6526,7 @@
],
"type": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
}
@@ -6796,7 +6820,7 @@
],
"type": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
}
@@ -13,14 +13,14 @@
"flags": {},
"children": [
{
"id": 402,
"id": 403,
"name": "StorageApiError",
"kind": 128,
"kindString": "Class",
"flags": {},
"children": [
{
"id": 403,
"id": 404,
"name": "constructor",
"kind": 512,
"kindString": "Constructor",
@@ -34,14 +34,14 @@
],
"signatures": [
{
"id": 404,
"id": 405,
"name": "new StorageApiError",
"kind": 16384,
"kindString": "Constructor signature",
"flags": {},
"parameters": [
{
"id": 405,
"id": 406,
"name": "message",
"kind": 32768,
"kindString": "Parameter",
@@ -52,7 +52,7 @@
}
},
{
"id": 406,
"id": 407,
"name": "status",
"kind": 32768,
"kindString": "Parameter",
@@ -65,24 +65,24 @@
],
"type": {
"type": "reference",
"id": 402,
"id": 403,
"name": "StorageApiError"
},
"overwrites": {
"type": "reference",
"id": 399,
"id": 400,
"name": "StorageError.constructor"
}
}
],
"overwrites": {
"type": "reference",
"id": 398,
"id": 399,
"name": "StorageError.constructor"
}
},
{
"id": 407,
"id": 408,
"name": "status",
"kind": 1024,
"kindString": "Property",
@@ -100,7 +100,7 @@
}
},
{
"id": 408,
"id": 409,
"name": "toJSON",
"kind": 2048,
"kindString": "Method",
@@ -114,7 +114,7 @@
],
"signatures": [
{
"id": 409,
"id": 410,
"name": "toJSON",
"kind": 4096,
"kindString": "Call signature",
@@ -122,14 +122,14 @@
"type": {
"type": "reflection",
"declaration": {
"id": 410,
"id": 411,
"name": "__type",
"kind": 65536,
"kindString": "Type literal",
"flags": {},
"children": [
{
"id": 412,
"id": 413,
"name": "message",
"kind": 1024,
"kindString": "Property",
@@ -148,7 +148,7 @@
"defaultValue": "..."
},
{
"id": 411,
"id": 412,
"name": "name",
"kind": 1024,
"kindString": "Property",
@@ -167,7 +167,7 @@
"defaultValue": "..."
},
{
"id": 413,
"id": 414,
"name": "status",
"kind": 1024,
"kindString": "Property",
@@ -190,7 +190,7 @@
{
"title": "Properties",
"kind": 1024,
"children": [412, 411, 413]
"children": [413, 412, 414]
}
]
}
@@ -203,17 +203,17 @@
{
"title": "Constructors",
"kind": 512,
"children": [403]
"children": [404]
},
{
"title": "Properties",
"kind": 1024,
"children": [407]
"children": [408]
},
{
"title": "Methods",
"kind": 2048,
"children": [408]
"children": [409]
}
],
"sources": [
@@ -226,7 +226,7 @@
"extendedTypes": [
{
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
]
@@ -606,7 +606,7 @@
],
"type": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
}
@@ -815,7 +815,7 @@
],
"type": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
}
@@ -1024,7 +1024,7 @@
],
"type": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
}
@@ -1248,7 +1248,7 @@
],
"type": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
}
@@ -1412,7 +1412,7 @@
],
"type": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
}
@@ -1668,7 +1668,7 @@
],
"type": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
}
@@ -1731,14 +1731,14 @@
]
},
{
"id": 397,
"id": 398,
"name": "StorageError",
"kind": 128,
"kindString": "Class",
"flags": {},
"children": [
{
"id": 398,
"id": 399,
"name": "constructor",
"kind": 512,
"kindString": "Constructor",
@@ -1752,14 +1752,14 @@
],
"signatures": [
{
"id": 399,
"id": 400,
"name": "new StorageError",
"kind": 16384,
"kindString": "Constructor signature",
"flags": {},
"parameters": [
{
"id": 400,
"id": 401,
"name": "message",
"kind": 32768,
"kindString": "Parameter",
@@ -1772,7 +1772,7 @@
],
"type": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
},
"overwrites": {
@@ -1791,7 +1791,7 @@
{
"title": "Constructors",
"kind": 512,
"children": [398]
"children": [399]
}
],
"sources": [
@@ -1812,25 +1812,25 @@
"extendedBy": [
{
"type": "reference",
"id": 402,
"id": 403,
"name": "StorageApiError"
},
{
"type": "reference",
"id": 415,
"id": 416,
"name": "StorageUnknownError"
}
]
},
{
"id": 415,
"id": 416,
"name": "StorageUnknownError",
"kind": 128,
"kindString": "Class",
"flags": {},
"children": [
{
"id": 416,
"id": 417,
"name": "constructor",
"kind": 512,
"kindString": "Constructor",
@@ -1844,14 +1844,14 @@
],
"signatures": [
{
"id": 417,
"id": 418,
"name": "new StorageUnknownError",
"kind": 16384,
"kindString": "Constructor signature",
"flags": {},
"parameters": [
{
"id": 418,
"id": 419,
"name": "message",
"kind": 32768,
"kindString": "Parameter",
@@ -1862,7 +1862,7 @@
}
},
{
"id": 419,
"id": 420,
"name": "originalError",
"kind": 32768,
"kindString": "Parameter",
@@ -1875,24 +1875,24 @@
],
"type": {
"type": "reference",
"id": 415,
"id": 416,
"name": "StorageUnknownError"
},
"overwrites": {
"type": "reference",
"id": 399,
"id": 400,
"name": "StorageError.constructor"
}
}
],
"overwrites": {
"type": "reference",
"id": 398,
"id": 399,
"name": "StorageError.constructor"
}
},
{
"id": 420,
"id": 421,
"name": "originalError",
"kind": 1024,
"kindString": "Property",
@@ -1914,12 +1914,12 @@
{
"title": "Constructors",
"kind": 512,
"children": [416]
"children": [417]
},
{
"title": "Properties",
"kind": 1024,
"children": [420]
"children": [421]
}
],
"sources": [
@@ -1932,7 +1932,7 @@
"extendedTypes": [
{
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
]
@@ -2827,6 +2827,30 @@
"kindString": "Interface",
"flags": {},
"children": [
{
"id": 394,
"name": "format",
"kind": 1024,
"kindString": "Property",
"flags": {
"isOptional": true
},
"comment": {
"shortText": "Specify the format of the image requested.",
"text": "When using 'origin' we force the format to be the same as the original image,\nbypassing automatic browser optimisation such as webp conversion\n"
},
"sources": [
{
"fileName": "src/lib/types.ts",
"line": 98,
"character": 2
}
],
"type": {
"type": "literal",
"value": "origin"
}
},
{
"id": 392,
"name": "height",
@@ -2914,7 +2938,7 @@
{
"title": "Properties",
"kind": 1024,
"children": [392, 393, 391]
"children": [394, 392, 393, 391]
}
],
"sources": [
@@ -2926,7 +2950,7 @@
]
},
{
"id": 394,
"id": 395,
"name": "isStorageError",
"kind": 64,
"kindString": "Function",
@@ -2940,14 +2964,14 @@
],
"signatures": [
{
"id": 395,
"id": 396,
"name": "isStorageError",
"kind": 4096,
"kindString": "Call signature",
"flags": {},
"parameters": [
{
"id": 396,
"id": 397,
"name": "error",
"kind": 32768,
"kindString": "Parameter",
@@ -2964,7 +2988,7 @@
"asserts": false,
"targetType": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
}
@@ -2976,7 +3000,7 @@
{
"title": "Classes",
"kind": 128,
"children": [402, 266, 397, 415]
"children": [403, 266, 398, 416]
},
{
"title": "Interfaces",
@@ -2986,7 +3010,7 @@
{
"title": "Functions",
"kind": 64,
"children": [394]
"children": [395]
}
],
"sources": [
@@ -3369,7 +3393,7 @@
],
"type": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
}
@@ -3568,7 +3592,7 @@
],
"type": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
}
@@ -3767,7 +3791,7 @@
],
"type": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
}
@@ -3934,7 +3958,7 @@
],
"type": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
}
@@ -4088,7 +4112,7 @@
],
"type": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
}
@@ -4334,7 +4358,7 @@
],
"type": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
}
@@ -4772,7 +4796,7 @@
],
"type": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
}
@@ -4926,6 +4950,30 @@
"kindString": "Interface",
"flags": {},
"children": [
{
"id": 394,
"name": "format",
"kind": 1024,
"kindString": "Property",
"flags": {
"isOptional": true
},
"comment": {
"shortText": "Specify the format of the image requested.",
"text": "When using 'origin' we force the format to be the same as the original image,\nbypassing automatic browser optimisation such as webp conversion\n"
},
"sources": [
{
"fileName": "src/lib/types.ts",
"line": 98,
"character": 2
}
],
"type": {
"type": "literal",
"value": "origin"
}
},
{
"id": 392,
"name": "height",
@@ -5013,7 +5061,7 @@
{
"title": "Properties",
"kind": 1024,
"children": [392, 393, 391]
"children": [394, 392, 393, 391]
}
],
"sources": [
@@ -5174,7 +5222,7 @@
],
"type": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
}
@@ -5505,7 +5553,7 @@
],
"type": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
}
@@ -5613,6 +5661,30 @@
"kindString": "Interface",
"flags": {},
"children": [
{
"id": 394,
"name": "format",
"kind": 1024,
"kindString": "Property",
"flags": {
"isOptional": true
},
"comment": {
"shortText": "Specify the format of the image requested.",
"text": "When using 'origin' we force the format to be the same as the original image,\nbypassing automatic browser optimisation such as webp conversion\n"
},
"sources": [
{
"fileName": "src/lib/types.ts",
"line": 98,
"character": 2
}
],
"type": {
"type": "literal",
"value": "origin"
}
},
{
"id": 392,
"name": "height",
@@ -5700,7 +5772,7 @@
{
"title": "Properties",
"kind": 1024,
"children": [392, 393, 391]
"children": [394, 392, 393, 391]
}
],
"sources": [
@@ -5830,7 +5902,7 @@
],
"type": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
}
@@ -5970,6 +6042,30 @@
"kindString": "Interface",
"flags": {},
"children": [
{
"id": 394,
"name": "format",
"kind": 1024,
"kindString": "Property",
"flags": {
"isOptional": true
},
"comment": {
"shortText": "Specify the format of the image requested.",
"text": "When using 'origin' we force the format to be the same as the original image,\nbypassing automatic browser optimisation such as webp conversion\n"
},
"sources": [
{
"fileName": "src/lib/types.ts",
"line": 98,
"character": 2
}
],
"type": {
"type": "literal",
"value": "origin"
}
},
{
"id": 392,
"name": "height",
@@ -6057,7 +6153,7 @@
{
"title": "Properties",
"kind": 1024,
"children": [392, 393, 391]
"children": [394, 392, 393, 391]
}
],
"sources": [
@@ -6558,7 +6654,7 @@
],
"type": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
}
@@ -6771,7 +6867,7 @@
],
"type": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
}
@@ -6944,7 +7040,7 @@
],
"type": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
}
@@ -7330,7 +7426,7 @@
],
"type": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
}
@@ -7716,7 +7812,7 @@
],
"type": {
"type": "reference",
"id": 397,
"id": 398,
"name": "StorageError"
}
}
+3 -1
View File
@@ -724,7 +724,9 @@
"properties": {
"height": { "type": "integer", "minimum": 0, "example": 100 },
"width": { "type": "integer", "minimum": 0, "example": 100 },
"resize": { "type": "string", "enum": ["cover", "contain", "fill"] }
"resize": { "type": "string", "enum": ["cover", "contain", "fill"] },
"format": { "type": "string", "enum": ["origin", "avif"] },
"quality": { "type": "integer", "minimum": 20, "maximum": 100 }
}
}
},
File diff suppressed because it is too large. Load diff
+5 -6
View File
@@ -176,7 +176,7 @@ functions:
```
- id: sign-up-with-redirect
name: Sign up with a redirect URL
description: |
description: |
- See [redirect URLs and wildcards](/docs/guides/auth/overview#redirect-urls-and-wildcards) to add additional redirect URLs to your project.
code: |
```js
@@ -3991,11 +3991,10 @@ functions:
title: on().subscribe()
$ref: '@supabase/realtime-js.RealtimeChannel.on'
notes: |
- Realtime is disabled by default for new Projects for better database performance and security. You can turn it on by [managing replication](/docs/guides/api#managing-realtime).
- Row level security is not applied to delete statements.
- If you want to receive the "previous" data for updates and deletes, you will need to set `REPLICA IDENTITY` to `FULL`, like this: `ALTER TABLE your_table REPLICA IDENTITY FULL;`
- When a delete occurs, the contents of old_record will be broadcast to all subscribers to that table so ensure that each table's replica identity only contains information that is safe to expose publicly.
- The channel name must exactly match the schema/table/filter you want to listen to separated by colons. See below examples for additional context.
- By default, Broadcast and Presence are enabled for all projects.
- By default, listening to database changes is disabled for new projects due to database performance and security concerns. You can turn it on by managing Realtime's [replication](/docs/guides/api#realtime-api-overview).
- You can receive the "previous" data for updates and deletes by setting the table's `REPLICA IDENTITY` to `FULL` (e.g., `ALTER TABLE your_table REPLICA IDENTITY FULL;`).
- Row level security is not applied to delete statements. When RLS is enabled and replica identity is set to full, only the primary key is sent to clients.
examples:
- id: listen-to-broadcast
name: Listen to broadcast messages
@@ -570,9 +570,6 @@
},
"import_map": {
"type": "boolean"
},
"body": {
"type": "string"
}
},
"required": [
@@ -2484,9 +2481,6 @@
},
"import_map": {
"type": "boolean"
},
"body": {
"type": "string"
}
},
"required": ["id", "slug", "name", "status", "version", "created_at", "updated_at"]
@@ -1128,6 +1128,15 @@
"resize": {
"type": "string",
"enum": ["cover", "contain", "fill"]
},
"format": {
"type": "string",
"enum": ["origin", "avif"]
},
"quality": {
"type": "integer",
"minimum": 20,
"maximum": 100
}
}
}
@@ -257,7 +257,7 @@ export const SQL_FILTER_TEMPLATES: any = {
"severity.error": `REGEXP_CONTAINS(event_message, "level.{3}error|level.{3}fatal")`,
"severity.warning": `REGEXP_CONTAINS(event_message, "level.{3}warning")`,
"severity.info": `REGEXP_CONTAINS(event_message, "level.{3}info")`,
"status_code.server_error": `REGEXP_CONTAINS(event_message, "status.{3}5[0-9]{2}`,
"status_code.server_error": `REGEXP_CONTAINS(event_message, "status.{3}5[0-9]{2}")`,
"status_code.client_error": `REGEXP_CONTAINS(event_message, "status.{3}4[0-9]{2}")`,
"status_code.redirection": `REGEXP_CONTAINS(event_message, "status.{3}3[0-9]{2}")`,
"status_code.success": `REGEXP_CONTAINS(event_message, "status.{3}2[0-9]{2}")`,
@@ -12,10 +12,11 @@ import {
IconLoader,
IconAlertCircle,
IconExternalLink,
Checkbox,
} from 'ui'
import { CLIENT_LIBRARIES } from 'common/constants'
import { Project } from 'types'
import { Organization, Project } from 'types'
import { useStore, useFlag } from 'hooks'
import { post, get } from 'lib/common/fetch'
import { API_URL, PRICING_TIER_PRODUCT_IDS } from 'lib/constants'
@@ -50,8 +51,9 @@ const SupportForm: FC<Props> = ({ setSentCategory }) => {
const sortedOrganizations = app.organizations.list()
const sortedProjects = app.projects.list()
const projectDefaults: Partial<Project>[] = [{ ref: 'no-project', name: 'No specific project' }]
const isInitialized = app.projects.isInitialized
const projectDefaults: Partial<Project>[] = [{ ref: 'no-project', name: 'No specific project' }]
const projects = [...sortedProjects, ...projectDefaults]
const planNames = {
@@ -84,18 +86,29 @@ const SupportForm: FC<Props> = ({ setSentCategory }) => {
const selectedCategory = CATEGORY_OPTIONS.find((option) => {
if (option.value.toLowerCase() === ((category as string) ?? '').toLowerCase()) return option
})
const initialProjectRef =
selectedProject !== undefined
? selectedProject.ref
: sortedProjects.length > 0
? sortedProjects[0].ref
: 'no-project'
const initialOrganizationSlug =
initialProjectRef !== 'no-project'
? sortedOrganizations.find((org) => {
const project = sortedProjects.find((project) => project.ref === initialProjectRef)
return org.id === project?.organization_id
})?.slug
: sortedOrganizations[0]?.slug
const initialValues = {
category: selectedCategory !== undefined ? selectedCategory.value : CATEGORY_OPTIONS[0].value,
severity: 'Low',
projectRef:
selectedProject !== undefined
? selectedProject.ref
: sortedProjects.length > 0
? sortedProjects[0].ref
: 'no-project',
projectRef: initialProjectRef,
organizationSlug: initialOrganizationSlug,
library: 'no-library',
subject: subject ?? '',
message: '',
allowSupportAccess: false,
}
const onFilesUpload = async (event: ChangeEvent<HTMLInputElement>) => {
@@ -178,11 +191,10 @@ const SupportForm: FC<Props> = ({ setSentCategory }) => {
return (
<Form id="support-form" initialValues={initialValues} validate={onValidate} onSubmit={onSubmit}>
{({ isSubmitting, values }: any) => {
{({ isSubmitting, resetForm, values }: any) => {
const selectedCategory = CATEGORY_OPTIONS.find(
(category) => category.value === values.category
)
const selectedLibrary = CLIENT_LIBRARIES.find(
(library) => library.language === values.library
)
@@ -200,8 +212,20 @@ const SupportForm: FC<Props> = ({ setSentCategory }) => {
['Performance', 'Problem'].includes(values.category)
useEffect(() => {
if (selectedProject && !selectedProject.subscription_tier) {
app.projects.fetchSubscriptionTier(selectedProject as Project)
if (values.projectRef === 'no-project') {
const updatedValues = { ...values, organizationSlug: sortedOrganizations[0]?.slug }
resetForm({ values: updatedValues, initialValues: updatedValues })
} else if (selectedProject) {
if (!selectedProject.subscription_tier) {
app.projects.fetchSubscriptionTier(selectedProject as Project)
}
const organization = sortedOrganizations.find(
(org) => org.id === selectedProject.organization_id
)
if (organization) {
const updatedValues = { ...values, organizationSlug: organization.slug }
resetForm({ values: updatedValues, initialValues: updatedValues })
}
}
}, [values.projectRef])
@@ -284,6 +308,28 @@ const SupportForm: FC<Props> = ({ setSentCategory }) => {
)}
</div>
{values.projectRef === 'no-project' && sortedOrganizations.length > 0 && (
<div className="px-6">
<Listbox
id="organizationSlug"
layout="vertical"
label="Which organization is affected?"
>
{sortedOrganizations.map((option) => {
return (
<Listbox.Option
key={`option-${option.slug}`}
label={option.name || ''}
value={option.slug}
>
<span>{option.name}</span>
</Listbox.Option>
)
})}
</Listbox>
</div>
)}
{selectedProject?.subscription_tier === PRICING_TIER_PRODUCT_IDS.FREE && (
<div className="px-6">
<InformationBox
@@ -328,71 +374,105 @@ const SupportForm: FC<Props> = ({ setSentCategory }) => {
{!isDisabled ? (
<>
<div className="px-6">
<Input
id="subject"
label="Subject"
placeholder="Summary of the problem you have"
{['Performance'].includes(values.category) ? (
<DisabledStateForFreeTier
category={selectedCategory?.label ?? ''}
projectRef={values.projectRef}
/>
</div>
{values.category === 'Problem' && (
<div className="px-6">
<Listbox
id="library"
layout="vertical"
label="Which library are you having issues with?"
>
<Listbox.Option
disabled
label="Please select a library"
value="no-library"
className="min-w-[500px]"
>
<span>Please select a library</span>
</Listbox.Option>
{CLIENT_LIBRARIES.map((option, i) => {
return (
) : (
<>
<div className="px-6">
<Input
id="subject"
label="Subject"
placeholder="Summary of the problem you have"
/>
</div>
{values.category === 'Problem' && (
<div className="px-6">
<Listbox
id="library"
layout="vertical"
label="Which library are you having issues with?"
>
<Listbox.Option
key={`option-${option.key}`}
label={option.language}
value={option.language}
disabled
label="Please select a library"
value="no-library"
className="min-w-[500px]"
>
<span>{option.language}</span>
<span>Please select a library</span>
</Listbox.Option>
)
})}
</Listbox>
</div>
)}
{CLIENT_LIBRARIES.map((option, i) => {
return (
<Listbox.Option
key={`option-${option.key}`}
label={option.language}
value={option.language}
className="min-w-[500px]"
>
<span>{option.language}</span>
</Listbox.Option>
)
})}
</Listbox>
</div>
)}
{selectedLibrary !== undefined && (
<div className="px-6 space-y-4 !mt-4">
<div className="space-y-2">
<p className="text-sm text-scale-1100">
Found an issue or a bug? Try searching our Github issues or submit a new
one.
</p>
</div>
<div className="flex items-center space-x-4 overflow-x-auto">
{selectedClientLibraries?.map((library) => {
const libraryLanguage =
values.library === 'Dart (Flutter)'
? library.name.split('-')[1]
: values.library
return (
{selectedLibrary !== undefined && (
<div className="px-6 space-y-4 !mt-4">
<div className="space-y-2">
<p className="text-sm text-scale-1100">
Found an issue or a bug? Try searching our Github issues or submit a new
one.
</p>
</div>
<div className="flex items-center space-x-4 overflow-x-auto">
{selectedClientLibraries?.map((library) => {
const libraryLanguage =
values.library === 'Dart (Flutter)'
? library.name.split('-')[1]
: values.library
return (
<div
key={library.name}
className="w-[230px] min-w-[230px] min-h-[128px] rounded border border-scale-600 bg-scale-300 space-y-3 px-4 py-3"
>
<div className="space-y-1">
<p className="text-sm">{library.name}</p>
<p className="text-sm text-scale-1100">
For issues regarding the {libraryLanguage} client library
</p>
</div>
<div>
<Link href={library.url}>
<a target="_blank">
<Button
type="default"
icon={<IconExternalLink size={14} strokeWidth={1.5} />}
>
View Github issues
</Button>
</a>
</Link>
</div>
</div>
)
})}
<div
key={library.name}
className="w-[230px] min-w-[230px] min-h-[128px] rounded border border-scale-600 bg-scale-300 space-y-3 px-4 py-3"
className={[
'px-4 py-3 rounded border border-scale-600 bg-scale-300',
'w-[230px] min-w-[230px] min-h-[128px] flex flex-col justify-between space-y-3',
].join(' ')}
>
<div className="space-y-1">
<p className="text-sm">{library.name}</p>
<p className="text-sm">supabase</p>
<p className="text-sm text-scale-1100">
For issues regarding the {libraryLanguage} client library
For any issues about our API
</p>
</div>
<div>
<Link href={library.url}>
<Link href="https://github.com/supabase/supabase">
<a target="_blank">
<Button
type="default"
@@ -404,125 +484,108 @@ const SupportForm: FC<Props> = ({ setSentCategory }) => {
</Link>
</div>
</div>
)
})}
<div
className={[
'px-4 py-3 rounded border border-scale-600 bg-scale-300',
'w-[230px] min-w-[230px] min-h-[128px] flex flex-col justify-between space-y-3',
].join(' ')}
>
<div className="space-y-1">
<p className="text-sm">supabase</p>
<p className="text-sm text-scale-1100">For any issues about our API</p>
</div>
<div>
<Link href="https://github.com/supabase/supabase">
<a target="_blank">
<Button
type="default"
icon={<IconExternalLink size={14} strokeWidth={1.5} />}
>
View Github issues
</Button>
</a>
</Link>
</div>
</div>
</div>
</div>
)}
<div className="px-6 space-y-2">
<p className="text-sm text-scale-1100">Which services are affected?</p>
<MultiSelect
options={SERVICE_OPTIONS}
value={selectedServices}
placeholder="No particular service"
searchPlaceholder="Search for a service"
onChange={setSelectedServices}
/>
</div>
<div className="text-area-text-sm px-6">
<Input.TextArea
id="message"
label="Message"
placeholder="Describe the issue you're facing, along with any relevant information. Please be as detailed and specific as possible."
limit={5000}
labelOptional="5000 character limit"
/>
</div>
<div className="space-y-4 px-6">
<div className="space-y-1">
<p className="block text-sm text-scale-1100">Attachments</p>
<p className="block text-sm text-scale-1000">
Upload up to {MAX_ATTACHMENTS} screenshots that might be relevant to the issue
that you're facing
</p>
</div>
<div>
<input
multiple
type="file"
// @ts-ignore
ref={uploadButtonRef}
className="hidden"
accept="image/png, image/jpeg"
onChange={onFilesUpload}
/>
</div>
<div className="flex items-center space-x-2">
{uploadedDataUrls.map((x: any, idx: number) => (
<div
key={idx}
style={{ backgroundImage: `url("${x}")` }}
className="relative h-14 w-14 rounded bg-cover bg-center bg-no-repeat"
>
<div
className={[
'flex h-4 w-4 items-center justify-center rounded-full bg-red-900',
'absolute -top-1 -right-1 cursor-pointer',
].join(' ')}
onClick={() => removeUploadedFile(idx)}
>
<IconX size={12} strokeWidth={2} />
</div>
</div>
))}
{uploadedFiles.length < MAX_ATTACHMENTS && (
<div
className={[
'border border-scale-800 opacity-50 transition hover:opacity-100',
'group flex h-14 w-14 cursor-pointer items-center justify-center rounded',
].join(' ')}
onClick={() => {
if (uploadButtonRef.current) (uploadButtonRef.current as any).click()
}}
>
<IconPlus strokeWidth={2} size={20} />
</div>
)}
</div>
</div>
<div className="px-6">
<div className="flex justify-end">
<Button
htmlType="submit"
size="small"
icon={<IconMail />}
disabled={isSubmitting}
loading={isSubmitting}
>
Send support request
</Button>
</div>
</div>
<div className="px-6 space-y-2">
<p className="text-sm text-scale-1100">Which services are affected?</p>
<MultiSelect
options={SERVICE_OPTIONS}
value={selectedServices}
placeholder="No particular service"
searchPlaceholder="Search for a service"
onChange={setSelectedServices}
/>
</div>
<div className="text-area-text-sm px-6">
<Input.TextArea
id="message"
label="Message"
placeholder="Describe the issue you're facing, along with any relevant information. Please be as detailed and specific as possible."
limit={5000}
labelOptional="5000 character limit"
/>
</div>
{['Problem', 'Database_unresponsive', 'Performance'].includes(
values.category
) && (
<div className="px-6">
<Checkbox
name="allowSupportAccess"
label="Allow Supabase Support to access your project temporarily"
description="In some cases, we may require temporary access to your project to complete troubleshooting, or to answer questions related specifically to your project"
/>
</div>
)}
<div className="space-y-4 px-6">
<div className="space-y-1">
<p className="block text-sm text-scale-1100">Attachments</p>
<p className="block text-sm text-scale-1000">
Upload up to {MAX_ATTACHMENTS} screenshots that might be relevant to the
issue that you're facing
</p>
</div>
<div>
<input
multiple
type="file"
// @ts-ignore
ref={uploadButtonRef}
className="hidden"
accept="image/png, image/jpeg"
onChange={onFilesUpload}
/>
</div>
<div className="flex items-center space-x-2">
{uploadedDataUrls.map((x: any, idx: number) => (
<div
key={idx}
style={{ backgroundImage: `url("${x}")` }}
className="relative h-14 w-14 rounded bg-cover bg-center bg-no-repeat"
>
<div
className={[
'flex h-4 w-4 items-center justify-center rounded-full bg-red-900',
'absolute -top-1 -right-1 cursor-pointer',
].join(' ')}
onClick={() => removeUploadedFile(idx)}
>
<IconX size={12} strokeWidth={2} />
</div>
</div>
))}
{uploadedFiles.length < MAX_ATTACHMENTS && (
<div
className={[
'border border-scale-800 opacity-50 transition hover:opacity-100',
'group flex h-14 w-14 cursor-pointer items-center justify-center rounded',
].join(' ')}
onClick={() => {
if (uploadButtonRef.current) (uploadButtonRef.current as any).click()
}}
>
<IconPlus strokeWidth={2} size={20} />
</div>
)}
</div>
</div>
<div className="px-6">
<div className="flex justify-end">
<Button
htmlType="submit"
size="small"
icon={<IconMail />}
disabled={isSubmitting}
loading={isSubmitting}
>
Send support request
</Button>
</div>
</div>
</>
)}
</>
) : ['Problem', 'Performance'].includes(values.category) ? (
<DisabledStateForFreeTier
category={selectedCategory?.label ?? ''}
projectRef={values.projectRef}
/>
) : (
<></>
)}
@@ -88,10 +88,10 @@ const DisplayApiSettings = () => {
))}
{x.tags === 'service_role' && (
<>
<code className="text-xs text-white bg-red-900">{'secret'}</code>
<code className="bg-red-900 text-xs text-white">secret</code>
</>
)}
{x.tags === 'anon' && <code className="text-xs text-code">{'public'}</code>}
{x.tags === 'anon' && <code className="text-xs text-code">public</code>}
</>
}
copy={canReadAPIKeys && isNotUpdatingJwtSecret}
+9 -6
View File
@@ -12,6 +12,14 @@ const withTM = require('next-transpile-modules')(['ui', 'common'])
// https://nextjs.org/docs/api-reference/next.config.js/introduction
// https://docs.sentry.io/platforms/javascript/guides/nextjs/
const csp = [
"frame-ancestors 'none';",
// IS_PLATFORM
process.env.NEXT_PUBLIC_IS_PLATFORM === 'true' ? 'upgrade-insecure-requests;' : '',
]
.filter(Boolean)
.join(' ')
const nextConfig = {
async redirects() {
return [
@@ -137,12 +145,7 @@ const nextConfig = {
},
{
key: 'Content-Security-Policy',
value: `
frame-ancestors 'none';
upgrade-insecure-requests;
`
.replace(/\s{2,}/g, ' ')
.trim(),
value: csp,
},
{
key: 'Referrer-Policy',
+1 -1
View File
@@ -55,7 +55,7 @@ const GenericProjectPage: NextPage = () => {
<>
<Header />
<div className="flex flex-col mx-auto w-full max-w-5xl">
<h3 className="mt-8 text-2xl">Select a project to continue</h3>
<h1 className="mt-8 text-2xl">Select a project to continue</h1>
<div
className="flex-grow py-6 space-y-8 overflow-y-auto"
style={{ maxHeight: 'calc(100vh - 49px - 64px)' }}
+1 -1
View File
@@ -29,7 +29,7 @@ const SupportPage = () => {
<div className="flex justify-between items-center">
<div className="flex items-center space-x-3">
<SVG src={`/img/supabase-logo.svg`} className="h-4 w-4" />
<h4 className="m-0 text-lg">Supabase support</h4>
<h1 className="m-0 text-lg">Supabase support</h1>
</div>
<div className="flex items-center space-x-3">
<Tooltip.Root delayDuration={0}>