+
+ )
+}
+
+export default withAuth(observer(PageLayout))
diff --git a/studio/pages/project/[ref]/functions/[id]/invocations.tsx b/studio/pages/project/[ref]/functions/[id]/invocations.tsx
new file mode 100644
index 00000000000..b3603421de8
--- /dev/null
+++ b/studio/pages/project/[ref]/functions/[id]/invocations.tsx
@@ -0,0 +1,32 @@
+import React from 'react'
+import { NextPage } from 'next'
+import { useRouter } from 'next/router'
+import { observer } from 'mobx-react-lite'
+import { withAuth } from 'hooks'
+import { LOG_TYPE_LABEL_MAPPING } from 'components/interfaces/Settings/Logs'
+import LogsPreviewer from 'components/interfaces/Settings/Logs/LogsPreviewer'
+import FunctionLayout from '../../../../../components/interfaces/functions/FunctionLayout'
+
+/**
+ * Placeholder page for logs previewers until we figure out where to slot them
+ */
+export const LogPage: NextPage = () => {
+ const router = useRouter()
+ const { ref, type, id } = router.query
+
+ const title = `Invocation Logs - ${
+ LOG_TYPE_LABEL_MAPPING[type as keyof typeof LOG_TYPE_LABEL_MAPPING]
+ }`
+
+ return (
+
+
+
+ )
+}
+
+export default withAuth(observer(LogPage))
diff --git a/studio/pages/project/[ref]/functions/[id]/logs.tsx b/studio/pages/project/[ref]/functions/[id]/logs.tsx
new file mode 100644
index 00000000000..b553e520703
--- /dev/null
+++ b/studio/pages/project/[ref]/functions/[id]/logs.tsx
@@ -0,0 +1,32 @@
+import React from 'react'
+import { NextPage } from 'next'
+import { useRouter } from 'next/router'
+import { observer } from 'mobx-react-lite'
+import { withAuth } from 'hooks'
+import { LOG_TYPE_LABEL_MAPPING } from 'components/interfaces/Settings/Logs'
+import LogsPreviewer from 'components/interfaces/Settings/Logs/LogsPreviewer'
+import FunctionLayout from '../../../../../components/interfaces/functions/FunctionLayout'
+
+/**
+ * Placeholder page for logs previewers until we figure out where to slot them
+ */
+export const LogPage: NextPage = () => {
+ const router = useRouter()
+ const { ref, type, id } = router.query
+
+ const title = `Function Logs - ${
+ LOG_TYPE_LABEL_MAPPING[type as keyof typeof LOG_TYPE_LABEL_MAPPING]
+ }`
+
+ return (
+
+
+
+ )
+}
+
+export default withAuth(observer(LogPage))
diff --git a/studio/pages/project/[ref]/functions/[id]/triggers.tsx b/studio/pages/project/[ref]/functions/[id]/triggers.tsx
new file mode 100644
index 00000000000..feb8d9299c8
--- /dev/null
+++ b/studio/pages/project/[ref]/functions/[id]/triggers.tsx
@@ -0,0 +1,10 @@
+import { observer } from 'mobx-react-lite'
+import { withAuth } from 'hooks'
+
+import FunctionLayout from '../../../../../components/interfaces/functions/FunctionLayout'
+
+const PageLayout = () => {
+ return Triggers
+}
+
+export default withAuth(observer(PageLayout))
diff --git a/studio/pages/project/[ref]/functions/index.tsx b/studio/pages/project/[ref]/functions/index.tsx
new file mode 100644
index 00000000000..6312801a979
--- /dev/null
+++ b/studio/pages/project/[ref]/functions/index.tsx
@@ -0,0 +1,295 @@
+import { observer } from 'mobx-react-lite'
+import { useStore, withAuth } from 'hooks'
+
+import FunctionsLayout from '../../../../components/interfaces/functions/FunctionsLayout'
+import { Button, IconBookOpen, IconSearch, IconTerminal, Input, Loading } from '@supabase/ui'
+import { useEffect } from 'react'
+import Table from 'components/to-be-cleaned/Table'
+
+import FunctionsListItem from '../../../../components/interfaces/functions/FunctionsListItem'
+import { useRouter } from 'next/router'
+
+import { post } from 'lib/common/fetch'
+import { API_URL, PROJECT_STATUS } from 'lib/constants'
+
+import CommandRender from '../../../../components/interfaces/functions/CommandRender'
+import Link from 'next/link'
+
+import { Function } from '../../../../components/interfaces/functions/Functions.types'
+
+const EmptyFunctions = () => {
+ const router = useRouter()
+ const { ref } = router.query
+
+ interface Commands {
+ command: string
+ description: string
+ jsx?: () => void
+ comment?: string
+ }
+ const commands: Commands[] = [
+ {
+ command: 'supabase init ',
+ description: "Needed if the project hasen't been inited before",
+ jsx: () => {
+ return (
+ <>
+ supabase init
+ >
+ )
+ },
+ comment: 'Initialize Supabase locally',
+ },
+ {
+ command: 'supabase login',
+ description: "Writes the user's API token to disk",
+ jsx: () => {
+ return (
+ <>
+ supabase login
+ >
+ )
+ },
+ comment: 'Login using your access token',
+ },
+ {
+ command: `supabase link --ref ${ref}`,
+ description: `Sets the Supabase project to be associated with your project ${ref}`,
+ jsx: () => {
+ return (
+ <>
+ supabase link --ref {ref}
+ >
+ )
+ },
+ comment: 'Link this project',
+ },
+ {
+ command: 'supabase functions new hello',
+ description: ' creates a function stub at ./functions/hello.ts',
+ jsx: () => {
+ return (
+ <>
+ supabase functions new hello
+ >
+ )
+ },
+ comment: 'Create a function',
+ },
+ {
+ command: 'supabase functions deploy hello',
+ description: 'Deploys function at ./functions/hello.ts',
+ jsx: () => {
+ return (
+ <>
+ supabase functions deploy hello
+ >
+ )
+ },
+ comment: 'Deploy your function',
+ },
+ {
+ command: `curl -L -X POST 'https://${ref}.functions.supabase.co/hello' -H 'Authorization: Bearer [YOUR ANON KEY]'`,
+ description: 'Deploys function at ./functions/hello.ts',
+ jsx: () => {
+ return (
+ <>
+ curl -L -X POST 'https://{ref}
+ .functions.supabase.co/hello' -H 'Authorization: Bearer [YOUR ANON KEY]'
+ >
+ )
+ },
+ comment: 'Deploy your function',
+ },
+ ]
+ return (
+ <>
+
+
+
+ Scalable pay-as-you-go functions as a service (FaaS) to run your code with zero server
+ management.
+
+
+ No servers to provision, manage, or upgrade Automatically scale based on the load
+ Integrated monitoring, logging, and debugging capability Built-in security at role and
+ per function level based on the principle of least privilege Key networking capabilities
+ for hybrid and multi-cloud scenarios
+
),
+ LogsExplorerLayout: jest.fn().mockImplementation(({ children }) =>
{children}
),
}))
// mock mobx
@@ -17,7 +17,7 @@ jest.mock('next/router')
import { useRouter } from 'next/router'
const defaultRouterMock = () => {
const router = jest.fn()
- router.query = { ref: '123', type: 'auth' }
+ router.query = { ref: '123' }
router.push = jest.fn()
router.pathname = 'logs/path'
return router
@@ -40,67 +40,71 @@ jest.mock('components/ui/Flag/Flag')
import Flag from 'components/ui/Flag/Flag'
Flag.mockImplementation(({ children }) => <>{children}>)
jest.mock('hooks')
-import { useFlag } from 'hooks'
+import { useStore, useFlag } from 'hooks'
useFlag.mockReturnValue(true)
+useStore.mockImplementation(() => ({
+ content: jest.fn(),
+}))
import { SWRConfig } from 'swr'
-jest.mock('pages/project/[ref]/settings/logs/explorer')
-import { LogsExplorerPage } from 'pages/project/[ref]/settings/logs/explorer'
-LogsExplorerPage.mockImplementation((props) => {
- const Page = jest.requireActual('pages/project/[ref]/settings/logs/explorer').LogsExplorerPage
- // wrap with SWR to reset the cache each time
- return (
- new Map(),
- shouldRetryOnError: false,
- }}
- >
-
-
- )
-})
+import { LogsExplorerPage as Page } from 'pages/project/[ref]/logs-explorer/index'
+const LogsExplorerPage = (props) => (
+ new Map(),
+ shouldRetryOnError: false,
+ }}
+ >
+
+
+)
-import { render, fireEvent, waitFor, screen, act } from '@testing-library/react'
+import { render, fireEvent, waitFor, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
-import { getToggleByText } from '../../helpers'
-import { wait } from '@testing-library/user-event/dist/utils'
import { logDataFixture } from '../../fixtures'
+
beforeEach(() => {
// reset mocks between tests
get.mockReset()
useRouter.mockReset()
useRouter.mockReturnValue(defaultRouterMock())
})
-test('can display log data and metadata', async () => {
+test('can display log data', async () => {
get.mockResolvedValue({
result: [
logDataFixture({
- event_message: 'some event happened',
+ id: 'some-event-happened',
metadata: {
my_key: 'something_value',
},
}),
],
})
- render()
- fireEvent.click(await screen.findByText(/happened/))
- await screen.findByText(/my_key/)
+ const {container} = render()
+ let editor = container.querySelector('.monaco-editor')
+ await waitFor(() => {
+ editor = container.querySelector('.monaco-editor')
+ expect(editor).toBeTruthy()
+ })
+ // type new query
+ userEvent.type(editor, 'select \ncount(*) as my_count \nfrom edge_logs')
+
+ userEvent.click(await screen.findByText(/Run/))
+ const row = await screen.findByText("some-event-happened")
+ screen.debug()
+ userEvent.click(row)
await screen.findByText(/something_value/)
})
test('q= query param will populate the query input', async () => {
const router = defaultRouterMock()
- router.query = { ...router.query, type: 'api', q: 'some_query', s: 'someSearch' }
+ router.query = { ...router.query, type: 'api', q: 'some_query' }
useRouter.mockReturnValue(router)
render()
// should populate editor with the query param
await waitFor(() => {
expect(get).toHaveBeenCalledWith(expect.stringContaining('sql=some_query'))
})
-
- // query takes precedence of search queryparam
- expect(() => !screen.queryByDisplayValue(/someSearch/))
})
test('custom sql querying', async () => {
diff --git a/studio/tsconfig.json b/studio/tsconfig.json
index 379a3b4c863..71436a2fdd4 100644
--- a/studio/tsconfig.json
+++ b/studio/tsconfig.json
@@ -1,11 +1,7 @@
{
"compilerOptions": {
"target": "es5",
- "lib": [
- "dom",
- "dom.iterable",
- "esnext"
- ],
+ "lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
@@ -17,16 +13,9 @@
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
- "baseUrl": "."
+ "baseUrl": ".",
+ "downlevelIteration": true
},
- "include": [
- "next-env.d.ts",
- "**/*.ts",
- "**/*.tsx",
- "**/*.js",
- "**/*.jsx"
- ],
- "exclude": [
- "node_modules"
- ]
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx"],
+ "exclude": ["node_modules"]
}
diff --git a/studio/types/userContent.ts b/studio/types/userContent.ts
index 35c79fac7d3..1219ea809b3 100644
--- a/studio/types/userContent.ts
+++ b/studio/types/userContent.ts
@@ -2,9 +2,9 @@ export interface UserContent {
id?: string
name: string
description?: string
- type: 'sql' | 'report'
+ type: 'sql' | 'report' | 'log_sql'
visibility: 'user' | 'project' | 'org' | 'public'
- content: Dashboards.Content | SqlSnippets.Content
+ content: Dashboards.Content | SqlSnippets.Content | LogSqlSnippets.Content
owner_id?: number // user id
last_updated_by?: number // user id
inserted_at?: string // '2021-08-26T08:24:52.040695+00:00'
@@ -120,3 +120,25 @@ export namespace SqlSnippets {
favorite: boolean
}
}
+
+export namespace LogSqlSnippets {
+ /**
+ * To be stored in the database: public.user_content.content
+ * In this case there is only one thing to store, but it's good to
+ * nest it in an object for future expansion.
+ */
+ export interface Content {
+ // unique id of the sql snippet, possibly to used so snippets can support versioning
+ content_id: string
+
+ // A full SQL query - this will be hashed on the /content endpoint
+ sql: string
+
+ // we can add some versioning to this schema in case we need to change the format.
+ schema_version: string
+
+ // show sql snippet as a favorite.
+ // this could be problematic if sql snippets have visibility that is != 'user'
+ favorite: boolean
+ }
+}
diff --git a/web/docs/guides/api.mdx b/web/docs/guides/api.mdx
index a7fb8dfc992..8faedf6a8d1 100644
--- a/web/docs/guides/api.mdx
+++ b/web/docs/guides/api.mdx
@@ -13,18 +13,18 @@ Supabase generates three types of API directly from your database schema.
- REST - interact with your database through a restful interface.
- Realtime - listen to database changes.
-- GraphQL - [coming soon](https://supabase.com/blog/2021/12/03/pg-graphql).
+- GraphQL - [in beta](/blog/2021/12/03/pg-graphql).
The APIs are:
-- Instant and auto-generated: as you update your database the changes are immediately accessible through your API.
-- Self documenting: Supabase generates documentation in the Dashboard which updates as you make database changes.
-- Secure: the API is configured to work with PostgreSQL's Row Level Security, provisioned behind an API gateway with key-auth enabled.
-- Fast: our benchmarks for basic reads are more than 300% faster than Firebase. The API is a very thin layer on top of Postgres, which does most of the heavy lifting.
-- Scalable: the API can serve thousands of simultaneous requests, and works well for Serverless workloads.
+- **Instant and auto-generated.** As you update your database the changes are immediately accessible through your API.
+- **Self documenting.** Supabase generates documentation in the Dashboard which updates as you make database changes.
+- **Secure.** The API is configured to work with PostgreSQL's Row Level Security, provisioned behind an API gateway with key-auth enabled.
+- **Fast.** Our benchmarks for basic reads are more than 300% faster than Firebase. The API is a very thin layer on top of Postgres, which does most of the heavy lifting.
+- **Scalable.** The API can serve thousands of simultaneous requests, and works well for Serverless workloads.
-### RESTful API
+### REST API
Supabase provides a RESTful API using [PostgREST](https://postgrest.org/). This is a very thin API layer on top of Postgres.
It provides everything you need from a CRUD API:
@@ -45,20 +45,29 @@ It provides everything you need from a CRUD API:
allowFullScreen
>
+### GraphQL API
+
+:::note
+
+GraphQL is in Beta, and may have breaking changes. It is only available on self-hosted setups and Supabase projects created after 28th March 2022.
+
+:::
+
+GraphQL in Supabase works through [pg_graphql](/blog/2021/12/03/pg-graphql), an open source PostgreSQL extension for GraphQL.
+To get started with GraphQL you must enable the `pg_graphql` extension in your project.
+
+
+
### Realtime API
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.
-### GraphQL API
-
-[Coming soon](https://supabase.com/blog/2021/12/03/pg-graphql). We are developing `pg_graphql`, an open source PostgreSQL extension for GraphQL.
-`pg_graphql` inspects an existing PostgreSQL schema and reflects a GraphQL schema with resolvers. We will expose `pg_graphql` via the existing REST interface.
-
-
## Getting started
-After you have added tables or functions to your database, you can use the API.
+All APIs are auto-created from Database tables. After you have added tables or functions to your database, you can use the APIs provided.
### Creating API Routes
@@ -105,19 +114,10 @@ create table todos (
-
### API URL and Keys
Every Supabase project has a unique API URL. Your API is secured behind an API gateway which requires an API Key for every request.
-You can find the Keys inside the Dashboard.
-
-
-
```sh
1. Go to the "Settings" section.
@@ -130,23 +130,30 @@ values={[
-
-
+The REST API and the GraphQL API are both accessible through this URL:
+
+- REST: `https://.supabase.com/rest/v1`
+- GraphQL: `https://.supabase.com/rest/v1`
+
+Both of these routes require the `anon` key to be passed through an `apikey` header.
+
+#### API Keys
-#### Details and links:
+You can find the Keys inside the Dashboard in the same location as the URL above.
-You are provided with two keys initially:
+You are provided with two keys:
- an `anon` key, which is safe to be used in a browser context.
-- a `service_role` key, which should only be used on a server. This key can bypass Row Level Security.
+- a `service_role` key, which should only be used on a server. This key can bypass Row Level Security. NEVER use this key in a browser.
### Accessing the Docs
-Supabase generates documentation in the Dashboard which updates as you make database changes.
+#### REST API
-Let's view the documentation for the `todos` table which we created in the first step.
+Supabase generates documentation in the Dashboard which updates as you make database changes.
+Let's view the documentation for a `countries` table which we created in our database.
+
+
+
+#### GraphQL
-### Using the API
+The GraphQL Endpoint that we provide (`https://.supabase.com/rest/v1`) is compatible with any GraphiQL implementation that can pass an `apikey` header.
+Some suggested applications:
+
+- [paw.cloud](https://paw.cloud)
+- [insomnia.rest](https://insomnia.rest)
+- [postman.com/graphql](https://www.postman.com/graphql/)
+- Self-hosted GraphiQL: GraphiQL can be served through a simple HTML file. See [this discussion](https://github.com/supabase/supabase/discussions/6144) for more details.
+
+## Using the API
+
+
+### REST API
You can interact with your API directly via HTTP requests, or you can use the client libraries which we provide.
Let's see how to make a request to the `todos` table which we created in the first step,
-using the API URL (`[SUPABASE_URL]`) and Key (`[SUPABASE_ANON_KEY]`) we provided:
+using the API URL (`SUPABASE_URL`) and Key (`SUPABASE_ANON_KEY`) we provided:
/rest/v1/todos' \
+-H "apikey: " \
+-H "Authorization: Bearer "
```
-#### Details and links:
-
-- When you create a table in Postgres, Row Level Security is disabled by default. Make sure you secure it by [enabling RLS](/docs/guides/api#securing-your-routes).
-- Never expose the `service_role` key in a browser or anywhere where a user can see it.
-- JS Reference: [select()](/docs/reference/javascript/select),
+JS Reference: [select()](/docs/reference/javascript/select),
[insert()](/docs/reference/javascript/insert),
[update()](/docs/reference/javascript/update),
[upsert()](/docs/reference/javascript/upsert),
[delete()](/docs/reference/javascript/delete),
[rpc()](/docs/reference/javascript/rpc) (call Postgres functions).
-### Safeguards towards accidental deletes and updates
-For new projects, by default, the Postgres extension [safeupdate](https://github.com/eradman/pg-safeupdate) is enabled for all queries coming from the API.
-This ensures that any `delete()` or `update()` would fail if there are no accompanying filters provided.
-This can be disabled by running the following query on the SQL editor on the dashboard:
+### GraphQL API
-```sql
-alter role "authenticator"
-set "session_preload_libraries" to default;
+:::note
+
+While pg_graphql is in beta, we have disabled GraphQL auto-refreshing. If you want to refresh your GraphQL introspection, call `select graphql.rebuild_schema();` to rebuild your GraphQL schema.
+
+:::
+
+You can use any GraphQL client with the Supabase GraphQL API. For our GraphQL example we will use [urlql](https://formidable.com/open-source/urql/docs/).
+
+
+
+
+```javascript
+import { createClient, useQuery } from 'urql'
+
+// Prepare API key and Authorization header
+const headers = {
+ apikey: ,
+ authorization: `Bearer: ${
+}
+
+// Create GraphQL client
+// See: https://formidable.com/open-source/urql/docs/basics/react-preact/#setting-up-the-client
+const client = createClient({
+ url: '/grapqhl/v1',
+ fetchOptions: function createFetchOptions() {
+ return { headers }
+ },
+})
+
+// Prepare our GraphQL query
+const TodosQuery = `
+ query {
+ todos {
+ id
+ title
+ }
+ }
+`
+
+// Query for the data (React)
+const [result, reexecuteQuery] = useQuery({
+ query: TodosQuery,
+})
+
+// Read the result
+const { data, fetching, error } = result
```
-To reenable it :
-```sql
-alter role "authenticator"
-set "session_preload_libraries" = 'safeupdate';
+
+
+
+```bash
+# Append /grapqhl/v1/ to your URL, and then use the table name as the route
+curl --request POST '/grapqhl/v1' \
+-H 'apikey: ' \
+-H 'Authorization: Bearer ' \
+-d '{ "query":"{ todos(first: 3) { edges { node { id } } } }" }'
```
-The above can also be run to enable it for existing projects. Settings are applied immediately and as such no restarts are needed after running any of the two.
-### Managing Realtime
+
+
-The Realtime API works through PostgreSQL's replication functionality. Postgres sends database changes to a "publication"
-called `supabase_realtime`, and by managing this publication you can control which data is broadcast.
+### Realtime API
By default Realtime is disabled on your database. Let's turn on Realtime for the `todos` table.
+:::note
+
+Realtime only works for tables in the public schema.
+
+:::
+
-#### Details and links:
+Now we can listen to any new data that is inserted into the `todo` table:
-- Realtime only works for tables in the public schema.
-- [JS Reference](/docs/reference/javascript/subscribe): Subscribe to database changes using the realtime client
+
+
+
+```javascript
+// Initialize the JS client
+import { createClient } from '@supabase/supabase-js'
+const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY)
+
+// Create a function to handle inserts
+const handleInserts = (payload) => {
+ console.log('Change received!', payload)
+}
+
+// Listen to unserts
+const { data: todos, error } = await supabase
+ .from('todos')
+ .in('INSERT', handleUpdates)
+ .subscribe()
+```
+
+
+
+
+Use [subscribe()](/docs/reference/javascript/subscribe) to listen to database changes.
+The Realtime API works through PostgreSQL's replication functionality. Postgres sends database changes to a [publication](/docs/guides/database/replication#publications)
+called `supabase_realtime`, and by managing this publication you can control which data is broadcast.
+
+## API Security
### Securing your Routes
+
+Your API is designed to work with Postgres Row Level Security. If you use Supabase [Auth](/docs/guides/auth), you can restrict data based on the logged-in user.
+To control access to your data, you can use [Policies](/docs/guides/auth#policies).
+When you create a table in Postgres, Row Level Security is disabled by default. Make sure you secure it by [enabling RLS](/docs/guides/api#securing-your-routes).
+
+### The `service_role` key
-#### Details and links:
-- Your API is designed to work with Postgres Row Level Security. If you use Supabase [Auth](/docs/guides/auth), you can restrict data based on the logged-in user.
-- To control access to your data, you can use [Policies](/docs/guides/auth#policies).
+Never expose the `service_role` key in a browser or anywhere where a user can see it. This Key can is designed to bypass Row Level Security - so it should only be used on a private server.
+
+We have [partnered with GitHub](/blog/2022/03/28/community-day#supabase-is-now-a-github-secret-scanning-partner) to scan for Supabase `service_role` keys pushed to public repositories.
+If they detect any keys with service_role privileges being pushed to GitHub, they will forward the API key to us, so that we can automatically revoke the detected secrets and notify you, protecting your data against malicious actors.
+
+### Safeguards towards accidental deletes and updates
+
+For new projects, by default, the Postgres extension [safeupdate](https://github.com/eradman/pg-safeupdate) is enabled for all queries coming from the API.
+This ensures that any `delete()` or `update()` would fail if there are no accompanying filters provided.
+This can be disabled by running the following query on the SQL editor on the dashboard:
+
+```sql
+alter role "authenticator"
+set "session_preload_libraries" to default;
+```
+
+To reenable it :
+```sql
+alter role "authenticator"
+set "session_preload_libraries" = 'safeupdate';
+```
+The above can also be run to enable it for existing projects. Settings are applied immediately and as such no restarts are needed after running any of the two.
+
diff --git a/web/docusaurus.config.js b/web/docusaurus.config.js
index 422937a2783..778739c1d1d 100755
--- a/web/docusaurus.config.js
+++ b/web/docusaurus.config.js
@@ -40,8 +40,8 @@ module.exports = {
},
},
algolia: {
- apiKey: '766d56f13dd1e82f43253559b7c86636',
- appId: 'supabase',
+ appId: 'W4BIZ4FKU9',
+ apiKey: 'ac408c5c0a323ee4d7952cee149d1474',
indexName: 'supabase',
},
image: '/img/supabase-og-image.png', // used for meta tag, in particular og:image and twitter:image
diff --git a/web/static/lawyers.txt b/web/static/lawyers.txt
index e248d52b8b7..4aa599ea4d1 100644
--- a/web/static/lawyers.txt
+++ b/web/static/lawyers.txt
@@ -9,7 +9,9 @@ Supabase™ is a trademark of Supabase Inc.
If you're a creator/contributor to one of these packages, thanks!
-Last updated: 2022-03-24
+Last updated: 2022-03-29
+
+JavaScript/TypeScript
-- ------------------------------------ ---------------------- -------------------------------------------------------------------- --------------------------------------------------------------------------------------- -------------------------
0 lodash@4.17.21 MIT https://github.com/lodash/lodash https://github.com/lodash/lodash/raw/master/LICENSE @supabase/ui
@@ -110,3 +112,298 @@ Last updated: 2022-03-24
95 stripe@8.145.0 MIT https://github.com/stripe/stripe-node https://github.com/stripe/stripe-node/raw/master/LICENSE stripe-sync-engine
96 yesql@5.0.0 ISC https://github.com/pihvi/yesql https://github.com/pihvi/yesql stripe-sync-engine
-- ------------------------------------ ---------------------- -------------------------------------------------------------------- --------------------------------------------------------------------------------------- -------------------------
+
+
+Elixir
+
+Id Name Version License
+-- --------------------------------- ------- ----------
+ 0 castore 0.1.11 Apache 2.0
+ 1 certifi 2.5.3 BSD
+ 2 combine 0.10.0 MIT
+ 3 connection 1.1.0 Apache 2.0
+ 4 cowboy 2.8.0 ISC
+ 5 cowboy_telemetry 0.3.1 Apache 2.0
+ 6 cowlib 2.9.1 ISC
+ 7 db_connection 2.4.1 Apache 2.0
+ 8 decimal 2.0.0 Apache 2.0
+ 9 ecto 3.7.1 Apache 2.0
+10 ecto_sql 3.7.1 Apache 2.0
+11 epgsql 4.6.0 BSD
+12 file_system 0.2.10 WTFPL
+13 finch 0.7.0 MIT
+14 gettext 0.18.2 Apache 2.0
+15 hackney 1.17.0 Apache 2.0
+16 httpoison 1.8.0 MIT
+17 idna 6.1.1 MIT
+18 jason 1.2.2 Apache 2.0
+19 joken 2.3.0 Apache 2.0
+20 jose 1.11.1 MIT
+21 metrics 1.0.1 BSD
+22 mime 1.5.0 Apache 2.0
+23 mimerl 1.2.0 MIT
+24 mint 1.3.0 Apache 2.0
+25 nimble_options 0.3.5 Apache 2.0
+26 nimble_pool 0.2.4 Apache 2.0
+27 parse_trans 3.3.1 Apache 2.0
+28 phoenix 1.5.8 MIT
+29 phoenix_html 2.14.3 MIT
+30 phoenix_live_reload 1.3.0 MIT
+31 phoenix_pubsub 2.0.0 MIT
+32 plug 1.11.0 Apache 2.0
+33 plug_cowboy 2.4.1 Apache 2.0
+34 plug_crypto 1.2.1 Apache 2.0
+35 postgrex 0.15.13 Apache 2.0
+36 prom_ex 1.3.0 MIT
+37 ranch 1.7.1 ISC
+38 retry 0.14.1 Apache 2.0
+39 ssl_verify_fun 1.1.6 MIT
+40 telemetry 0.4.2 Apache 2.0
+41 telemetry_metrics 0.6.1 Apache 2.0
+42 telemetry_metrics_prometheus_core 1.0.1 Apache 2.0
+43 telemetry_poller 0.5.1 Apache 2.0
+44 timex 3.6.3 MIT
+45 tzdata 1.0.5 MIT
+46 unicode_util_compat 0.7.0 Apache 2.0
+47 bunt 0.2.0 MIT
+48 credo 1.5.5 MIT
+49 dialyxir 1.1.0 Apache 2.0
+50 earmark_parser 1.4.12 Apache 2.0
+51 erlex 0.2.6 Apache 2.0
+52 ex_doc 0.24.1 Apache 2.0
+53 file_system 0.2.10 WTFPL
+54 jason 1.2.2 Apache 2.0
+55 makeup 1.0.5 BSD
+56 makeup_elixir 0.15.1 BSD
+57 makeup_erlang 0.1.1 BSD
+58 nimble_parsec 1.1.0 Apache 2.0
+59 warpath 0.6.0 MIT
+-- --------------------------------- ------- ----------
+
+Go
+
+ID Package Link Version
+--- ----------------------------------------------------------- -------------------------------------
+License Type
+------------------------------------------------------
+ 0 github.com/BurntSushi/toml v1.0.0 MIT
+ 1 github.com/adrg/xdg v0.4.0 MIT
+ 2 github.com/alecthomas/chroma v0.10.0 MIT
+ 3 github.com/aymerick/douceur v0.2.0 MIT
+ 4 github.com/charmbracelet/bubbles v0.10.3 MIT
+ 5 github.com/charmbracelet/bubbletea v0.20.0 MIT
+ 6 github.com/charmbracelet/glamour v0.5.0 MIT
+ 7 github.com/charmbracelet/harmonica v0.1.0 MIT
+ 8 github.com/charmbracelet/lipgloss v0.5.0 MIT
+ 9 github.com/containerd/console v1.0.3 Apache 2.0
+ 10 github.com/containerd/containerd v1.6.2 Apache 2.0
+ 11 github.com/dlclark/regexp2 v1.4.0 MIT
+ 12 github.com/docker/distribution v2.8.1 Apache 2.0
+ 13 github.com/docker/docker v20.10.14 Apache 2.0,MIT
+ 14 github.com/docker/go-connections v0.4.0 Apache 2.0
+ 15 github.com/docker/go-units v0.4.0 Apache 2.0
+ 16 github.com/fsnotify/fsnotify v1.5.1 New BSD
+ 17 github.com/gogo/protobuf v1.3.2 New BSD
+ 18 github.com/golang/protobuf v1.5.2 New BSD
+ 19 github.com/gorilla/css v1.0.0 New BSD
+ 20 github.com/hashicorp/hcl v1.0.0 Mozilla Public License 2.0
+ 21 github.com/jackc/chunkreader/v2 v2.0.1 MIT
+ 22 github.com/jackc/pgconn v1.11.0 MIT
+ 23 github.com/jackc/pgio v1.0.0 MIT
+ 24 github.com/jackc/pgpassfile v1.0.0 MIT
+ 25 github.com/jackc/pgproto3/v2 v2.2.0 MIT
+ 26 github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b MIT
+ 27 github.com/jackc/pgtype v1.10.0 MIT
+ 28 github.com/jackc/pgx/v4 v4.15.0 MIT
+ 29 github.com/joho/godotenv v1.4.0 MIT
+ 30 github.com/lucasb-eyer/go-colorful v1.2.0 MIT
+ 31 github.com/magiconair/properties v1.8.6 Simplified BSD
+ 32 github.com/mattn/go-isatty v0.0.14 MIT
+ 33 github.com/mattn/go-runewidth v0.0.13 MIT
+ 34 github.com/microcosm-cc/bluemonday v1.0.18 New BSD
+ 35 github.com/mitchellh/mapstructure v1.4.3 MIT
+ 36 github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 Apache 2.0
+ 37 github.com/morikuni/aec v1.0.0 MIT
+ 38 github.com/muesli/ansi v0.0.0-20211031195517-c9f0611b6c70 MIT
+ 39 github.com/muesli/reflow v0.3.0 MIT
+ 40 github.com/muesli/termenv v0.11.1-0.20220212125758-44cd13922739 MIT
+ 41 github.com/olekukonko/tablewriter v0.0.5 MIT
+ 42 github.com/opencontainers/go-digest v1.0.0 Apache 2.0
+ 43 github.com/opencontainers/image-spec v1.0.2 Apache 2.0
+ 44 github.com/pelletier/go-toml v1.9.4 Apache 2.0
+ 45 github.com/pkg/errors v0.9.1 Simplified BSD
+ 46 github.com/rivo/uniseg v0.2.0 MIT
+ 47 github.com/sirupsen/logrus v1.8.1 MIT
+ 48 github.com/spf13/afero v1.8.2 Apache 2.0
+ 49 github.com/spf13/cast v1.4.1 MIT
+ 50 github.com/spf13/cobra v1.4.0 Apache 2.0
+ 51 github.com/spf13/jwalterweatherman v1.1.0 MIT
+ 52 github.com/spf13/pflag v1.0.5 New BSD
+ 53 github.com/spf13/viper v1.10.1 MIT
+ 54 github.com/subosito/gotenv v1.2.0 MIT
+ 55 github.com/withfig/autocomplete-tools/packages/cobra v1.1.3 MIT
+ 56 github.com/yuin/goldmark v1.4.11 MIT
+ 57 github.com/yuin/goldmark-emoji v1.0.1 MIT
+ 58 golang.org/x/crypto v0.0.0-20220321153916-2c7772ba3064 New BSD
+ 59 golang.org/x/net v0.0.0-20220225172249-27dd8689420f New BSD
+ 60 golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8 New BSD
+ 61 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 New BSD
+ 62 golang.org/x/text v0.3.7 New BSD
+ 63 google.golang.org/genproto v0.0.0-20220323144105-ec3c684e5b14 Apache 2.0
+ 64 google.golang.org/grpc v1.45.0 Apache 2.0
+ 65 google.golang.org/protobuf v1.28.0 New BSD
+ 66 gopkg.in/ini.v1 v1.66.4 Apache 2.0
+ 67 gopkg.in/yaml.v2 v2.4.0 Apache 2.0,MIT
+ 68 github.com/aws/aws-sdk-go-v2 v1.8.0 Apache 2.0,New BSD
+ 69 github.com/aws/aws-sdk-go-v2/config v1.6.0 Apache 2.0
+ 70 github.com/aws/aws-sdk-go-v2/credentials v1.3.2 Apache 2.0
+ 71 github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.4.0 Apache 2.0
+ 72 github.com/aws/aws-sdk-go-v2/internal/ini v1.2.0 Apache 2.0
+ 73 github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.2.2 Apache 2.0
+ 74 github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.5.0 Apache 2.0
+ 75 github.com/aws/aws-sdk-go-v2/service/sso v1.3.2 Apache 2.0
+ 76 github.com/aws/aws-sdk-go-v2/service/sts v1.6.1 Apache 2.0
+ 77 github.com/aws/smithy-go v1.7.0 Apache 2.0
+ 78 github.com/coreos/go-semver v0.3.0 Apache 2.0
+ 79 github.com/coreos/go-systemd/v22 v22.3.2 Apache 2.0
+ 80 github.com/fsnotify/fsnotify v1.4.9 New BSD
+ 81 github.com/gogo/protobuf v1.3.2 New BSD
+ 82 github.com/golang/protobuf v1.5.2 New BSD
+ 83 github.com/hashicorp/hcl v1.0.0 Mozilla Public License 2.0
+ 84 github.com/magiconair/properties v1.8.5 Simplified BSD
+ 85 github.com/mitchellh/mapstructure v1.4.1 MIT
+ 86 github.com/pelletier/go-toml v1.9.3 Apache 2.0
+ 87 github.com/pkg/errors v0.9.1 Simplified BSD
+ 88 github.com/spf13/afero v1.6.0 Apache 2.0
+ 89 github.com/spf13/cast v1.3.1 MIT
+ 90 github.com/spf13/cobra v1.2.1 Apache 2.0,GPLv2,GPLv3,LGPL,MIT,New BSD,Simplified BSD
+ 91 github.com/spf13/jwalterweatherman v1.1.0 MIT
+ 92 github.com/spf13/pflag v1.0.5 New BSD
+ 93 github.com/spf13/viper v1.8.1 MIT
+ 94 github.com/subosito/gotenv v1.2.0 MIT
+ 95 go.etcd.io/etcd/api/v3 v3.5.0 Apache 2.0
+ 96 go.etcd.io/etcd/client/pkg/v3 v3.5.0 Apache 2.0
+ 97 go.etcd.io/etcd/client/v3 v3.5.0 Apache 2.0
+ 98 go.uber.org/atomic v1.9.0 MIT
+ 99 go.uber.org/multierr v1.7.0 MIT
+100 go.uber.org/zap v1.19.0 MIT
+101 golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 New BSD
+102 golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40 New BSD
+103 golang.org/x/text v0.3.5 New BSD
+104 google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c Apache 2.0
+105 google.golang.org/grpc v1.38.0 Apache 2.0
+106 google.golang.org/protobuf v1.26.0 New BSD
+107 gopkg.in/ini.v1 v1.62.0 Apache 2.0
+108 gopkg.in/yaml.v2 v2.4.0 Apache 2.0,MIT
+109 github.com/coreos/go-oidc v2.2.1 Apache 2.0
+110 github.com/kelseyhightower/envconfig v1.4.0 MIT
+111 github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 Apache 2.0
+112 golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899 New BSD
+113 golang.org/x/net v0.0.0-20200707034311-ab3426394381 New BSD
+114 golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d New BSD
+115 gopkg.in/square/go-jose.v2 v2.5.1 Apache 2.0,New BSD
+116 cloud.google.com/go v0.67.0 Apache 2.0,New BSD
+117 github.com/GoogleCloudPlatform/cloudsql-proxy v0.0.0-20170623214735-571947b0f240 Apache 2.0
+118 github.com/Masterminds/semver/v3 v3.1.1 MIT
+119 github.com/aymerick/douceur v0.2.0 MIT
+120 github.com/badoux/checkmail v0.0.0-20170203135005-d0a759655d62 MIT
+121 github.com/beevik/etree v1.1.0 Simplified BSD
+122 github.com/coreos/go-oidc/v3 v3.0.0 Apache 2.0
+123 github.com/didip/tollbooth/v5 v5.1.1 MIT
+124 github.com/fatih/color v1.10.0 MIT
+125 github.com/fatih/structs v1.1.0 MIT
+126 github.com/go-chi/chi v4.0.2 MIT
+127 github.com/go-sql-driver/mysql v1.5.0 Mozilla Public License 2.0
+128 github.com/gobuffalo/envy v1.9.0 MIT
+129 github.com/gobuffalo/fizz v1.13.0 MIT
+130 github.com/gobuffalo/flect v0.2.2 MIT
+131 github.com/gobuffalo/github_flavored_markdown v1.1.0 MIT,Simplified BSD
+132 github.com/gobuffalo/helpers v0.6.1 MIT
+133 github.com/gobuffalo/nulls v0.4.0 MIT
+134 github.com/gobuffalo/packd v1.0.0 MIT
+135 github.com/gobuffalo/plush/v4 v4.1.0 MIT
+136 github.com/gobuffalo/pop/v5 v5.3.3 MIT
+137 github.com/gobuffalo/tags/v3 v3.1.0 MIT
+138 github.com/gobuffalo/validate/v3 v3.3.0 MIT
+139 github.com/gofrs/uuid v4.0.0 MIT
+140 github.com/golang-jwt/jwt v3.2.1 MIT
+141 github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e Apache 2.0
+142 github.com/golang/protobuf v1.4.2 New BSD
+143 github.com/googleapis/gax-go/v2 v2.0.5 New BSD
+144 github.com/gorilla/context v1.1.1 New BSD
+145 github.com/gorilla/css v1.0.0 New BSD
+146 github.com/gorilla/securecookie v1.1.1 New BSD
+147 github.com/gorilla/sessions v1.1.1 New BSD
+148 github.com/imdario/mergo v0.0.0-20160216103600-3e95a51e0639 New BSD
+149 github.com/jackc/chunkreader/v2 v2.0.1 MIT
+150 github.com/jackc/pgconn v1.8.0 MIT
+151 github.com/jackc/pgio v1.0.0 MIT
+152 github.com/jackc/pgpassfile v1.0.0 MIT
+153 github.com/jackc/pgproto3/v2 v2.0.7 MIT
+154 github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b MIT
+155 github.com/jackc/pgtype v1.6.2 MIT
+156 github.com/jackc/pgx/v4 v4.10.1 MIT
+157 github.com/jmoiron/sqlx v1.3.1 MIT
+158 github.com/joho/godotenv v1.3.0 MIT
+159 github.com/jonboulle/clockwork v0.2.2 Apache 2.0
+160 github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 MIT
+161 github.com/kelseyhightower/envconfig v1.4.0 MIT
+162 github.com/lestrrat-go/jwx v0.9.0 MIT
+163 github.com/luna-duclos/instrumentedsql v1.1.3 MIT
+164 github.com/mattermost/xml-roundtrip-validator v0.1.0 Apache 2.0
+165 github.com/mattn/go-colorable v0.1.8 MIT
+166 github.com/mattn/go-isatty v0.0.12 MIT
+167 github.com/microcosm-cc/bluemonday v1.0.16 New BSD
+168 github.com/mitchellh/mapstructure v1.1.2 MIT
+169 github.com/mrjones/oauth v0.0.0-20190623134757-126b35219450 MIT
+170 github.com/netlify/mailme v1.1.1 MIT
+171 github.com/netlify/netlify-commons v0.32.0 MIT
+172 github.com/opentracing/opentracing-go v1.1.0 Apache 2.0
+173 github.com/patrickmn/go-cache v2.1.0 MIT
+174 github.com/philhofer/fwd v1.0.0 MIT
+175 github.com/pkg/errors v0.9.1 Simplified BSD
+176 github.com/rogpeppe/go-internal v1.8.0 New BSD
+177 github.com/rs/cors v1.6.0 MIT
+178 github.com/russellhaering/gosaml2 v0.6.1-0.20210916051624-757d23f1bc28 Apache 2.0
+179 github.com/russellhaering/goxmldsig v1.1.1 Apache 2.0
+180 github.com/sebest/xff v0.0.0-20160910043805-6c115e0ffa35 MIT
+181 github.com/sergi/go-diff v1.1.0 Apache 2.0,MIT
+182 github.com/sethvargo/go-password v0.2.0 MIT
+183 github.com/sirupsen/logrus v1.7.0 MIT
+184 github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d New BSD
+185 github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e New BSD
+186 github.com/spf13/cobra v1.1.3 Apache 2.0,GPLv2,GPLv3,LGPL,MIT,New BSD,Simplified BSD
+187 github.com/spf13/pflag v1.0.5 New BSD
+188 github.com/tinylib/msgp v1.1.0 MIT
+189 go.opencensus.io v0.22.4 Apache 2.0
+190 golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad New BSD
+191 golang.org/x/net v0.0.0-20220121210141-e204ce36a2ba New BSD
+192 golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43 New BSD
+193 golang.org/x/sync v0.0.0-20201207232520-09787c993a3a New BSD
+194 golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e New BSD
+195 golang.org/x/text v0.3.7 New BSD
+196 golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1 New BSD
+197 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 New BSD
+198 google.golang.org/api v0.32.0 New BSD
+199 google.golang.org/genproto v0.0.0-20200929141702-51c3e5b607fe Apache 2.0
+200 google.golang.org/grpc v1.32.0 Apache 2.0
+201 google.golang.org/protobuf v1.25.0 New BSD
+202 gopkg.in/DataDog/dd-trace-go.v1 v1.12.1 New BSD
+203 gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df MIT
+204 gopkg.in/square/go-jose.v2 v2.5.1 Apache 2.0,New BSD
+205 gopkg.in/yaml.v2 v2.4.0 Apache 2.0,MIT
+206 github.com/aws/aws-sdk-go v1.36.20 Apache 2.0,New BSD
+207 github.com/beorn7/perks v1.0.1 MIT
+208 github.com/cespare/xxhash/v2 v2.1.1 MIT
+209 github.com/golang/protobuf v1.4.3 New BSD
+210 github.com/jmespath/go-jmespath v0.4.0 Apache 2.0
+211 github.com/matttproud/golang_protobuf_extensions v1.0.1 Apache 2.0
+212 github.com/prometheus/client_golang v1.9.0 Apache 2.0
+213 github.com/prometheus/client_model v0.2.0 Apache 2.0
+214 github.com/prometheus/common v0.15.0 Apache 2.0,New BSD
+215 github.com/prometheus/procfs v0.2.0 Apache 2.0
+216 github.com/sirupsen/logrus v1.6.0 MIT
+217 golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e New BSD
+218 google.golang.org/protobuf v1.23.0 New BSD
+219 gopkg.in/yaml.v2 v2.3.0 Apache 2.0,MIT
+--- ----------------------------------------------------------- ------------------------------------- ------------------------------------------------------
diff --git a/web/static/videos/api/api-docs.mp4 b/web/static/videos/api/api-docs.mp4
new file mode 100644
index 00000000000..7fe41d76a17
Binary files /dev/null and b/web/static/videos/api/api-docs.mp4 differ
diff --git a/web/static/videos/api/api-enable-graphql.mp4 b/web/static/videos/api/api-enable-graphql.mp4
new file mode 100644
index 00000000000..f563d278f21
Binary files /dev/null and b/web/static/videos/api/api-enable-graphql.mp4 differ
diff --git a/www/_blog/2022-03-25-supabase-launch-week-four.mdx b/www/_blog/2022-03-25-supabase-launch-week-four.mdx
index 89db9bd88f9..b8cd220c35f 100644
--- a/www/_blog/2022-03-25-supabase-launch-week-four.mdx
+++ b/www/_blog/2022-03-25-supabase-launch-week-four.mdx
@@ -72,8 +72,10 @@ Monday 28 March 2022: 9am PT
### What?
-If Postgres could talk it would sing “I am the [WALRUS](https://supabase.com/blog/2021/09/10/supabase-beta-august-2021#realtime-security-codename-walrus)”.
-Since last Launch Week we’ve been busy shipping. Tune in on Tuesday to learn about a brand new way to fetch your data.
+~If Postgres could talk it would sing “I am the [WALRUS](https://supabase.com/blog/2021/09/10/supabase-beta-august-2021#realtime-security-codename-walrus)”.~
+~Since last Launch Week we've been busy shipping. Tune in on Tuesday to learn about a brand new way to fetch your data.~
+
+[GraphQL is now available in Supabase!](/blog/2022/03/29/graphql-now-available)
### When?
@@ -81,8 +83,9 @@ Tuesday 29 March 2022: 9am PT
### Where?
-Blog post coming soon. Follow our [Twitter](https://twitter.com/supabase) to get notified immediately,
-and set a reminder for our [YouTube live stream](https://www.youtube.com/watch?v=fApxu_U_hdw).
+- Read the [blog post](/blog/2022/03/29/graphql-now-available).
+- Tune in live on [Twitter Spaces](https://twitter.com/i/spaces/1dRKZlAQPaVJB).
+- Watch live on [YouTube](https://youtu.be/fApxu_U_hdw).
## Wednesday: Something for the Enterprise
@@ -107,7 +110,7 @@ Blog post coming soon. Follow our [Twitter](https://twitter.com/supabase) to get
### What?
-This one’s gonna be hotter than the Human Torch 🔥, more scalable than Mister Fantastic, more rock solid than The Thing,
+This one's gonna be hotter than the Human Torch 🔥, more scalable than Mister Fantastic, more rock solid than The Thing,
and the latency will be harder to find than Invisible Woman.
### When?
diff --git a/www/_blog/2022-03-29-graphql-now-available.mdx b/www/_blog/2022-03-29-graphql-now-available.mdx
new file mode 100644
index 00000000000..dc2e53fa8ff
--- /dev/null
+++ b/www/_blog/2022-03-29-graphql-now-available.mdx
@@ -0,0 +1,324 @@
+---
+title: 'GraphQL is now available in Supabase'
+description: GraphQL support is now in general availability on the Supabase platform via our open source PostgreSQL extension, pg_graphql (beta).
+author: oli_rice,dthyresson
+image: launch-week-4/tuesday-graphql/graphql-thumb-og.png
+thumb: launch-week-4/tuesday-graphql/graphql-thumb.png
+tags:
+ - launch-week
+ - graphql
+date: '2022-03-29'
+toc_depth: 3
+---
+
+GraphQL support is now in general availability on the Supabase platform via our [open source](https://github.com/supabase/pg_graphql/) PostgreSQL extension,
+[`pg_graphql](https://supabase.github.io/pg_graphql/) (beta)`.
+
+
+
+`pg_graphql` enables you to query existing PostgreSQL databases using GraphQL, either from within SQL or over HTTP:
+
+From SQL:
+
+```sql
+select graphql.resolve($$
+ {
+ accountCollection(first: 1) {
+ edges {
+ node {
+ id
+ firstName
+ address {
+ countryCode
+ }
+ }
+ }
+ }
+ }
+$$);
+```
+
+or over HTTP:
+
+```bash
+curl -X POST https://.supabase.co/graphql/v1 \
+ -H 'apiKey: '\
+ -H 'Content-Type: application/json' \
+ --data-raw '
+ {
+ "query":"{ accountCollection(first: 3) { edges { node { id } } } }"
+ }'
+```
+
+## Schema Reflection
+
+GraphQL types and fields are reflected from the SQL schema:
+
+- Tables become types
+- Columns become fields
+- Foreign keys become relations
+
+For example:
+
+```sql
+create table "Account"(
+ "id" serial primary key,
+ "email" varchar(255) not null,
+ "createdAt" timestamp not null,
+ "updatedAt" timestamp not null
+);
+
+-- Rebuild the GraphQL Schema Cache
+select graphql.rebuild_schema();
+```
+
+Translates to the GraphQL base type
+
+```graphql
+type Account {
+ id: Int!
+ email: String!
+ createdAt: DateTime!
+ updatedAt: DateTime!
+}
+```
+
+And exposes bulk CRUD operations on the `Query` and `Mutation` types, complete with relay style keyset pagination, filters, and ordering and (optional) name inflection.
+
+```graphql
+type Query {
+ accountCollection(
+ first: Int
+ last: Int
+ before: Cursor
+ after: Cursor
+ filter: AccountFilter
+ orderBy: [AccountOrderBy!]
+ ): AccountConnection
+}
+
+type Mutation {
+ insertIntoAccountCollection(
+ objects: [AccountInsertInput!]!
+ ): AccountInsertResponse
+
+ updateAccountCollection(
+ set: AccountUpdateInput!
+ filter: AccountFilter
+ atMost: Int! = 1
+ ): AccountUpdateResponse!
+
+ deleteFromAccountCollection(
+ filter: AccountFilter
+ atMost: Int! = 1
+ ): AccountDeleteResponse!
+```
+
+For a complete example with relationships, check out the [reflection docs](https://supabase.github.io/pg_graphql/reflection/).
+
+## Security
+
+An advantage to embedding GraphQL directly in the database is that we can lean on PostgreSQL's built-in primitives for authentication and authorization.
+
+### Authentication
+
+The GraphQL types exposed by `pg_graphql` are filtered according to the SQL role's [INSERT/UPDATE/DELETE permissions](https://www.postgresql.org/docs/current/sql-grant.html).
+At Supabase, each API request is resolved in the database using the role in the request's JWT.
+
+Anonymous users receive the `anon` role, and logged in users get the `authenticated` role. In either case, pg_graphql resolves requests according to the SQL permissions.
+The [introspection schema](https://graphql.org/learn/introspection/) is similarly filtered to limit exposed types and fields to those that the user has permission to access.
+That means we can serve multiple GraphQL schemas for users of differing privilege levels from a single endpoint!
+
+### Authorization
+
+Another nice side effect of making PostgreSQL do the heavy lifting is that GraphQL queries respect your existing
+[row level security policies](https://www.postgresql.org/docs/current/ddl-rowsecurity.html) right out-of-the-box. No additional configuration required.
+
+## Performance
+
+Each [free tier database](https://supabase.com/pricing) on the Supabase platform runs on a dedicated AWS t4g.micro instance with 2 vCPUs and 1 GB of memory.
+To squeeze the most out of that limited hardware we had to make a few significant optimizations:
+
+**GraphQL queries are always transpiled into exactly one SQL query**
+
+The SQL queries select and aggregate requested data into the shape of the GraphQL JSON response.
+In addition to solving the [N+1 query problem](https://medium.com/the-marcy-lab-school/what-is-the-n-1-problem-in-graphql-dd4921cb3c1a), a common issue with GraphQL resolvers,
+GraphQL queries requiring multiple joins typically produce significantly less IO due to reduced data duplication.
+
+For example, when selecting all comments for a blog post:
+
+```sql
+select
+ blog_posts.title,
+ comments.body as comment_body
+from
+ blog_posts
+join
+ comments on blog_posts.id = comments.blog_post_id
+```
+
+a SQL response would duplicate all data from the `blog_posts` table (title).
+
+```markdown
+| title | comment_body |
+| ---------- | ------------------------------ |
+| F1sRt P0$T | this guy gets it! |
+| F1sRt P0$T | you should re-write it in rust |
+| F1sRt P0$T | 10% off daily vitamin http:... |
+```
+
+Compared to the equivalent GraphQL response.
+
+```json
+{
+ "blogPostCollection": {
+ "edges": {
+ "node":
+ "title": "F1sRt P0$T"
+ "commentCollection": {
+ "edges": [
+ "node": {
+ "body": "this guy gets it!"
+ },
+ "node": {
+ "body": "you should re-write it in rust"
+ },
+ "node": {
+ "body": "10% off daily vitamin http:..."
+ }
+ ]
+ }
+ }
+ }
+ }
+}
+```
+
+Which has no duplication of data.
+
+The difference in payload size is negligible in this case, but as the number of 1-to-many joins grows, data duplication in the SQL response grows geometrically.
+
+**Queries are cached as [prepared statements](https://www.postgresql.org/docs/current/sql-prepare.html)**
+
+After a GraphQL query is transpiled to SQL, it is added to the prepared statement cache so subsequent requests with the same structure (think pagination) can skip the transpilation step.
+
+Using prepared statements also allows PostgreSQL to skip the overhead of computing a query plan. For small, on-index, queries,
+the query planning step can take several times as long as the query's execution time, so the saving is significant at scale.
+
+**All operations are bulk**
+
+Finally, all reflected query and mutation fields support bulk operations to nudge users towards consuming the API efficiently.
+Batching similar operations reduces network round-trips and time spent in the database.
+
+**Result**
+
+As a result of these optimizations, the throughput of a “hello world” equivalent query on Supabase free-tier hardware is:
+
+- 377.4 requests/second through the API (mean)
+- 656.2 queries/second through SQL (single connection, mean)
+
+## Getting Started
+
+
+
+To enable GraphQL in your Supabase instance, enable `pg_graphql` from the dashboard.
+
+
+
+Or create the extension in your database
+
+```sql
+create extension pg_graphql;
+```
+
+And we're done!
+
+The GraphQL endpoint is available at: `https://.supabase.co/graphql/v1`
+
+## Example app: Build a HN clone with Postgres and GraphQL
+
+
+
+We're excited to have worked with [The Guild](https://www.the-guild.dev) to show you [how to use](https://supabase-graphql-example.vercel.app/about) `pg_graphql`
+and their tools to build a [HackerNews clone](https://supabase-graphql-example.vercel.app/).
+
+The [demo application](https://supabase-graphql-example.vercel.app/) showcases:
+
+- **CRUD (Query + Mutation Operations).**
+ Data is fetched from the GraphQL layer auto-generated via `pg_graphql`.
+- **Cursor Based Pagination.**
+ `pg_graphql` generates standardized pagination types and fields as defined by the GraphQL Cursor Connections Specification.
+- **Authorization / RLS.**
+ GraphQL requests made include Supabase authorization headers so that Row Level Security on the Postgres layer ensures that viewers can only access what they are allowed to — and authenticated users can only update what they should.
+- **Code generation.**
+ Introspect your GraphQL schema and operations to generates the types for full backend to frontend type-safety.
+- **Postgres Triggers and Functions.**
+ Recalculate the feed scoring each time someone votes.
+- **Supabase UI.**
+ Use Auth widget straight out the box to handle logins and access tokens.
+
+
+
+Now instead of using the Supabase PostgREST API to query your database ...
+
+```jsx
+// using Supabase PostgREST
+
+const { data, error } = await supabase
+ .from('profile')
+ .select('id, username, bio, avatarUrl, website')
+```
+
+... all data fetching and updates are done using the same GraphQL operations you know and love! 🤯
+
+```
+// using GraphQL
+
+query ProfilesQuery {
+ profileCollection {
+ edges {
+ node {
+ id
+ username
+ bio
+ avatarUrl
+ website
+ }
+ }
+ }
+}
+```
+
+🎁 Get the code on GitHub here: [github.com/supabase-community/supabase-graphql-example](https://github.com/supabase-community/supabase-graphql-example)
+
+## Supabase + The Guild
+
+
+
+This is just the start of what we hope to be a close collaboration with the Guild, whose expertise of the GraphQL ecosystem will guide the development of Supabase's GraphQL features.
+The Guild and Supabase share a similar approach to open source - we both favor collaboration and composability, making collaboration easy and productive.
+
+Be sure to visit [The Guild](https://www.the-guild.dev) and [follow them](https://twitter.com/TheGuildDev) to stay informed of the latest developments in GraphQL.
+
+## Limitations & Roadmap
+
+Our first general availability release of `pg_graphql` supports:
+
+- Full CRUD on table columns with scalar types
+- Read only support for array types
+- Extending types with [computed fields](https://supabase.github.io/pg_graphql/computed_fields/)
+- Configuration with [SQL comments](https://supabase.github.io/pg_graphql/configuration/)
+
+In the near term, we plan to fully support array and json/b types. Longer term, we intend to support views and custom mutations from user defined functions.
+
+Didn't see the feature you're interested in? [Let us know](https://github.com/supabase/pg_graphql/issues)
diff --git a/www/lib/authors.json b/www/lib/authors.json
index edaa5a794da..e884a8cead3 100644
--- a/www/lib/authors.json
+++ b/www/lib/authors.json
@@ -112,5 +112,13 @@
"position": "Engineering",
"author_url": "https://github.com/w3b6x9",
"author_image_url": "https://github.com/w3b6x9.png"
+ },
+ {
+ "author_id": "dthyresson",
+ "author": "David Thyresson",
+ "username": "dthyresson",
+ "position": "Engineering",
+ "author_url": "https://github.com/dthyresson",
+ "author_image_url": "https://github.com/dthyresson.png"
}
]
diff --git a/www/pages/blog.tsx b/www/pages/blog.tsx
index f11fc03261a..6f844a88c52 100644
--- a/www/pages/blog.tsx
+++ b/www/pages/blog.tsx
@@ -168,26 +168,28 @@ function FeaturedThumb(blog: PostTypes) {
{blog.description}
- {author.map((author: any) => {
- return (
-
- {author.author_image_url && (
-
-
+
+ {author.map((author: any) => {
+ return (
+
+ {author.author_image_url && (
+
+
+
+ )}
+
+ {author.author}
+ {author.position}
- )}
-
- {author.author}
- {author.position}
-
- )
- })}
+ )
+ })}
+
diff --git a/www/pages/blog/[year]/[month]/[day]/[slug].tsx b/www/pages/blog/[year]/[month]/[day]/[slug].tsx
index bacfd356040..e5070c4ab0f 100644
--- a/www/pages/blog/[year]/[month]/[day]/[slug].tsx
+++ b/www/pages/blog/[year]/[month]/[day]/[slug].tsx
@@ -215,7 +215,7 @@ function BlogPostPage(props: any) {