feat: sql types autocomplete (#2810)

* feat: sql types autocomplete

* fix: frontend check
This commit is contained in:
HugoCasa
2023-12-08 15:20:33 +01:00
committed by GitHub
parent b9f7fd882a
commit 03568178a4
9 changed files with 208 additions and 15 deletions
+70 -5
View File
@@ -44,7 +44,7 @@
import type { DocumentUri, MessageTransports } from 'vscode-languageclient'
import { buildWorkerDefinition } from './build_workers'
import { workspaceStore } from '$lib/stores'
import { UserService } from '$lib/gen'
import { Preview, UserService } from '$lib/gen'
import type { Text } from 'yjs'
import { initializeMode } from 'monaco-graphql/esm/initializeMode'
import type { MonacoGraphQLAPI } from 'monaco-graphql/esm/api'
@@ -52,6 +52,13 @@
import { editorCodeCompletion } from './copilot/completion'
import { initializeVscode } from './vscode'
import EditorTheme from './EditorTheme.svelte'
import {
BIGQUERY_TYPES,
MSSQL_TYPES,
MYSQL_TYPES,
POSTGRES_TYPES,
SNOWFLAKE_TYPES
} from '$lib/consts'
// import EditorTheme from './EditorTheme.svelte'
let divEl: HTMLDivElement | null = null
@@ -66,7 +73,6 @@
| 'graphql'
| 'powershell'
| 'css'
export let deno: boolean
export let code: string = ''
export let cmdEnterAction: (() => void) | undefined = undefined
export let formatAction: (() => void) | undefined = undefined
@@ -90,6 +96,7 @@
export let useWebsockets: boolean = true
export let listenEmptyChanges = false
export let small = false
export let scriptLang: Preview.language
const rHash = randomHash()
$: filePath = computePath(path)
@@ -119,7 +126,7 @@
let destroyed = false
const uri =
lang == 'typescript' && deno
lang == 'typescript' && scriptLang === 'deno'
? `file:///${filePath ?? rHash}.${langToExt(lang)}`
: `file:///tmp/monaco/${randomHash()}.${langToExt(lang)}`
@@ -239,6 +246,63 @@
let command: Disposable | undefined = undefined
let sqlTypeCompletor: Disposable | undefined = undefined
$: lang === 'sql' && scriptLang ? addSqlTypeCompletor() : sqlTypeCompletor?.dispose()
function addSqlTypeCompletor() {
if (sqlTypeCompletor) {
sqlTypeCompletor.dispose()
}
sqlTypeCompletor = languages.registerCompletionItemProvider('sql', {
triggerCharacters: scriptLang === 'postgresql' ? [':'] : ['('],
provideCompletionItems: function (model, position) {
const lineUntilPosition = model.getValueInRange({
startLineNumber: position.lineNumber,
startColumn: 1,
endLineNumber: position.lineNumber,
endColumn: position.column
})
let suggestions: languages.CompletionItem[] = []
if (
scriptLang === 'postgresql'
? lineUntilPosition.endsWith('::')
: lineUntilPosition.match(/^-- .* \(/)
) {
const word = model.getWordUntilPosition(position)
const range = {
startLineNumber: position.lineNumber,
endLineNumber: position.lineNumber,
startColumn: word.startColumn,
endColumn: word.endColumn
}
suggestions = (
scriptLang === 'postgresql'
? POSTGRES_TYPES
: scriptLang === 'mysql'
? MYSQL_TYPES
: scriptLang === 'snowflake'
? SNOWFLAKE_TYPES
: scriptLang === 'bigquery'
? BIGQUERY_TYPES
: scriptLang === 'mssql'
? MSSQL_TYPES
: []
).map((t) => ({
label: t,
kind: languages.CompletionItemKind.Function,
insertText: t,
range: range,
sortText: 'a'
}))
}
return {
suggestions
}
}
})
}
let sqlSchemaCompletor: Disposable | undefined = undefined
function updateSchema() {
@@ -616,7 +680,7 @@
let encodedImportMap = ''
if (useWebsockets) {
if (lang == 'typescript' && deno) {
if (lang == 'typescript' && scriptLang === 'deno') {
let expiration = new Date()
expiration.setHours(expiration.getHours() + 2)
const token = await UserService.createToken({
@@ -682,7 +746,7 @@
]
}
)
} else if (lang === 'typescript' && !deno) {
} else if (lang === 'typescript' && scriptLang !== 'deno') {
await connectToLanguageServer(
`${wsProtocol}://${window.location.host}/ws/bun`,
'bun',
@@ -1012,6 +1076,7 @@
websocketInterval && clearInterval(websocketInterval)
sqlSchemaCompletor && sqlSchemaCompletor.dispose()
copilotCompletor && copilotCompletor.dispose()
sqlTypeCompletor && sqlTypeCompletor.dispose()
})
</script>
@@ -307,7 +307,7 @@
}}
class="flex flex-1 h-full !overflow-visible"
lang={scriptLangToEditorLang(lang)}
deno={lang == 'deno'}
scriptLang={lang}
automaticLayout={true}
{fixedOverflowWidgets}
{args}
@@ -4,7 +4,7 @@
import Multiselect from 'svelte-multiselect'
import ToggleButton from './common/toggleButton-v2/ToggleButton.svelte'
import ToggleButtonGroup from './common/toggleButton-v2/ToggleButtonGroup.svelte'
import { ConfigService } from '$lib/gen'
import { ConfigService, Preview } from '$lib/gen'
import ConfirmationModal from './common/confirmationModal/ConfirmationModal.svelte'
import { createEventDispatcher } from 'svelte'
import { sendUserToast } from '$lib/toast'
@@ -353,7 +353,7 @@
class="flex flex-1 grow h-full w-full"
automaticLayout
lang="shell"
deno={false}
scriptLang={Preview.language.BASH}
useWebsockets={false}
fixedOverflowWidgets={false}
listenEmptyChanges
@@ -202,8 +202,6 @@
fixedOverflowWidgets={true}
small
automaticLayout
deno={false}
subType="tailwind"
/>
</div>
{#if componentType && ccomponents?.[componentType]?.quickstyle?.[name]?.quickTailwindClasses}
@@ -80,7 +80,6 @@
small
automaticLayout
bind:this={cssEditor}
deno={false}
/>
{:else}
<ThemeCodePreview theme={$app.theme}>
@@ -29,6 +29,5 @@
small
automaticLayout
bind:this={cssEditor}
deno={false}
/>
</div>
@@ -254,12 +254,12 @@
{#if !drawerIsOpen}
{#if inlineScript.language != 'frontend'}
<Editor
deno={inlineScript.language == 'deno'}
path={inlineScript.path}
bind:this={editor}
small
class="flex flex-1 grow h-full"
lang={scriptLangToEditorLang(inlineScript?.language)}
scriptLang={inlineScript.language}
bind:code={inlineScript.content}
fixedOverflowWidgets={true}
cmdEnterAction={async () => {
@@ -8,7 +8,7 @@
import Toggle from '$lib/components/Toggle.svelte'
import { createScriptFromInlineScript, fork } from '$lib/components/flows/flowStateUtils'
import { RawScript, type FlowModule, Script } from '$lib/gen'
import { type FlowModule, Script } from '$lib/gen'
import FlowCard from '../common/FlowCard.svelte'
import FlowModuleHeader from './FlowModuleHeader.svelte'
import { getLatestHashForScript, scriptLangToEditorLang } from '$lib/scripts'
@@ -259,8 +259,8 @@
bind:this={editor}
class="h-full relative"
bind:code={flowModule.value.content}
deno={flowModule.value.language === RawScript.language.DENO}
lang={scriptLangToEditorLang(flowModule.value.language)}
scriptLang={flowModule.value.language}
automaticLayout={true}
cmdEnterAction={async () => {
selected = 'test'
+132
View File
@@ -43,3 +43,135 @@ export const WORKER_S3_BUCKET_SYNC_SETTING = 'worker_s3_bucket_sync'
export const CUSTOM_TAGS_SETTING = 'custom_tags'
export const WORKSPACE_SLACK_BOT_TOKEN_PATH = 'f/slack_bot/bot_token'
export const POSTGRES_TYPES = [
'VARCHAR',
'VARCHAR[]',
'TEXT',
'TEXT[]',
'INT',
'INT[]',
'BIGINT',
'BIGINT[]',
'BOOL',
'BOOL[]',
'CHAR',
'CHAR[]',
'SMALLINT',
'SMALLINT[]',
'SMALLSERIAL',
'SMALLSERIAL[]',
'SERIAL',
'SERIAL[]',
'BIGSERIAL',
'BIGSERIAL[]',
'REAL',
'REAL[]',
'DOUBLE PRECISION',
'DOUBLE PRECISION[]',
'NUMERIC',
'NUMERIC[]',
'DECIMAL',
'DECIMAL[]',
'OID',
'OID[]',
'DATE',
'DATE[]',
'TIME',
'TIME[]',
'TIMESTAMP',
'TIMESTAMP[]'
]
export const MYSQL_TYPES = [
'varchar',
'char',
'bin',
'varbinary',
'blob',
'text',
'enum',
'set',
'int',
'uint',
'integer',
'bool',
'bit',
'float',
'real',
'dec',
'fixed',
'date',
'datetime',
'timestamp',
'time'
]
export const BIGQUERY_TYPES = [
'string',
'string[]',
'bytes',
'bytes[]',
'json',
'json[]',
'timestamp',
'timestamp[]',
'date',
'date[]',
'time',
'time[]',
'datetime',
'datetime[]',
'integer',
'integer[]',
'int64',
'int64[]',
'float',
'float[]',
'float64',
'float64[]',
'numeric',
'numeric[]',
'bignumeric',
'bignumeric[]',
'bool',
'bool[]'
]
export const SNOWFLAKE_TYPES = [
'varchar',
'binary',
'date',
'time',
'timestamp',
'int',
'float',
'boolean'
]
export const MSSQL_TYPES = [
'char',
'varchar',
'text',
'nchar',
'nvarchar',
'ntext',
'binary',
'varbinary',
'image',
'date',
'datetime2',
'datetime',
'datetimeoffset',
'smalldatetime',
'time',
'bigint',
'int',
'tinyint',
'smallint',
'float',
'real',
'numeric',
'decimal',
'bit'
]