@sqlrooms/sql-editor 0.29.0-rc.1 → 0.29.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -3
- package/dist/SqlCodeMirrorEditor.d.ts +29 -0
- package/dist/SqlCodeMirrorEditor.d.ts.map +1 -0
- package/dist/SqlCodeMirrorEditor.js +54 -0
- package/dist/SqlCodeMirrorEditor.js.map +1 -0
- package/dist/SqlMonacoEditor.d.ts +10 -4
- package/dist/SqlMonacoEditor.d.ts.map +1 -1
- package/dist/SqlMonacoEditor.js +51 -11
- package/dist/SqlMonacoEditor.js.map +1 -1
- package/dist/codemirror/extensions/completion.d.ts +12 -0
- package/dist/codemirror/extensions/completion.d.ts.map +1 -0
- package/dist/codemirror/extensions/completion.js +60 -0
- package/dist/codemirror/extensions/completion.js.map +1 -0
- package/dist/codemirror/extensions/create-sql-extension.d.ts +17 -0
- package/dist/codemirror/extensions/create-sql-extension.d.ts.map +1 -0
- package/dist/codemirror/extensions/create-sql-extension.js +20 -0
- package/dist/codemirror/extensions/create-sql-extension.js.map +1 -0
- package/dist/codemirror/extensions/duck-db/duck-db.d.ts +9 -0
- package/dist/codemirror/extensions/duck-db/duck-db.d.ts.map +1 -0
- package/dist/codemirror/extensions/duck-db/duck-db.js +27 -0
- package/dist/codemirror/extensions/duck-db/duck-db.js.map +1 -0
- package/dist/codemirror/extensions/duck-db/duckdb-keywords.d.ts +2 -0
- package/dist/codemirror/extensions/duck-db/duckdb-keywords.d.ts.map +1 -0
- package/dist/codemirror/extensions/duck-db/duckdb-keywords.js +487 -0
- package/dist/codemirror/extensions/duck-db/duckdb-keywords.js.map +1 -0
- package/dist/codemirror/extensions/duck-db/duckdb-sql-extension.d.ts +5 -0
- package/dist/codemirror/extensions/duck-db/duckdb-sql-extension.d.ts.map +1 -0
- package/dist/codemirror/extensions/duck-db/duckdb-sql-extension.js +36 -0
- package/dist/codemirror/extensions/duck-db/duckdb-sql-extension.js.map +1 -0
- package/dist/codemirror/extensions/duck-db/duckdb-sql.d.ts +5 -0
- package/dist/codemirror/extensions/duck-db/duckdb-sql.d.ts.map +1 -0
- package/dist/codemirror/extensions/duck-db/duckdb-sql.js +11 -0
- package/dist/codemirror/extensions/duck-db/duckdb-sql.js.map +1 -0
- package/dist/codemirror/extensions/duck-db/index.d.ts +2 -0
- package/dist/codemirror/extensions/duck-db/index.d.ts.map +1 -0
- package/dist/codemirror/extensions/duck-db/index.js +2 -0
- package/dist/codemirror/extensions/duck-db/index.js.map +1 -0
- package/dist/codemirror/extensions/hover.d.ts +11 -0
- package/dist/codemirror/extensions/hover.d.ts.map +1 -0
- package/dist/codemirror/extensions/hover.js +55 -0
- package/dist/codemirror/extensions/hover.js.map +1 -0
- package/dist/codemirror/extensions/sql-keymap.d.ts +4 -0
- package/dist/codemirror/extensions/sql-keymap.d.ts.map +1 -0
- package/dist/codemirror/extensions/sql-keymap.js +25 -0
- package/dist/codemirror/extensions/sql-keymap.js.map +1 -0
- package/dist/codemirror/themes/sql-theme.d.ts +7 -0
- package/dist/codemirror/themes/sql-theme.d.ts.map +1 -0
- package/dist/codemirror/themes/sql-theme.js +55 -0
- package/dist/codemirror/themes/sql-theme.js.map +1 -0
- package/dist/codemirror/themes/sql-tooltip-theme.d.ts +7 -0
- package/dist/codemirror/themes/sql-tooltip-theme.d.ts.map +1 -0
- package/dist/codemirror/themes/sql-tooltip-theme.js +21 -0
- package/dist/codemirror/themes/sql-tooltip-theme.js.map +1 -0
- package/dist/codemirror/utils/schema-converter.d.ts +5 -0
- package/dist/codemirror/utils/schema-converter.d.ts.map +1 -0
- package/dist/codemirror/utils/schema-converter.js +9 -0
- package/dist/codemirror/utils/schema-converter.js.map +1 -0
- package/dist/components/CreateTableModal.d.ts.map +1 -1
- package/dist/components/CreateTableModal.js +5 -11
- package/dist/components/CreateTableModal.js.map +1 -1
- package/dist/components/FunctionDocumentation.d.ts +7 -0
- package/dist/components/FunctionDocumentation.d.ts.map +1 -0
- package/dist/components/FunctionDocumentation.js +44 -0
- package/dist/components/FunctionDocumentation.js.map +1 -0
- package/dist/components/QueryEditorPanelActions.d.ts.map +1 -1
- package/dist/components/QueryEditorPanelActions.js +3 -37
- package/dist/components/QueryEditorPanelActions.js.map +1 -1
- package/dist/components/QueryEditorPanelEditor.d.ts.map +1 -1
- package/dist/components/QueryEditorPanelEditor.js +11 -34
- package/dist/components/QueryEditorPanelEditor.js.map +1 -1
- package/dist/components/SchemaExplorer.d.ts +25 -0
- package/dist/components/SchemaExplorer.d.ts.map +1 -0
- package/dist/components/SchemaExplorer.js +20 -0
- package/dist/components/SchemaExplorer.js.map +1 -0
- package/dist/components/SqlColumnTooltip.d.ts +12 -0
- package/dist/components/SqlColumnTooltip.d.ts.map +1 -0
- package/dist/components/SqlColumnTooltip.js +15 -0
- package/dist/components/SqlColumnTooltip.js.map +1 -0
- package/dist/components/SqlColumnsTable.d.ts +10 -0
- package/dist/components/SqlColumnsTable.d.ts.map +1 -0
- package/dist/components/SqlColumnsTable.js +10 -0
- package/dist/components/SqlColumnsTable.js.map +1 -0
- package/dist/components/SqlTableTooltip.d.ts +9 -0
- package/dist/components/SqlTableTooltip.d.ts.map +1 -0
- package/dist/components/SqlTableTooltip.js +13 -0
- package/dist/components/SqlTableTooltip.js.map +1 -0
- package/dist/components/TableStructurePanel.d.ts +6 -3
- package/dist/components/TableStructurePanel.d.ts.map +1 -1
- package/dist/components/TableStructurePanel.js +8 -7
- package/dist/components/TableStructurePanel.js.map +1 -1
- package/dist/index.d.ts +21 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -1
- package/dist/utils/qualified-name-parser.d.ts +41 -0
- package/dist/utils/qualified-name-parser.d.ts.map +1 -0
- package/dist/utils/qualified-name-parser.js +126 -0
- package/dist/utils/qualified-name-parser.js.map +1 -0
- package/package.json +23 -11
package/README.md
CHANGED
|
@@ -79,8 +79,12 @@ import {useRoomStore} from './store';
|
|
|
79
79
|
import {Button} from '@sqlrooms/ui';
|
|
80
80
|
|
|
81
81
|
function RunQueryButton() {
|
|
82
|
-
const parseAndRunQuery = useRoomStore(
|
|
83
|
-
|
|
82
|
+
const parseAndRunQuery = useRoomStore(
|
|
83
|
+
(state) => state.sqlEditor.parseAndRunQuery,
|
|
84
|
+
);
|
|
85
|
+
const createQueryTab = useRoomStore(
|
|
86
|
+
(state) => state.sqlEditor.createQueryTab,
|
|
87
|
+
);
|
|
84
88
|
|
|
85
89
|
const run = async () => {
|
|
86
90
|
createQueryTab('SELECT COUNT(*) AS total FROM earthquakes');
|
|
@@ -101,7 +105,13 @@ import {useState} from 'react';
|
|
|
101
105
|
|
|
102
106
|
export function StandaloneEditor() {
|
|
103
107
|
const [sql, setSql] = useState('SELECT 1');
|
|
104
|
-
return
|
|
108
|
+
return (
|
|
109
|
+
<SqlMonacoEditor
|
|
110
|
+
value={sql}
|
|
111
|
+
onChange={(v) => setSql(v ?? '')}
|
|
112
|
+
height="320px"
|
|
113
|
+
/>
|
|
114
|
+
);
|
|
105
115
|
}
|
|
106
116
|
```
|
|
107
117
|
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { DataTable, DuckDbConnector } from '@sqlrooms/duckdb';
|
|
3
|
+
import { CodeMirrorEditorProps } from '@sqlrooms/codemirror';
|
|
4
|
+
import { type SqlDialect } from './codemirror/extensions/create-sql-extension';
|
|
5
|
+
export interface SqlCodeMirrorEditorProps extends Omit<CodeMirrorEditorProps, 'extensions'> {
|
|
6
|
+
/** SQL dialect for syntax highlighting and completions */
|
|
7
|
+
dialect?: SqlDialect;
|
|
8
|
+
/**
|
|
9
|
+
* Connector for dynamic function suggestions
|
|
10
|
+
* TODO: change to generic connector interface to support multiple dialects
|
|
11
|
+
*/
|
|
12
|
+
connector?: DuckDbConnector;
|
|
13
|
+
/** Table schemas for autocompletion and hover tooltips */
|
|
14
|
+
tableSchemas?: DataTable[];
|
|
15
|
+
/** Callback to get the latest table schemas */
|
|
16
|
+
getLatestSchemas?: () => {
|
|
17
|
+
tableSchemas: DataTable[];
|
|
18
|
+
};
|
|
19
|
+
/** Callback when Cmd+Enter is pressed (selected text or full document) */
|
|
20
|
+
onRunQuery?: (query: string) => void;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* CodeMirror editor for SQL with dialect-specific support
|
|
24
|
+
*
|
|
25
|
+
* Lightweight alternative to SqlMonacoEditor with syntax highlighting,
|
|
26
|
+
* linting, schema-aware completions, and hover tooltips. Cmd+Enter to run query.
|
|
27
|
+
*/
|
|
28
|
+
export declare const SqlCodeMirrorEditor: React.FC<SqlCodeMirrorEditorProps>;
|
|
29
|
+
//# sourceMappingURL=SqlCodeMirrorEditor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SqlCodeMirrorEditor.d.ts","sourceRoot":"","sources":["../src/SqlCodeMirrorEditor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqC,MAAM,OAAO,CAAC;AAG1D,OAAO,KAAK,EAAC,SAAS,EAAE,eAAe,EAAC,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAmB,qBAAqB,EAAC,MAAM,sBAAsB,CAAC;AAC7E,OAAO,EAGL,KAAK,UAAU,EAChB,MAAM,8CAA8C,CAAC;AAItD,MAAM,WAAW,wBAAyB,SAAQ,IAAI,CACpD,qBAAqB,EACrB,YAAY,CACb;IACC,0DAA0D;IAC1D,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB;;;OAGG;IACH,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,0DAA0D;IAC1D,YAAY,CAAC,EAAE,SAAS,EAAE,CAAC;IAC3B,+CAA+C;IAC/C,gBAAgB,CAAC,EAAE,MAAM;QAAC,YAAY,EAAE,SAAS,EAAE,CAAA;KAAC,CAAC;IACrD,0EAA0E;IAC1E,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC;AASD;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,EAAE,KAAK,CAAC,EAAE,CAAC,wBAAwB,CA8DlE,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useMemo, useRef } from 'react';
|
|
3
|
+
import { CodeMirrorEditor } from '@sqlrooms/codemirror';
|
|
4
|
+
import { createSqlExtension, SqlDialects, } from './codemirror/extensions/create-sql-extension';
|
|
5
|
+
import { createSqlKeymap } from './codemirror/extensions/sql-keymap';
|
|
6
|
+
import { createSqlTheme } from './codemirror/themes/sql-theme';
|
|
7
|
+
const EDITOR_OPTIONS = {
|
|
8
|
+
lineNumbers: true,
|
|
9
|
+
lineWrapping: true,
|
|
10
|
+
highlightActiveLine: true,
|
|
11
|
+
autocompletion: true,
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* CodeMirror editor for SQL with dialect-specific support
|
|
15
|
+
*
|
|
16
|
+
* Lightweight alternative to SqlMonacoEditor with syntax highlighting,
|
|
17
|
+
* linting, schema-aware completions, and hover tooltips. Cmd+Enter to run query.
|
|
18
|
+
*/
|
|
19
|
+
export const SqlCodeMirrorEditor = ({ dialect = SqlDialects.DuckDb, connector, tableSchemas = [], getLatestSchemas, onRunQuery, onMount, options, ...restProps }) => {
|
|
20
|
+
const viewRef = useRef(null);
|
|
21
|
+
// Get current schemas (use callback if provided)
|
|
22
|
+
const currentSchemas = useMemo(() => {
|
|
23
|
+
if (getLatestSchemas) {
|
|
24
|
+
return getLatestSchemas().tableSchemas;
|
|
25
|
+
}
|
|
26
|
+
return tableSchemas;
|
|
27
|
+
}, [getLatestSchemas, tableSchemas]);
|
|
28
|
+
// Build extensions
|
|
29
|
+
const extensions = useMemo(() => {
|
|
30
|
+
return [
|
|
31
|
+
...createSqlExtension({
|
|
32
|
+
dialect,
|
|
33
|
+
currentSchemas,
|
|
34
|
+
connector,
|
|
35
|
+
}),
|
|
36
|
+
createSqlKeymap(onRunQuery),
|
|
37
|
+
createSqlTheme(),
|
|
38
|
+
];
|
|
39
|
+
}, [dialect, currentSchemas, onRunQuery, connector]);
|
|
40
|
+
// Handle editor mount
|
|
41
|
+
const handleEditorMount = useCallback((view) => {
|
|
42
|
+
viewRef.current = view;
|
|
43
|
+
// Call user onMount if provided
|
|
44
|
+
if (onMount) {
|
|
45
|
+
onMount(view);
|
|
46
|
+
}
|
|
47
|
+
}, [onMount]);
|
|
48
|
+
const combinedOptions = useMemo(() => ({
|
|
49
|
+
...EDITOR_OPTIONS,
|
|
50
|
+
...options,
|
|
51
|
+
}), [options]);
|
|
52
|
+
return (_jsx(CodeMirrorEditor, { onMount: handleEditorMount, extensions: extensions, options: combinedOptions, ...restProps }));
|
|
53
|
+
};
|
|
54
|
+
//# sourceMappingURL=SqlCodeMirrorEditor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SqlCodeMirrorEditor.js","sourceRoot":"","sources":["../src/SqlCodeMirrorEditor.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAC,WAAW,EAAE,OAAO,EAAE,MAAM,EAAC,MAAM,OAAO,CAAC;AAI1D,OAAO,EAAC,gBAAgB,EAAwB,MAAM,sBAAsB,CAAC;AAC7E,OAAO,EACL,kBAAkB,EAClB,WAAW,GAEZ,MAAM,8CAA8C,CAAC;AACtD,OAAO,EAAC,eAAe,EAAC,MAAM,oCAAoC,CAAC;AACnE,OAAO,EAAC,cAAc,EAAC,MAAM,+BAA+B,CAAC;AAqB7D,MAAM,cAAc,GAAqC;IACvD,WAAW,EAAE,IAAI;IACjB,YAAY,EAAE,IAAI;IAClB,mBAAmB,EAAE,IAAI;IACzB,cAAc,EAAE,IAAI;CACrB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAuC,CAAC,EACtE,OAAO,GAAG,WAAW,CAAC,MAAM,EAC5B,SAAS,EACT,YAAY,GAAG,EAAE,EACjB,gBAAgB,EAChB,UAAU,EACV,OAAO,EACP,OAAO,EACP,GAAG,SAAS,EACb,EAAE,EAAE;IACH,MAAM,OAAO,GAAG,MAAM,CAAoB,IAAI,CAAC,CAAC;IAEhD,iDAAiD;IACjD,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,EAAE;QAClC,IAAI,gBAAgB,EAAE,CAAC;YACrB,OAAO,gBAAgB,EAAE,CAAC,YAAY,CAAC;QACzC,CAAC;QACD,OAAO,YAAY,CAAC;IACtB,CAAC,EAAE,CAAC,gBAAgB,EAAE,YAAY,CAAC,CAAC,CAAC;IAErC,mBAAmB;IACnB,MAAM,UAAU,GAAG,OAAO,CAAc,GAAG,EAAE;QAC3C,OAAO;YACL,GAAG,kBAAkB,CAAC;gBACpB,OAAO;gBACP,cAAc;gBACd,SAAS;aACV,CAAC;YACF,eAAe,CAAC,UAAU,CAAC;YAC3B,cAAc,EAAE;SACjB,CAAC;IACJ,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC,CAAC;IAErD,sBAAsB;IACtB,MAAM,iBAAiB,GAAG,WAAW,CACnC,CAAC,IAAgB,EAAE,EAAE;QACnB,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;QAEvB,gCAAgC;QAChC,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC;IACH,CAAC,EACD,CAAC,OAAO,CAAC,CACV,CAAC;IAEF,MAAM,eAAe,GAAG,OAAO,CAC7B,GAAqC,EAAE,CAAC,CAAC;QACvC,GAAG,cAAc;QACjB,GAAG,OAAO;KACX,CAAC,EACF,CAAC,OAAO,CAAC,CACV,CAAC;IAEF,OAAO,CACL,KAAC,gBAAgB,IACf,OAAO,EAAE,iBAAiB,EAC1B,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,eAAe,KACpB,SAAS,GACb,CACH,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import React, {useCallback, useMemo, useRef} from 'react';\nimport type {EditorView} from '@codemirror/view';\nimport type {Extension} from '@codemirror/state';\nimport type {DataTable, DuckDbConnector} from '@sqlrooms/duckdb';\nimport {CodeMirrorEditor, CodeMirrorEditorProps} from '@sqlrooms/codemirror';\nimport {\n createSqlExtension,\n SqlDialects,\n type SqlDialect,\n} from './codemirror/extensions/create-sql-extension';\nimport {createSqlKeymap} from './codemirror/extensions/sql-keymap';\nimport {createSqlTheme} from './codemirror/themes/sql-theme';\n\nexport interface SqlCodeMirrorEditorProps extends Omit<\n CodeMirrorEditorProps,\n 'extensions'\n> {\n /** SQL dialect for syntax highlighting and completions */\n dialect?: SqlDialect;\n /**\n * Connector for dynamic function suggestions\n * TODO: change to generic connector interface to support multiple dialects\n */\n connector?: DuckDbConnector;\n /** Table schemas for autocompletion and hover tooltips */\n tableSchemas?: DataTable[];\n /** Callback to get the latest table schemas */\n getLatestSchemas?: () => {tableSchemas: DataTable[]};\n /** Callback when Cmd+Enter is pressed (selected text or full document) */\n onRunQuery?: (query: string) => void;\n}\n\nconst EDITOR_OPTIONS: CodeMirrorEditorProps['options'] = {\n lineNumbers: true,\n lineWrapping: true,\n highlightActiveLine: true,\n autocompletion: true,\n};\n\n/**\n * CodeMirror editor for SQL with dialect-specific support\n *\n * Lightweight alternative to SqlMonacoEditor with syntax highlighting,\n * linting, schema-aware completions, and hover tooltips. Cmd+Enter to run query.\n */\nexport const SqlCodeMirrorEditor: React.FC<SqlCodeMirrorEditorProps> = ({\n dialect = SqlDialects.DuckDb,\n connector,\n tableSchemas = [],\n getLatestSchemas,\n onRunQuery,\n onMount,\n options,\n ...restProps\n}) => {\n const viewRef = useRef<EditorView | null>(null);\n\n // Get current schemas (use callback if provided)\n const currentSchemas = useMemo(() => {\n if (getLatestSchemas) {\n return getLatestSchemas().tableSchemas;\n }\n return tableSchemas;\n }, [getLatestSchemas, tableSchemas]);\n\n // Build extensions\n const extensions = useMemo<Extension[]>(() => {\n return [\n ...createSqlExtension({\n dialect,\n currentSchemas,\n connector,\n }),\n createSqlKeymap(onRunQuery),\n createSqlTheme(),\n ];\n }, [dialect, currentSchemas, onRunQuery, connector]);\n\n // Handle editor mount\n const handleEditorMount = useCallback(\n (view: EditorView) => {\n viewRef.current = view;\n\n // Call user onMount if provided\n if (onMount) {\n onMount(view);\n }\n },\n [onMount],\n );\n\n const combinedOptions = useMemo(\n (): CodeMirrorEditorProps['options'] => ({\n ...EDITOR_OPTIONS,\n ...options,\n }),\n [options],\n );\n\n return (\n <CodeMirrorEditor\n onMount={handleEditorMount}\n extensions={extensions}\n options={combinedOptions}\n {...restProps}\n />\n );\n};\n"]}
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import type { DataTable, DuckDbConnector } from '@sqlrooms/db';
|
|
2
2
|
import type { MonacoEditorProps } from '@sqlrooms/monaco-editor';
|
|
3
3
|
import React from 'react';
|
|
4
|
+
export type SqlMonacoRunQueryOptions = {
|
|
5
|
+
value: string;
|
|
6
|
+
selectedValue: string;
|
|
7
|
+
isSelectionEmpty: boolean;
|
|
8
|
+
};
|
|
4
9
|
export interface SqlMonacoEditorProps extends Omit<MonacoEditorProps, 'language'> {
|
|
5
10
|
connector?: DuckDbConnector;
|
|
6
11
|
/**
|
|
@@ -23,17 +28,18 @@ export interface SqlMonacoEditorProps extends Omit<MonacoEditorProps, 'language'
|
|
|
23
28
|
* Table schemas for autocompletion
|
|
24
29
|
*/
|
|
25
30
|
tableSchemas?: DataTable[];
|
|
26
|
-
/**
|
|
27
|
-
* Callback to get the latest table schemas
|
|
28
|
-
* This is called from within provideCompletionItems to ensure we have the latest data
|
|
29
|
-
*/
|
|
31
|
+
/** Callback to get the latest table schemas */
|
|
30
32
|
getLatestSchemas?: () => {
|
|
31
33
|
tableSchemas: DataTable[];
|
|
32
34
|
};
|
|
35
|
+
/** Callback when Cmd/Ctrl+Enter is pressed to run query */
|
|
36
|
+
onRunQuery?: (params: SqlMonacoRunQueryOptions) => void;
|
|
33
37
|
}
|
|
34
38
|
/**
|
|
35
39
|
* A Monaco editor for editing SQL with DuckDB syntax highlighting and autocompletion
|
|
36
40
|
* This is an internal component used by SqlEditor
|
|
41
|
+
*
|
|
42
|
+
* @deprecated Use SqlCodeMirrorEditor instead. This component will be removed in a future version.
|
|
37
43
|
*/
|
|
38
44
|
export declare const SqlMonacoEditor: React.FC<SqlMonacoEditorProps>;
|
|
39
45
|
//# sourceMappingURL=SqlMonacoEditor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SqlMonacoEditor.d.ts","sourceRoot":"","sources":["../src/SqlMonacoEditor.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,SAAS,EAAE,eAAe,EAAC,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"SqlMonacoEditor.d.ts","sourceRoot":"","sources":["../src/SqlMonacoEditor.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,SAAS,EAAE,eAAe,EAAC,MAAM,cAAc,CAAC;AAE7D,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,yBAAyB,CAAC;AAI/D,OAAO,KAAgD,MAAM,OAAO,CAAC;AASrE,MAAM,MAAM,wBAAwB,GAAG;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,OAAO,CAAC;CAC3B,CAAC;AAEF,MAAM,WAAW,oBAAqB,SAAQ,IAAI,CAChD,iBAAiB,EACjB,UAAU,CACX;IACC,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B;;OAEG;IACH,YAAY,CAAC,EAAE,SAAS,EAAE,CAAC;IAC3B,+CAA+C;IAC/C,gBAAgB,CAAC,EAAE,MAAM;QACvB,YAAY,EAAE,SAAS,EAAE,CAAC;KAC3B,CAAC;IACF,2DAA2D;IAC3D,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,wBAAwB,KAAK,IAAI,CAAC;CACzD;AAkOD;;;;;GAKG;AACH,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAyI1D,CAAC"}
|
package/dist/SqlMonacoEditor.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { getFunctionSuggestions } from '@sqlrooms/duckdb';
|
|
2
3
|
import { MonacoEditor } from '@sqlrooms/monaco-editor';
|
|
3
4
|
import { cn } from '@sqlrooms/ui';
|
|
4
5
|
import { useCallback, useEffect, useMemo, useRef } from 'react';
|
|
5
6
|
import { DUCKDB_FUNCTIONS, DUCKDB_KEYWORDS, SQL_LANGUAGE_CONFIGURATION, } from './constants/duckdb-dialect';
|
|
6
|
-
import {
|
|
7
|
+
import { FunctionDocumentation } from './components/FunctionDocumentation';
|
|
8
|
+
import { renderComponentToString } from '@sqlrooms/utils';
|
|
7
9
|
const EDITOR_OPTIONS = {
|
|
8
10
|
formatOnPaste: true,
|
|
9
11
|
formatOnType: true,
|
|
@@ -102,13 +104,15 @@ function ensureSqlCompletionProvider(monaco) {
|
|
|
102
104
|
});
|
|
103
105
|
});
|
|
104
106
|
if (ctx.connector) {
|
|
105
|
-
const
|
|
106
|
-
for (const { name,
|
|
107
|
+
const functionGroups = await getFunctionSuggestions(ctx.connector, word.word);
|
|
108
|
+
for (const { name, overloads } of functionGroups) {
|
|
107
109
|
suggestions.push({
|
|
108
110
|
label: name,
|
|
109
111
|
insertText: name,
|
|
110
112
|
documentation: {
|
|
111
|
-
value:
|
|
113
|
+
value: renderComponentToString(FunctionDocumentation, {
|
|
114
|
+
functions: overloads,
|
|
115
|
+
}),
|
|
112
116
|
isTrusted: true,
|
|
113
117
|
supportHtml: true,
|
|
114
118
|
},
|
|
@@ -193,9 +197,15 @@ function ensureSqlCompletionProvider(monaco) {
|
|
|
193
197
|
/**
|
|
194
198
|
* A Monaco editor for editing SQL with DuckDB syntax highlighting and autocompletion
|
|
195
199
|
* This is an internal component used by SqlEditor
|
|
200
|
+
*
|
|
201
|
+
* @deprecated Use SqlCodeMirrorEditor instead. This component will be removed in a future version.
|
|
196
202
|
*/
|
|
197
|
-
export const SqlMonacoEditor = ({ connector, customKeywords = [], customFunctions = [], tableSchemas = [], getLatestSchemas, onMount, className, options, ...restProps }) => {
|
|
203
|
+
export const SqlMonacoEditor = ({ connector, customKeywords = [], customFunctions = [], tableSchemas = [], getLatestSchemas, onRunQuery, onMount, className, options, ...restProps }) => {
|
|
198
204
|
const modelRef = useRef(null);
|
|
205
|
+
const onRunQueryRef = useRef(onRunQuery);
|
|
206
|
+
useEffect(() => {
|
|
207
|
+
onRunQueryRef.current = onRunQuery;
|
|
208
|
+
}, [onRunQuery]);
|
|
199
209
|
// Update per-model context when props change
|
|
200
210
|
useEffect(() => {
|
|
201
211
|
const model = modelRef.current;
|
|
@@ -228,8 +238,9 @@ export const SqlMonacoEditor = ({ connector, customKeywords = [], customFunction
|
|
|
228
238
|
const handleEditorDidMount = useCallback((editor, monaco) => {
|
|
229
239
|
ensureSqlLanguageConfigured(monaco);
|
|
230
240
|
ensureSqlCompletionProvider(monaco);
|
|
231
|
-
const
|
|
232
|
-
|
|
241
|
+
const setContextForModel = (model) => {
|
|
242
|
+
if (!model)
|
|
243
|
+
return;
|
|
233
244
|
modelRef.current = model;
|
|
234
245
|
sqlCompletionContextByModel.set(model, {
|
|
235
246
|
connector,
|
|
@@ -238,13 +249,41 @@ export const SqlMonacoEditor = ({ connector, customKeywords = [], customFunction
|
|
|
238
249
|
customKeywords,
|
|
239
250
|
customFunctions,
|
|
240
251
|
});
|
|
252
|
+
};
|
|
253
|
+
// Initial model context
|
|
254
|
+
setContextForModel(editor.getModel?.());
|
|
255
|
+
// IMPORTANT: when callers pass `path`, @monaco-editor/react swaps the underlying
|
|
256
|
+
// Monaco model without re-mounting the editor. Keep the completion context in sync
|
|
257
|
+
// with the active model so suggestions remain database-aware.
|
|
258
|
+
const modelChangeDisposable = editor.onDidChangeModel?.(() => {
|
|
259
|
+
setContextForModel(editor.getModel?.());
|
|
260
|
+
});
|
|
261
|
+
// Add keyboard shortcut for running query
|
|
262
|
+
if (onRunQuery) {
|
|
263
|
+
editor.onKeyDown((e) => {
|
|
264
|
+
if ((e.ctrlKey || e.metaKey) && e.keyCode === monaco.KeyCode.Enter) {
|
|
265
|
+
e.preventDefault();
|
|
266
|
+
e.stopPropagation();
|
|
267
|
+
const model = editor.getModel();
|
|
268
|
+
const selection = editor.getSelection();
|
|
269
|
+
const value = editor.getValue();
|
|
270
|
+
const selectedValue = model && selection ? model.getValueInRange(selection) : '';
|
|
271
|
+
const isSelectionEmpty = !selection || selection.isEmpty();
|
|
272
|
+
onRunQuery({
|
|
273
|
+
value,
|
|
274
|
+
selectedValue,
|
|
275
|
+
isSelectionEmpty,
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
});
|
|
241
279
|
}
|
|
242
280
|
// Cleanup on dispose
|
|
243
|
-
|
|
244
|
-
|
|
281
|
+
editor.onDidDispose(() => {
|
|
282
|
+
modelChangeDisposable?.dispose?.();
|
|
283
|
+
const model = modelRef.current;
|
|
284
|
+
if (model)
|
|
245
285
|
sqlCompletionContextByModel.delete(model);
|
|
246
|
-
|
|
247
|
-
}
|
|
286
|
+
});
|
|
248
287
|
// Call the original onMount if provided
|
|
249
288
|
if (onMount) {
|
|
250
289
|
onMount(editor, monaco);
|
|
@@ -255,6 +294,7 @@ export const SqlMonacoEditor = ({ connector, customKeywords = [], customFunction
|
|
|
255
294
|
customFunctions,
|
|
256
295
|
getLatestSchemas,
|
|
257
296
|
onMount,
|
|
297
|
+
onRunQuery,
|
|
258
298
|
tableSchemas,
|
|
259
299
|
]);
|
|
260
300
|
const combinedOptions = useMemo(() => ({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SqlMonacoEditor.js","sourceRoot":"","sources":["../src/SqlMonacoEditor.tsx"],"names":[],"mappings":"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","sourcesContent":["import type {OnMount} from '@monaco-editor/react';\nimport type {DataTable, DuckDbConnector} from '@sqlrooms/db';\nimport type {MonacoEditorProps} from '@sqlrooms/monaco-editor';\nimport {MonacoEditor} from '@sqlrooms/monaco-editor';\nimport {cn} from '@sqlrooms/ui';\nimport type * as Monaco from 'monaco-editor';\nimport React, {useCallback, useEffect, useMemo, useRef} from 'react';\nimport {\n DUCKDB_FUNCTIONS,\n DUCKDB_KEYWORDS,\n SQL_LANGUAGE_CONFIGURATION,\n} from './constants/duckdb-dialect';\nimport {getFunctionSuggestions} from './constants/functionSuggestions';\nexport interface SqlMonacoEditorProps extends Omit<\n MonacoEditorProps,\n 'language'\n> {\n connector?: DuckDbConnector;\n /**\n * Custom SQL keywords to add to the completion provider.\n *\n * Note: syntax highlighting is global and uses the built-in DuckDB dialect\n * (`DUCKDB_KEYWORDS` / `DUCKDB_FUNCTIONS`) to avoid per-editor global reconfiguration\n * (which can cause flashing). These are currently **completion-only**.\n */\n customKeywords?: string[];\n /**\n * Custom SQL functions to add to the completion provider.\n *\n * Note: syntax highlighting is global and uses the built-in DuckDB dialect\n * (`DUCKDB_KEYWORDS` / `DUCKDB_FUNCTIONS`) to avoid per-editor global reconfiguration\n * (which can cause flashing). These are currently **completion-only**.\n */\n customFunctions?: string[];\n /**\n * Table schemas for autocompletion\n */\n tableSchemas?: DataTable[];\n /**\n * Callback to get the latest table schemas\n * This is called from within provideCompletionItems to ensure we have the latest data\n */\n getLatestSchemas?: () => {\n tableSchemas: DataTable[];\n };\n}\n\nconst EDITOR_OPTIONS: MonacoEditorProps['options'] = {\n formatOnPaste: true,\n formatOnType: true,\n wordWrap: 'on',\n scrollBeyondLastLine: false,\n scrollbar: {\n alwaysConsumeMouseWheel: false,\n },\n};\n\ntype MonacoInstance = typeof Monaco;\n\ntype SqlCompletionContext = {\n connector?: DuckDbConnector;\n tableSchemas: DataTable[];\n getLatestSchemas?: () => {tableSchemas: DataTable[]};\n customKeywords: string[];\n customFunctions: string[];\n};\n\n// Singleton guards to prevent re-registration on every editor mount (causes flashing)\nlet sqlLanguageConfigured = false;\nlet sqlCompletionProviderDisposable: Monaco.IDisposable | null = null;\n// Per-model context store so multiple SqlMonacoEditor instances don't clobber each other.\n// WeakMap is used so entries can be GC'd in long-lived apps.\nconst sqlCompletionContextByModel = new WeakMap<object, SqlCompletionContext>();\n\nfunction ensureSqlLanguageConfigured(monaco: MonacoInstance) {\n if (sqlLanguageConfigured) return;\n sqlLanguageConfigured = true;\n\n if (!monaco.languages.getLanguages().some((lang: any) => lang.id === 'sql')) {\n monaco.languages.register({id: 'sql'});\n }\n\n // Tokenization is GLOBAL. Keep it stable for DuckDB to avoid global re-tokenization\n // when multiple SqlMonacoEditors exist (tabs/modals) which can cause flashing.\n monaco.languages.setMonarchTokensProvider('sql', {\n ...SQL_LANGUAGE_CONFIGURATION,\n keywords: DUCKDB_KEYWORDS,\n builtinFunctions: DUCKDB_FUNCTIONS,\n } as any);\n}\n\nfunction ensureSqlCompletionProvider(monaco: MonacoInstance) {\n if (sqlCompletionProviderDisposable) return;\n\n sqlCompletionProviderDisposable =\n monaco.languages.registerCompletionItemProvider('sql', {\n triggerCharacters: [' ', '.', ',', '(', '='],\n provideCompletionItems: async (model: any, position: any) => {\n try {\n const ctx = sqlCompletionContextByModel.get(model) ?? {\n connector: undefined,\n tableSchemas: [],\n getLatestSchemas: undefined,\n customKeywords: [],\n customFunctions: [],\n };\n\n // Get the latest schemas if the callback is provided\n let currentSchemas = ctx.tableSchemas;\n if (ctx.getLatestSchemas) {\n const latest = ctx.getLatestSchemas();\n currentSchemas = latest.tableSchemas;\n }\n\n const suggestions: Monaco.languages.CompletionItem[] = [];\n const word = model.getWordUntilPosition(position);\n const range = {\n startLineNumber: position.lineNumber,\n endLineNumber: position.lineNumber,\n startColumn: word.startColumn,\n endColumn: word.endColumn,\n };\n\n // Get the text before the cursor to determine context\n const lineContent = model.getLineContent(position.lineNumber);\n const textBeforeCursor = lineContent\n .substring(0, position.column - 1)\n .trim()\n .toLowerCase();\n\n // Check if we're after a FROM, JOIN, or similar clause to prioritize table suggestions\n const isTableContext = /\\b(from|join|into|update|table)\\s+\\w*$/.test(\n textBeforeCursor,\n );\n\n // Check if we're after a table name and period to prioritize column suggestions\n const isColumnContext = /\\b(\\w+)\\.\\w*$/.test(textBeforeCursor);\n\n // Combine keywords and functions with custom ones\n const keywords = [...DUCKDB_KEYWORDS, ...ctx.customKeywords];\n const functions = [...DUCKDB_FUNCTIONS, ...ctx.customFunctions];\n\n // Add keyword suggestions (if not in a specific context)\n if (!isColumnContext) {\n keywords.forEach((keyword) => {\n suggestions.push({\n label: keyword,\n kind: monaco.languages.CompletionItemKind.Keyword,\n insertText: keyword,\n range: range,\n detail: 'Keyword',\n sortText: isTableContext ? 'z' + keyword : 'a' + keyword, // Lower priority in table context\n });\n });\n }\n\n // Add function suggestions (if not in a specific context)\n if (!isColumnContext) {\n functions.forEach((func) => {\n suggestions.push({\n label: func,\n kind: monaco.languages.CompletionItemKind.Function,\n insertText: func,\n range: range,\n detail: 'Function',\n sortText: isTableContext ? 'z' + func : 'b' + func, // Lower priority in table context\n });\n });\n if (ctx.connector) {\n const functionSuggestions = await getFunctionSuggestions(\n ctx.connector,\n word.word,\n );\n for (const {name, documentation} of functionSuggestions) {\n suggestions.push({\n label: name,\n insertText: name,\n documentation: {\n value: documentation,\n isTrusted: true,\n supportHtml: true,\n },\n range: range,\n kind: monaco.languages.CompletionItemKind.Function,\n sortText: isTableContext ? 'z' + name : 'b' + name, // Lower priority in table context\n });\n }\n }\n }\n\n // Add table and column suggestions from schemas\n currentSchemas.forEach((table) => {\n const tableName = table.tableName;\n\n // Add table suggestion\n suggestions.push({\n label: tableName,\n kind: monaco.languages.CompletionItemKind.Class,\n insertText: tableName,\n range: range,\n detail: 'Table',\n documentation: {\n value: `Table: ${tableName}`,\n isTrusted: true,\n },\n sortText: isTableContext ? 'a' + tableName : 'c' + tableName, // Higher priority in table context\n });\n\n // Extract table name from context if we're in a column context\n let contextTableName = '';\n if (isColumnContext) {\n const match = textBeforeCursor.match(/\\b(\\w+)\\.\\w*$/);\n if (match && match[1]) {\n contextTableName = match[1];\n }\n }\n\n // Only add columns for the current table if we're in a column context\n if (!isColumnContext || contextTableName === tableName) {\n // Add column suggestions\n table.columns.forEach((column) => {\n const columnName = column.name;\n const columnType = column.type;\n\n suggestions.push({\n label: columnName,\n kind: monaco.languages.CompletionItemKind.Field,\n insertText: columnName,\n range: range,\n detail: `Column (${columnType})`,\n documentation: {\n value: `Column from table ${tableName}`,\n isTrusted: true,\n },\n sortText:\n isColumnContext && contextTableName === tableName\n ? 'a' + columnName\n : 'd' + columnName,\n });\n\n // Only add table.column suggestions if not in a column context\n if (!isColumnContext) {\n suggestions.push({\n label: `${tableName}.${columnName}`,\n kind: monaco.languages.CompletionItemKind.Field,\n insertText: `${tableName}.${columnName}`,\n range: range,\n detail: `Column (${columnType})`,\n documentation: {\n value: `Column from table ${tableName}`,\n isTrusted: true,\n },\n sortText: 'e' + tableName + columnName,\n });\n }\n });\n }\n });\n\n return {suggestions};\n } catch (error) {\n console.error('Error in SQL completion provider:', error);\n return {suggestions: []};\n }\n },\n });\n}\n\n/**\n * A Monaco editor for editing SQL with DuckDB syntax highlighting and autocompletion\n * This is an internal component used by SqlEditor\n */\nexport const SqlMonacoEditor: React.FC<SqlMonacoEditorProps> = ({\n connector,\n customKeywords = [],\n customFunctions = [],\n tableSchemas = [],\n getLatestSchemas,\n onMount,\n className,\n options,\n ...restProps\n}) => {\n const modelRef = useRef<any>(null);\n\n // Update per-model context when props change\n useEffect(() => {\n const model = modelRef.current;\n if (!model) return;\n sqlCompletionContextByModel.set(model, {\n connector,\n tableSchemas,\n getLatestSchemas,\n customKeywords,\n customFunctions,\n });\n }, [\n connector,\n tableSchemas,\n getLatestSchemas,\n customKeywords,\n customFunctions,\n ]);\n\n // Backstop cleanup: if the React component unmounts before Monaco disposes the model,\n // ensure we don't hold on to context longer than necessary.\n useEffect(() => {\n return () => {\n const model = modelRef.current;\n if (model) sqlCompletionContextByModel.delete(model);\n };\n }, []);\n\n // Handle editor mounting to configure SQL language features\n const handleEditorDidMount = useCallback<OnMount>(\n (editor, monaco) => {\n ensureSqlLanguageConfigured(monaco);\n ensureSqlCompletionProvider(monaco);\n\n const model = editor.getModel?.();\n if (model) {\n modelRef.current = model;\n sqlCompletionContextByModel.set(model, {\n connector,\n tableSchemas,\n getLatestSchemas,\n customKeywords,\n customFunctions,\n });\n }\n\n // Cleanup on dispose\n if (model) {\n editor.onDidDispose(() => {\n sqlCompletionContextByModel.delete(model);\n });\n }\n\n // Call the original onMount if provided\n if (onMount) {\n onMount(editor, monaco);\n }\n },\n [\n connector,\n customKeywords,\n customFunctions,\n getLatestSchemas,\n onMount,\n tableSchemas,\n ],\n );\n\n const combinedOptions = useMemo(\n (): MonacoEditorProps['options'] => ({\n ...EDITOR_OPTIONS,\n ...options,\n }),\n [options],\n );\n return (\n <MonacoEditor\n language=\"sql\"\n onMount={handleEditorDidMount}\n className={cn('h-full', className)}\n options={combinedOptions}\n {...restProps}\n />\n );\n};\n"]}
|
|
1
|
+
{"version":3,"file":"SqlMonacoEditor.js","sourceRoot":"","sources":["../src/SqlMonacoEditor.tsx"],"names":[],"mappings":"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","sourcesContent":["import type {OnMount} from '@monaco-editor/react';\nimport type {DataTable, DuckDbConnector} from '@sqlrooms/db';\nimport {getFunctionSuggestions} from '@sqlrooms/duckdb';\nimport type {MonacoEditorProps} from '@sqlrooms/monaco-editor';\nimport {MonacoEditor} from '@sqlrooms/monaco-editor';\nimport {cn} from '@sqlrooms/ui';\nimport type * as Monaco from 'monaco-editor';\nimport React, {useCallback, useEffect, useMemo, useRef} from 'react';\nimport {\n DUCKDB_FUNCTIONS,\n DUCKDB_KEYWORDS,\n SQL_LANGUAGE_CONFIGURATION,\n} from './constants/duckdb-dialect';\nimport {FunctionDocumentation} from './components/FunctionDocumentation';\nimport {renderComponentToString} from '@sqlrooms/utils';\n\nexport type SqlMonacoRunQueryOptions = {\n value: string;\n selectedValue: string;\n isSelectionEmpty: boolean;\n};\n\nexport interface SqlMonacoEditorProps extends Omit<\n MonacoEditorProps,\n 'language'\n> {\n connector?: DuckDbConnector;\n /**\n * Custom SQL keywords to add to the completion provider.\n *\n * Note: syntax highlighting is global and uses the built-in DuckDB dialect\n * (`DUCKDB_KEYWORDS` / `DUCKDB_FUNCTIONS`) to avoid per-editor global reconfiguration\n * (which can cause flashing). These are currently **completion-only**.\n */\n customKeywords?: string[];\n /**\n * Custom SQL functions to add to the completion provider.\n *\n * Note: syntax highlighting is global and uses the built-in DuckDB dialect\n * (`DUCKDB_KEYWORDS` / `DUCKDB_FUNCTIONS`) to avoid per-editor global reconfiguration\n * (which can cause flashing). These are currently **completion-only**.\n */\n customFunctions?: string[];\n /**\n * Table schemas for autocompletion\n */\n tableSchemas?: DataTable[];\n /** Callback to get the latest table schemas */\n getLatestSchemas?: () => {\n tableSchemas: DataTable[];\n };\n /** Callback when Cmd/Ctrl+Enter is pressed to run query */\n onRunQuery?: (params: SqlMonacoRunQueryOptions) => void;\n}\n\nconst EDITOR_OPTIONS: MonacoEditorProps['options'] = {\n formatOnPaste: true,\n formatOnType: true,\n wordWrap: 'on',\n scrollBeyondLastLine: false,\n scrollbar: {\n alwaysConsumeMouseWheel: false,\n },\n};\n\ntype MonacoInstance = typeof Monaco;\n\ntype SqlCompletionContext = {\n connector?: DuckDbConnector;\n tableSchemas: DataTable[];\n getLatestSchemas?: () => {tableSchemas: DataTable[]};\n customKeywords: string[];\n customFunctions: string[];\n};\n\n// Singleton guards to prevent re-registration on every editor mount (causes flashing)\nlet sqlLanguageConfigured = false;\nlet sqlCompletionProviderDisposable: Monaco.IDisposable | null = null;\n// Per-model context store so multiple SqlMonacoEditor instances don't clobber each other.\n// WeakMap is used so entries can be GC'd in long-lived apps.\nconst sqlCompletionContextByModel = new WeakMap<object, SqlCompletionContext>();\n\nfunction ensureSqlLanguageConfigured(monaco: MonacoInstance) {\n if (sqlLanguageConfigured) return;\n sqlLanguageConfigured = true;\n\n if (!monaco.languages.getLanguages().some((lang: any) => lang.id === 'sql')) {\n monaco.languages.register({id: 'sql'});\n }\n\n // Tokenization is GLOBAL. Keep it stable for DuckDB to avoid global re-tokenization\n // when multiple SqlMonacoEditors exist (tabs/modals) which can cause flashing.\n monaco.languages.setMonarchTokensProvider('sql', {\n ...SQL_LANGUAGE_CONFIGURATION,\n keywords: DUCKDB_KEYWORDS,\n builtinFunctions: DUCKDB_FUNCTIONS,\n } as any);\n}\n\nfunction ensureSqlCompletionProvider(monaco: MonacoInstance) {\n if (sqlCompletionProviderDisposable) return;\n\n sqlCompletionProviderDisposable =\n monaco.languages.registerCompletionItemProvider('sql', {\n triggerCharacters: [' ', '.', ',', '(', '='],\n provideCompletionItems: async (model: any, position: any) => {\n try {\n const ctx = sqlCompletionContextByModel.get(model) ?? {\n connector: undefined,\n tableSchemas: [],\n getLatestSchemas: undefined,\n customKeywords: [],\n customFunctions: [],\n };\n\n // Get the latest schemas if the callback is provided\n let currentSchemas = ctx.tableSchemas;\n if (ctx.getLatestSchemas) {\n const latest = ctx.getLatestSchemas();\n currentSchemas = latest.tableSchemas;\n }\n\n const suggestions: Monaco.languages.CompletionItem[] = [];\n const word = model.getWordUntilPosition(position);\n const range = {\n startLineNumber: position.lineNumber,\n endLineNumber: position.lineNumber,\n startColumn: word.startColumn,\n endColumn: word.endColumn,\n };\n\n // Get the text before the cursor to determine context\n const lineContent = model.getLineContent(position.lineNumber);\n const textBeforeCursor = lineContent\n .substring(0, position.column - 1)\n .trim()\n .toLowerCase();\n\n // Check if we're after a FROM, JOIN, or similar clause to prioritize table suggestions\n const isTableContext = /\\b(from|join|into|update|table)\\s+\\w*$/.test(\n textBeforeCursor,\n );\n\n // Check if we're after a table name and period to prioritize column suggestions\n const isColumnContext = /\\b(\\w+)\\.\\w*$/.test(textBeforeCursor);\n\n // Combine keywords and functions with custom ones\n const keywords = [...DUCKDB_KEYWORDS, ...ctx.customKeywords];\n const functions = [...DUCKDB_FUNCTIONS, ...ctx.customFunctions];\n\n // Add keyword suggestions (if not in a specific context)\n if (!isColumnContext) {\n keywords.forEach((keyword) => {\n suggestions.push({\n label: keyword,\n kind: monaco.languages.CompletionItemKind.Keyword,\n insertText: keyword,\n range: range,\n detail: 'Keyword',\n sortText: isTableContext ? 'z' + keyword : 'a' + keyword, // Lower priority in table context\n });\n });\n }\n\n // Add function suggestions (if not in a specific context)\n if (!isColumnContext) {\n functions.forEach((func) => {\n suggestions.push({\n label: func,\n kind: monaco.languages.CompletionItemKind.Function,\n insertText: func,\n range: range,\n detail: 'Function',\n sortText: isTableContext ? 'z' + func : 'b' + func, // Lower priority in table context\n });\n });\n if (ctx.connector) {\n const functionGroups = await getFunctionSuggestions(\n ctx.connector,\n word.word,\n );\n\n for (const {name, overloads} of functionGroups) {\n suggestions.push({\n label: name,\n insertText: name,\n documentation: {\n value: renderComponentToString(FunctionDocumentation, {\n functions: overloads,\n }),\n isTrusted: true,\n supportHtml: true,\n },\n range: range,\n kind: monaco.languages.CompletionItemKind.Function,\n sortText: isTableContext ? 'z' + name : 'b' + name, // Lower priority in table context\n });\n }\n }\n }\n\n // Add table and column suggestions from schemas\n currentSchemas.forEach((table) => {\n const tableName = table.tableName;\n\n // Add table suggestion\n suggestions.push({\n label: tableName,\n kind: monaco.languages.CompletionItemKind.Class,\n insertText: tableName,\n range: range,\n detail: 'Table',\n documentation: {\n value: `Table: ${tableName}`,\n isTrusted: true,\n },\n sortText: isTableContext ? 'a' + tableName : 'c' + tableName, // Higher priority in table context\n });\n\n // Extract table name from context if we're in a column context\n let contextTableName = '';\n if (isColumnContext) {\n const match = textBeforeCursor.match(/\\b(\\w+)\\.\\w*$/);\n if (match && match[1]) {\n contextTableName = match[1];\n }\n }\n\n // Only add columns for the current table if we're in a column context\n if (!isColumnContext || contextTableName === tableName) {\n // Add column suggestions\n table.columns.forEach((column) => {\n const columnName = column.name;\n const columnType = column.type;\n\n suggestions.push({\n label: columnName,\n kind: monaco.languages.CompletionItemKind.Field,\n insertText: columnName,\n range: range,\n detail: `Column (${columnType})`,\n documentation: {\n value: `Column from table ${tableName}`,\n isTrusted: true,\n },\n sortText:\n isColumnContext && contextTableName === tableName\n ? 'a' + columnName\n : 'd' + columnName,\n });\n\n // Only add table.column suggestions if not in a column context\n if (!isColumnContext) {\n suggestions.push({\n label: `${tableName}.${columnName}`,\n kind: monaco.languages.CompletionItemKind.Field,\n insertText: `${tableName}.${columnName}`,\n range: range,\n detail: `Column (${columnType})`,\n documentation: {\n value: `Column from table ${tableName}`,\n isTrusted: true,\n },\n sortText: 'e' + tableName + columnName,\n });\n }\n });\n }\n });\n\n return {suggestions};\n } catch (error) {\n console.error('Error in SQL completion provider:', error);\n return {suggestions: []};\n }\n },\n });\n}\n\n/**\n * A Monaco editor for editing SQL with DuckDB syntax highlighting and autocompletion\n * This is an internal component used by SqlEditor\n *\n * @deprecated Use SqlCodeMirrorEditor instead. This component will be removed in a future version.\n */\nexport const SqlMonacoEditor: React.FC<SqlMonacoEditorProps> = ({\n connector,\n customKeywords = [],\n customFunctions = [],\n tableSchemas = [],\n getLatestSchemas,\n onRunQuery,\n onMount,\n className,\n options,\n ...restProps\n}) => {\n const modelRef = useRef<any>(null);\n const onRunQueryRef = useRef(onRunQuery);\n\n useEffect(() => {\n onRunQueryRef.current = onRunQuery;\n }, [onRunQuery]);\n\n // Update per-model context when props change\n useEffect(() => {\n const model = modelRef.current;\n if (!model) return;\n sqlCompletionContextByModel.set(model, {\n connector,\n tableSchemas,\n getLatestSchemas,\n customKeywords,\n customFunctions,\n });\n }, [\n connector,\n tableSchemas,\n getLatestSchemas,\n customKeywords,\n customFunctions,\n ]);\n\n // Backstop cleanup: if the React component unmounts before Monaco disposes the model,\n // ensure we don't hold on to context longer than necessary.\n useEffect(() => {\n return () => {\n const model = modelRef.current;\n if (model) sqlCompletionContextByModel.delete(model);\n };\n }, []);\n\n // Handle editor mounting to configure SQL language features\n const handleEditorDidMount = useCallback<OnMount>(\n (editor, monaco) => {\n ensureSqlLanguageConfigured(monaco);\n ensureSqlCompletionProvider(monaco);\n\n const setContextForModel = (model: any) => {\n if (!model) return;\n modelRef.current = model;\n sqlCompletionContextByModel.set(model, {\n connector,\n tableSchemas,\n getLatestSchemas,\n customKeywords,\n customFunctions,\n });\n };\n\n // Initial model context\n setContextForModel(editor.getModel?.());\n\n // IMPORTANT: when callers pass `path`, @monaco-editor/react swaps the underlying\n // Monaco model without re-mounting the editor. Keep the completion context in sync\n // with the active model so suggestions remain database-aware.\n const modelChangeDisposable = editor.onDidChangeModel?.(() => {\n setContextForModel(editor.getModel?.());\n });\n\n // Add keyboard shortcut for running query\n if (onRunQuery) {\n editor.onKeyDown((e) => {\n if ((e.ctrlKey || e.metaKey) && e.keyCode === monaco.KeyCode.Enter) {\n e.preventDefault();\n e.stopPropagation();\n\n const model = editor.getModel();\n const selection = editor.getSelection();\n const value = editor.getValue();\n const selectedValue =\n model && selection ? model.getValueInRange(selection) : '';\n const isSelectionEmpty = !selection || selection.isEmpty();\n\n onRunQuery({\n value,\n selectedValue,\n isSelectionEmpty,\n });\n }\n });\n }\n\n // Cleanup on dispose\n editor.onDidDispose(() => {\n modelChangeDisposable?.dispose?.();\n const model = modelRef.current;\n if (model) sqlCompletionContextByModel.delete(model);\n });\n\n // Call the original onMount if provided\n if (onMount) {\n onMount(editor, monaco);\n }\n },\n [\n connector,\n customKeywords,\n customFunctions,\n getLatestSchemas,\n onMount,\n onRunQuery,\n tableSchemas,\n ],\n );\n\n const combinedOptions = useMemo(\n (): MonacoEditorProps['options'] => ({\n ...EDITOR_OPTIONS,\n ...options,\n }),\n [options],\n );\n return (\n <MonacoEditor\n language=\"sql\"\n onMount={handleEditorDidMount}\n className={cn('h-full', className)}\n options={combinedOptions}\n {...restProps}\n />\n );\n};\n"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Extension } from '@codemirror/state';
|
|
2
|
+
import type { GroupedFunctionSuggestion } from '@sqlrooms/db';
|
|
3
|
+
export interface CompletionContext {
|
|
4
|
+
getKeywordSuggestions?: () => string[];
|
|
5
|
+
getFunctionSuggestions?: (query: string) => Promise<GroupedFunctionSuggestion[]>;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Creates SQL completion extension with dynamic function docs and keywords.
|
|
9
|
+
* Complements marimo-sql's base SQL completions (keywords, tables, columns, CTEs).
|
|
10
|
+
*/
|
|
11
|
+
export declare function createCompletion({ getKeywordSuggestions, getFunctionSuggestions, }: CompletionContext): Extension;
|
|
12
|
+
//# sourceMappingURL=completion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"completion.d.ts","sourceRoot":"","sources":["../../../src/codemirror/extensions/completion.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,mBAAmB,CAAC;AAGjD,OAAO,KAAK,EAAC,yBAAyB,EAAC,MAAM,cAAc,CAAC;AAE5D,MAAM,WAAW,iBAAiB;IAChC,qBAAqB,CAAC,EAAE,MAAM,MAAM,EAAE,CAAC;IACvC,sBAAsB,CAAC,EAAE,CACvB,KAAK,EAAE,MAAM,KACV,OAAO,CAAC,yBAAyB,EAAE,CAAC,CAAC;CAC3C;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,qBAAqB,EACrB,sBAAsB,GACvB,EAAE,iBAAiB,GAAG,SAAS,CA2D/B"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { autocompletion, } from '@codemirror/autocomplete';
|
|
2
|
+
import { FunctionDocumentation } from '../../components/FunctionDocumentation';
|
|
3
|
+
import { renderComponentToDomElement } from '@sqlrooms/utils';
|
|
4
|
+
/**
|
|
5
|
+
* Creates SQL completion extension with dynamic function docs and keywords.
|
|
6
|
+
* Complements marimo-sql's base SQL completions (keywords, tables, columns, CTEs).
|
|
7
|
+
*/
|
|
8
|
+
export function createCompletion({ getKeywordSuggestions, getFunctionSuggestions, }) {
|
|
9
|
+
const completionSource = async (completionContext) => {
|
|
10
|
+
const suggestions = [];
|
|
11
|
+
// Get word at cursor for matching
|
|
12
|
+
const word = completionContext.matchBefore(/\w*/);
|
|
13
|
+
if (!word || (word.from === word.to && !completionContext.explicit)) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
// Add keywords
|
|
17
|
+
const keywords = getKeywordSuggestions?.() ?? [];
|
|
18
|
+
keywords.forEach((keyword) => {
|
|
19
|
+
suggestions.push({
|
|
20
|
+
label: keyword,
|
|
21
|
+
type: 'keyword',
|
|
22
|
+
boost: 5,
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
// Add dynamic function suggestions with documentation
|
|
26
|
+
if (getFunctionSuggestions && word.text) {
|
|
27
|
+
try {
|
|
28
|
+
const functionGroups = await getFunctionSuggestions(word.text);
|
|
29
|
+
suggestions.push(...functionGroups.map(({ name, overloads }) => {
|
|
30
|
+
return {
|
|
31
|
+
label: name,
|
|
32
|
+
type: 'method',
|
|
33
|
+
detail: overloads[0]?.description ?? '',
|
|
34
|
+
info: () => renderComponentToDomElement(FunctionDocumentation, {
|
|
35
|
+
functions: overloads,
|
|
36
|
+
}),
|
|
37
|
+
boost: 5,
|
|
38
|
+
};
|
|
39
|
+
}));
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
console.error('Error fetching function suggestions:', error);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return suggestions.length > 0
|
|
46
|
+
? {
|
|
47
|
+
from: word.from,
|
|
48
|
+
options: suggestions,
|
|
49
|
+
}
|
|
50
|
+
: null;
|
|
51
|
+
};
|
|
52
|
+
// Override default SQL completions with our custom completion source
|
|
53
|
+
return autocompletion({
|
|
54
|
+
override: [completionSource],
|
|
55
|
+
// Don't auto-select the first item when completion list opens
|
|
56
|
+
// This prevents the info tooltip from showing immediately
|
|
57
|
+
selectOnOpen: false,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=completion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"completion.js","sourceRoot":"","sources":["../../../src/codemirror/extensions/completion.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,cAAc,GACf,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAC,qBAAqB,EAAC,MAAM,wCAAwC,CAAC;AAC7E,OAAO,EAAC,2BAA2B,EAAC,MAAM,iBAAiB,CAAC;AAU5D;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,EAC/B,qBAAqB,EACrB,sBAAsB,GACJ;IAClB,MAAM,gBAAgB,GAAG,KAAK,EAAE,iBAAsC,EAAE,EAAE;QACxE,MAAM,WAAW,GAAiB,EAAE,CAAC;QAErC,kCAAkC;QAClC,MAAM,IAAI,GAAG,iBAAiB,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAClD,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,EAAE,CAAC;YACpE,OAAO,IAAI,CAAC;QACd,CAAC;QAED,eAAe;QACf,MAAM,QAAQ,GAAG,qBAAqB,EAAE,EAAE,IAAI,EAAE,CAAC;QACjD,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC3B,WAAW,CAAC,IAAI,CAAC;gBACf,KAAK,EAAE,OAAO;gBACd,IAAI,EAAE,SAAS;gBACf,KAAK,EAAE,CAAC;aACT,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,sDAAsD;QACtD,IAAI,sBAAsB,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACxC,IAAI,CAAC;gBACH,MAAM,cAAc,GAAG,MAAM,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAE/D,WAAW,CAAC,IAAI,CACd,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,EAAC,IAAI,EAAE,SAAS,EAAC,EAAc,EAAE;oBACtD,OAAO;wBACL,KAAK,EAAE,IAAI;wBACX,IAAI,EAAE,QAAQ;wBACd,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,IAAI,EAAE;wBACvC,IAAI,EAAE,GAAG,EAAE,CACT,2BAA2B,CAAC,qBAAqB,EAAE;4BACjD,SAAS,EAAE,SAAS;yBACrB,CAAC;wBACJ,KAAK,EAAE,CAAC;qBACT,CAAC;gBACJ,CAAC,CAAC,CACH,CAAC;YACJ,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,KAAK,CAAC,sCAAsC,EAAE,KAAK,CAAC,CAAC;YAC/D,CAAC;QACH,CAAC;QAED,OAAO,WAAW,CAAC,MAAM,GAAG,CAAC;YAC3B,CAAC,CAAC;gBACE,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,OAAO,EAAE,WAAW;aACrB;YACH,CAAC,CAAC,IAAI,CAAC;IACX,CAAC,CAAC;IAEF,qEAAqE;IACrE,OAAO,cAAc,CAAC;QACpB,QAAQ,EAAE,CAAC,gBAAgB,CAAC;QAC5B,8DAA8D;QAC9D,0DAA0D;QAC1D,YAAY,EAAE,KAAK;KACpB,CAAC,CAAC;AACL,CAAC","sourcesContent":["import {\n type CompletionContext as CMCompletionContext,\n type Completion,\n autocompletion,\n} from '@codemirror/autocomplete';\nimport type {Extension} from '@codemirror/state';\nimport {FunctionDocumentation} from '../../components/FunctionDocumentation';\nimport {renderComponentToDomElement} from '@sqlrooms/utils';\nimport type {GroupedFunctionSuggestion} from '@sqlrooms/db';\n\nexport interface CompletionContext {\n getKeywordSuggestions?: () => string[];\n getFunctionSuggestions?: (\n query: string,\n ) => Promise<GroupedFunctionSuggestion[]>;\n}\n\n/**\n * Creates SQL completion extension with dynamic function docs and keywords.\n * Complements marimo-sql's base SQL completions (keywords, tables, columns, CTEs).\n */\nexport function createCompletion({\n getKeywordSuggestions,\n getFunctionSuggestions,\n}: CompletionContext): Extension {\n const completionSource = async (completionContext: CMCompletionContext) => {\n const suggestions: Completion[] = [];\n\n // Get word at cursor for matching\n const word = completionContext.matchBefore(/\\w*/);\n if (!word || (word.from === word.to && !completionContext.explicit)) {\n return null;\n }\n\n // Add keywords\n const keywords = getKeywordSuggestions?.() ?? [];\n keywords.forEach((keyword) => {\n suggestions.push({\n label: keyword,\n type: 'keyword',\n boost: 5,\n });\n });\n\n // Add dynamic function suggestions with documentation\n if (getFunctionSuggestions && word.text) {\n try {\n const functionGroups = await getFunctionSuggestions(word.text);\n\n suggestions.push(\n ...functionGroups.map(({name, overloads}): Completion => {\n return {\n label: name,\n type: 'method',\n detail: overloads[0]?.description ?? '',\n info: () =>\n renderComponentToDomElement(FunctionDocumentation, {\n functions: overloads,\n }),\n boost: 5,\n };\n }),\n );\n } catch (error) {\n console.error('Error fetching function suggestions:', error);\n }\n }\n\n return suggestions.length > 0\n ? {\n from: word.from,\n options: suggestions,\n }\n : null;\n };\n\n // Override default SQL completions with our custom completion source\n return autocompletion({\n override: [completionSource],\n // Don't auto-select the first item when completion list opens\n // This prevents the info tooltip from showing immediately\n selectOnOpen: false,\n });\n}\n"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Extension } from '@codemirror/state';
|
|
2
|
+
import type { DataTable, DuckDbConnector } from '@sqlrooms/duckdb';
|
|
3
|
+
export declare const SqlDialects: {
|
|
4
|
+
readonly DuckDb: "duck-db";
|
|
5
|
+
};
|
|
6
|
+
export type SqlDialect = (typeof SqlDialects)[keyof typeof SqlDialects];
|
|
7
|
+
export type SqlExtensionOptions = {
|
|
8
|
+
dialect: SqlDialect;
|
|
9
|
+
currentSchemas: DataTable[];
|
|
10
|
+
connector?: DuckDbConnector;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Creates SQL extensions for the specified dialect.
|
|
14
|
+
* Routes to dialect-specific extension creators.
|
|
15
|
+
*/
|
|
16
|
+
export declare function createSqlExtension({ dialect, currentSchemas, connector, }: SqlExtensionOptions): Extension[];
|
|
17
|
+
//# sourceMappingURL=create-sql-extension.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-sql-extension.d.ts","sourceRoot":"","sources":["../../../src/codemirror/extensions/create-sql-extension.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,EAAC,SAAS,EAAE,eAAe,EAAC,MAAM,kBAAkB,CAAC;AAGjE,eAAO,MAAM,WAAW;;CAEd,CAAC;AAEX,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,OAAO,WAAW,CAAC,CAAC;AAExE,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,UAAU,CAAC;IACpB,cAAc,EAAE,SAAS,EAAE,CAAC;IAC5B,SAAS,CAAC,EAAE,eAAe,CAAC;CAC7B,CAAC;AAEF;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,OAAO,EACP,cAAc,EACd,SAAS,GACV,EAAE,mBAAmB,GAAG,SAAS,EAAE,CAUnC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { createDuckDbExtension } from './duck-db';
|
|
2
|
+
export const SqlDialects = {
|
|
3
|
+
DuckDb: 'duck-db',
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* Creates SQL extensions for the specified dialect.
|
|
7
|
+
* Routes to dialect-specific extension creators.
|
|
8
|
+
*/
|
|
9
|
+
export function createSqlExtension({ dialect, currentSchemas, connector, }) {
|
|
10
|
+
switch (dialect) {
|
|
11
|
+
case SqlDialects.DuckDb:
|
|
12
|
+
return createDuckDbExtension({
|
|
13
|
+
currentSchemas,
|
|
14
|
+
connector,
|
|
15
|
+
});
|
|
16
|
+
default:
|
|
17
|
+
throw new Error(`Unsupported SQL dialect: ${dialect}`);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=create-sql-extension.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-sql-extension.js","sourceRoot":"","sources":["../../../src/codemirror/extensions/create-sql-extension.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,qBAAqB,EAAC,MAAM,WAAW,CAAC;AAEhD,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,MAAM,EAAE,SAAS;CACT,CAAC;AAUX;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,EACjC,OAAO,EACP,cAAc,EACd,SAAS,GACW;IACpB,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,WAAW,CAAC,MAAM;YACrB,OAAO,qBAAqB,CAAC;gBAC3B,cAAc;gBACd,SAAS;aACV,CAAC,CAAC;QACL;YACE,MAAM,IAAI,KAAK,CAAC,4BAA4B,OAAO,EAAE,CAAC,CAAC;IAC3D,CAAC;AACH,CAAC","sourcesContent":["import type {Extension} from '@codemirror/state';\nimport type {DataTable, DuckDbConnector} from '@sqlrooms/duckdb';\nimport {createDuckDbExtension} from './duck-db';\n\nexport const SqlDialects = {\n DuckDb: 'duck-db',\n} as const;\n\nexport type SqlDialect = (typeof SqlDialects)[keyof typeof SqlDialects];\n\nexport type SqlExtensionOptions = {\n dialect: SqlDialect;\n currentSchemas: DataTable[];\n connector?: DuckDbConnector; // TODO: change to generic connector\n};\n\n/**\n * Creates SQL extensions for the specified dialect.\n * Routes to dialect-specific extension creators.\n */\nexport function createSqlExtension({\n dialect,\n currentSchemas,\n connector,\n}: SqlExtensionOptions): Extension[] {\n switch (dialect) {\n case SqlDialects.DuckDb:\n return createDuckDbExtension({\n currentSchemas,\n connector,\n });\n default:\n throw new Error(`Unsupported SQL dialect: ${dialect}`);\n }\n}\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Extension } from '@codemirror/state';
|
|
2
|
+
import { DataTable, DuckDbConnector } from '@sqlrooms/duckdb';
|
|
3
|
+
type DuckDbExtensionOptions = {
|
|
4
|
+
currentSchemas: DataTable[];
|
|
5
|
+
connector?: DuckDbConnector;
|
|
6
|
+
};
|
|
7
|
+
export declare function createDuckDbExtension({ currentSchemas, connector, }: DuckDbExtensionOptions): Extension[];
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=duck-db.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"duck-db.d.ts","sourceRoot":"","sources":["../../../../src/codemirror/extensions/duck-db/duck-db.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,mBAAmB,CAAC;AACjD,OAAO,EACL,SAAS,EACT,eAAe,EAGhB,MAAM,kBAAkB,CAAC;AAQ1B,KAAK,sBAAsB,GAAG;IAC5B,cAAc,EAAE,SAAS,EAAE,CAAC;IAC5B,SAAS,CAAC,EAAE,eAAe,CAAC;CAC7B,CAAC;AAEF,wBAAgB,qBAAqB,CAAC,EACpC,cAAc,EACd,SAAS,GACV,EAAE,sBAAsB,GAAG,SAAS,EAAE,CAoBtC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { getFunctionSuggestions, getFunctionDocumentation, } from '@sqlrooms/duckdb';
|
|
2
|
+
import { createDuckDbSql } from './duckdb-sql';
|
|
3
|
+
import { convertToSQLNamespace } from '../../utils/schema-converter';
|
|
4
|
+
import { createCompletion } from '../completion';
|
|
5
|
+
import { createDuckDbSqlExtension } from './duckdb-sql-extension';
|
|
6
|
+
import { createHover } from '../hover';
|
|
7
|
+
import { DUCKDB_SQL_KEYWORDS } from './duckdb-keywords';
|
|
8
|
+
export function createDuckDbExtension({ currentSchemas, connector, }) {
|
|
9
|
+
// Convert schema to SQLNamespace format
|
|
10
|
+
const schema = convertToSQLNamespace(currentSchemas);
|
|
11
|
+
return [
|
|
12
|
+
createDuckDbSql(schema),
|
|
13
|
+
createCompletion({
|
|
14
|
+
getKeywordSuggestions: () => DUCKDB_SQL_KEYWORDS,
|
|
15
|
+
getFunctionSuggestions: connector
|
|
16
|
+
? (query) => getFunctionSuggestions(connector, query)
|
|
17
|
+
: undefined,
|
|
18
|
+
}),
|
|
19
|
+
createDuckDbSqlExtension(schema, currentSchemas),
|
|
20
|
+
createHover({
|
|
21
|
+
getFunctionDocumentation: connector
|
|
22
|
+
? (functionName) => getFunctionDocumentation(connector, functionName)
|
|
23
|
+
: undefined,
|
|
24
|
+
}),
|
|
25
|
+
];
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=duck-db.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"duck-db.js","sourceRoot":"","sources":["../../../../src/codemirror/extensions/duck-db/duck-db.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAC,eAAe,EAAC,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAC,qBAAqB,EAAC,MAAM,8BAA8B,CAAC;AACnE,OAAO,EAAC,gBAAgB,EAAC,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAC,wBAAwB,EAAC,MAAM,wBAAwB,CAAC;AAChE,OAAO,EAAC,WAAW,EAAC,MAAM,UAAU,CAAC;AACrC,OAAO,EAAC,mBAAmB,EAAC,MAAM,mBAAmB,CAAC;AAOtD,MAAM,UAAU,qBAAqB,CAAC,EACpC,cAAc,EACd,SAAS,GACc;IACvB,wCAAwC;IACxC,MAAM,MAAM,GAAG,qBAAqB,CAAC,cAAc,CAAC,CAAC;IAErD,OAAO;QACL,eAAe,CAAC,MAAM,CAAC;QACvB,gBAAgB,CAAC;YACf,qBAAqB,EAAE,GAAG,EAAE,CAAC,mBAAmB;YAChD,sBAAsB,EAAE,SAAS;gBAC/B,CAAC,CAAC,CAAC,KAAa,EAAE,EAAE,CAAC,sBAAsB,CAAC,SAAS,EAAE,KAAK,CAAC;gBAC7D,CAAC,CAAC,SAAS;SACd,CAAC;QACF,wBAAwB,CAAC,MAAM,EAAE,cAAc,CAAC;QAChD,WAAW,CAAC;YACV,wBAAwB,EAAE,SAAS;gBACjC,CAAC,CAAC,CAAC,YAAoB,EAAE,EAAE,CACvB,wBAAwB,CAAC,SAAS,EAAE,YAAY,CAAC;gBACrD,CAAC,CAAC,SAAS;SACd,CAAC;KACH,CAAC;AACJ,CAAC","sourcesContent":["import type {Extension} from '@codemirror/state';\nimport {\n DataTable,\n DuckDbConnector,\n getFunctionSuggestions,\n getFunctionDocumentation,\n} from '@sqlrooms/duckdb';\nimport {createDuckDbSql} from './duckdb-sql';\nimport {convertToSQLNamespace} from '../../utils/schema-converter';\nimport {createCompletion} from '../completion';\nimport {createDuckDbSqlExtension} from './duckdb-sql-extension';\nimport {createHover} from '../hover';\nimport {DUCKDB_SQL_KEYWORDS} from './duckdb-keywords';\n\ntype DuckDbExtensionOptions = {\n currentSchemas: DataTable[];\n connector?: DuckDbConnector;\n};\n\nexport function createDuckDbExtension({\n currentSchemas,\n connector,\n}: DuckDbExtensionOptions): Extension[] {\n // Convert schema to SQLNamespace format\n const schema = convertToSQLNamespace(currentSchemas);\n\n return [\n createDuckDbSql(schema),\n createCompletion({\n getKeywordSuggestions: () => DUCKDB_SQL_KEYWORDS,\n getFunctionSuggestions: connector\n ? (query: string) => getFunctionSuggestions(connector, query)\n : undefined,\n }),\n createDuckDbSqlExtension(schema, currentSchemas),\n createHover({\n getFunctionDocumentation: connector\n ? (functionName: string) =>\n getFunctionDocumentation(connector, functionName)\n : undefined,\n }),\n ];\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"duckdb-keywords.d.ts","sourceRoot":"","sources":["../../../../src/codemirror/extensions/duck-db/duckdb-keywords.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,mBAAmB,UAqe/B,CAAC"}
|