feat: sql-to-rest docs tool

This commit is contained in:
Greg Richardson committed 2024-05-01 22:33:23 -06:00
1 parent 2b17f5a51d
commit 4e59f69511
7 files changed
+151 -4

No files matched your search

@@ -1024,6 +1024,11 @@ export const api: NavMenuConstant = {
url: '/guides/api/rest/generating-types',
items: [],
},
{
name: 'SQL to REST API Tool',
url: '/guides/api/sql-to-rest',
items: [],
},
{
name: 'Guides',
url: '/guides/api',
+4 -2
View File
@@ -32,9 +32,9 @@ import { NavData } from './NavData'
import { SharedData } from './SharedData'
// Partials
import HuggingFaceDeployment from './MDX/ai/quickstart_hf_deployment.mdx'
import DatabaseSetup from './MDX/database_setup.mdx'
import GetSessionWarning from './MDX/get_session_warning.mdx'
import HuggingFaceDeployment from './MDX/ai/quickstart_hf_deployment.mdx'
import KotlinProjectSetup from './MDX/kotlin_project_setup.mdx'
import MigrationWarnings from './MDX/migration_warnings.mdx'
import ProjectSetup from './MDX/project_setup.mdx'
@@ -43,6 +43,7 @@ import SocialProviderSettingsSupabase from './MDX/social_provider_settings_supab
import SocialProviderSetup from './MDX/social_provider_setup.mdx'
// Icons
import { IconArrowDown, IconCheck } from 'ui'
import {
IconMenuApi,
IconMenuAuth,
@@ -65,9 +66,9 @@ import {
IconMenuStorage,
IconMenuSwift,
} from './Navigation/NavigationMenu/HomeMenuIcons'
import { IconArrowDown, IconCheck } from 'ui'
// Heavy/rare (lazy-loaded)
import SqlToRest from '@ui-patterns/SqlToRest'
import { AppleSecretGenerator } from './AppleSecretGenerator'
import { Extensions } from './Extensions'
import { JwtGenerator } from './JwtGenerator'
@@ -151,6 +152,7 @@ const components = {
SharedData,
SocialProviderSettingsSupabase,
SocialProviderSetup,
SqlToRest,
StepHikeCompact,
TabPanel: (props: any) => <Tabs.Panel {...props}>{props.children}</Tabs.Panel>,
Tabs: (props: any) => <Tabs wrappable {...props} />,
@@ -0,0 +1,7 @@
---
id: 'sql-to-rest'
title: 'SQL to REST API Tool'
description: 'Convert SQL queries to HTTP requests and Supabase client code'
---
<SqlToRest />
+4 -1
View File
@@ -48193,15 +48193,18 @@
"packages/ui-patterns": {
"license": "MIT",
"dependencies": {
"@monaco-editor/react": "^4.6.0",
"cmdk": "^0.2.1",
"common": "*",
"lodash": "*",
"lucide-react": "*",
"monaco-editor": "*",
"next-themes": "*",
"react-error-boundary": "^4.0.12",
"react-hot-toast": "*",
"react-tooltip": "*",
"reactflow": "*",
"sql-to-rest": "*",
"tsconfig": "*",
"ui": "*"
},
@@ -49005,4 +49008,4 @@
"dev": true
}
}
}
}
+126
View File
@@ -0,0 +1,126 @@
import Editor, { useMonaco } from '@monaco-editor/react'
import type { editor } from 'monaco-editor'
import { useTheme } from 'next-themes'
import { useCallback, useEffect, useLayoutEffect, useState } from 'react'
import { processSql, renderHttp, renderSupabaseJs } from 'sql-to-rest'
import { CodeBlock, Tabs } from 'ui'
const defaultValue = `select
*
from
books
where
title = 'Cheese'
`
export default function SqlToRest() {
const [sql, setSql] = useState(defaultValue)
const [httpRequest, setHttpRequest] = useState('')
const [curlRequest, setCurlRequest] = useState('')
const [jsCode, setJsCode] = useState('')
const [errorMessage, setErrorMessage] = useState<string>()
const monaco = useMonaco()
const { resolvedTheme } = useTheme()
useLayoutEffect(() => {
if (monaco && resolvedTheme) {
const mode = getTheme(resolvedTheme)
monaco.editor.defineTheme('supabase', mode)
}
}, [resolvedTheme, monaco])
const process = useCallback(async (sql: string) => {
console.log({ sql })
setSql(sql)
try {
const statement = await processSql(sql)
const { method, path } = renderHttp(statement)
const { code } = renderSupabaseJs(statement)
setErrorMessage(undefined)
setHttpRequest(`${method} ${path}`)
setCurlRequest(`curl -X ${method} ${path}`)
setJsCode(code)
} catch (error) {
if (!(error instanceof Error)) {
console.error(error)
return
}
setErrorMessage(error.message)
}
}, [])
// Process initial value only
useEffect(() => {
process(sql)
}, [process])
return (
<div className="flex justify-between gap-4">
<div className="flex-1 h-96 py-4 border rounded-md bg-[#1e1e1e]">
<Editor
language="pgsql"
theme="supabase"
value={sql}
options={{
tabSize: 2,
minimap: {
enabled: false,
},
}}
onChange={async (sql) => {
if (!sql) {
return
}
await process(sql)
}}
/>
</div>
<div className="flex-1 flex-col gap-2">
<Tabs defaultActiveId="http">
<Tabs.Panel id="http" label="HTTP" className="flex flex-col gap-4">
<CodeBlock language="bash" hideLineNumbers className="self-stretch" hideCopy>
{httpRequest}
</CodeBlock>
</Tabs.Panel>
<Tabs.Panel id="curl" label="cURL" className="flex flex-col gap-4">
<CodeBlock language="bash" hideLineNumbers className="self-stretch">
{curlRequest}
</CodeBlock>
</Tabs.Panel>
<Tabs.Panel id="js" label="JavaScript">
<CodeBlock language="js" hideLineNumbers className="self-stretch">
{jsCode}
</CodeBlock>
</Tabs.Panel>
</Tabs>
{errorMessage && <div className="text-red-900">{errorMessage}</div>}
</div>
</div>
)
}
// TODO: this was copied from studio - find a way to share it between sites
export const getTheme = (theme: string): editor.IStandaloneThemeData => {
const isDarkMode = theme.includes('dark')
// [TODO] Probably need better theming for light mode
return {
base: isDarkMode ? 'vs-dark' : 'vs', // can also be vs-dark or hc-black
inherit: true, // can also be false to completely replace the builtin rules
rules: [
{
token: '',
background: isDarkMode ? '1f1f1f' : 'f0f0f0',
foreground: isDarkMode ? 'd4d4d4' : '444444',
},
{ token: 'string.sql', foreground: '24b47e' },
{ token: 'comment', foreground: '666666' },
{ token: 'predefined.sql', foreground: isDarkMode ? 'D4D4D4' : '444444' },
],
colors: { 'editor.background': isDarkMode ? '#1f1f1f' : '#f0f0f0' },
}
}
+1
View File
@@ -18,3 +18,4 @@ export * from './Dialogs/ConfirmDialog'
export * from './Dialogs/ConfirmationModal'
export * from './AssistantChat/AssistantChatForm'
export * from './AssistantChat/AssistantCommandsPopover'
export * from './SqlToRest'
+4 -1
View File
@@ -8,15 +8,18 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@monaco-editor/react": "^4.6.0",
"cmdk": "^0.2.1",
"common": "*",
"lodash": "*",
"lucide-react": "*",
"monaco-editor": "*",
"next-themes": "*",
"react-error-boundary": "^4.0.12",
"react-hot-toast": "*",
"react-tooltip": "*",
"reactflow": "*",
"sql-to-rest": "*",
"tsconfig": "*",
"ui": "*"
},
@@ -28,4 +31,4 @@
"react": "*",
"react-dom": "*"
}
}
}