From 4e59f695117e7db47c76e2e628b38afa6d9dad69 Mon Sep 17 00:00:00 2001 From: Greg Richardson Date: Wed, 1 May 2024 22:33:23 -0600 Subject: [PATCH] feat: sql-to-rest docs tool --- .../NavigationMenu.constants.ts | 5 + apps/docs/components/index.tsx | 6 +- apps/docs/content/guides/api/sql-to-rest.mdx | 7 + package-lock.json | 5 +- packages/ui-patterns/SqlToRest/index.tsx | 126 ++++++++++++++++++ packages/ui-patterns/index.tsx | 1 + packages/ui-patterns/package.json | 5 +- 7 files changed, 151 insertions(+), 4 deletions(-) create mode 100644 apps/docs/content/guides/api/sql-to-rest.mdx create mode 100644 packages/ui-patterns/SqlToRest/index.tsx diff --git a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts index 26d333582e3..bf00ca75626 100644 --- a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts +++ b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts @@ -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', diff --git a/apps/docs/components/index.tsx b/apps/docs/components/index.tsx index 107b4f8bd3a..e86ef02691c 100644 --- a/apps/docs/components/index.tsx +++ b/apps/docs/components/index.tsx @@ -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) => {props.children}, Tabs: (props: any) => , diff --git a/apps/docs/content/guides/api/sql-to-rest.mdx b/apps/docs/content/guides/api/sql-to-rest.mdx new file mode 100644 index 00000000000..8437b8c945a --- /dev/null +++ b/apps/docs/content/guides/api/sql-to-rest.mdx @@ -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' +--- + + diff --git a/package-lock.json b/package-lock.json index 9d92c117362..004fe038dbb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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 } } -} \ No newline at end of file +} diff --git a/packages/ui-patterns/SqlToRest/index.tsx b/packages/ui-patterns/SqlToRest/index.tsx new file mode 100644 index 00000000000..386169e09c9 --- /dev/null +++ b/packages/ui-patterns/SqlToRest/index.tsx @@ -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() + + 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 ( +
+
+ { + if (!sql) { + return + } + await process(sql) + }} + /> +
+ +
+ + + + {httpRequest} + + + + + {curlRequest} + + + + + {jsCode} + + + + {errorMessage &&
{errorMessage}
} +
+
+ ) +} + +// 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' }, + } +} diff --git a/packages/ui-patterns/index.tsx b/packages/ui-patterns/index.tsx index b87f8d0b5a4..4de370e84c1 100644 --- a/packages/ui-patterns/index.tsx +++ b/packages/ui-patterns/index.tsx @@ -18,3 +18,4 @@ export * from './Dialogs/ConfirmDialog' export * from './Dialogs/ConfirmationModal' export * from './AssistantChat/AssistantChatForm' export * from './AssistantChat/AssistantCommandsPopover' +export * from './SqlToRest' diff --git a/packages/ui-patterns/package.json b/packages/ui-patterns/package.json index 8992bac23c4..b806a785f1e 100644 --- a/packages/ui-patterns/package.json +++ b/packages/ui-patterns/package.json @@ -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": "*" } -} +} \ No newline at end of file