@sqlrooms/sql-editor 0.29.0-rc.0 → 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.
Files changed (99) hide show
  1. package/README.md +13 -3
  2. package/dist/SqlCodeMirrorEditor.d.ts +29 -0
  3. package/dist/SqlCodeMirrorEditor.d.ts.map +1 -0
  4. package/dist/SqlCodeMirrorEditor.js +54 -0
  5. package/dist/SqlCodeMirrorEditor.js.map +1 -0
  6. package/dist/SqlMonacoEditor.d.ts +10 -4
  7. package/dist/SqlMonacoEditor.d.ts.map +1 -1
  8. package/dist/SqlMonacoEditor.js +51 -11
  9. package/dist/SqlMonacoEditor.js.map +1 -1
  10. package/dist/codemirror/extensions/completion.d.ts +12 -0
  11. package/dist/codemirror/extensions/completion.d.ts.map +1 -0
  12. package/dist/codemirror/extensions/completion.js +60 -0
  13. package/dist/codemirror/extensions/completion.js.map +1 -0
  14. package/dist/codemirror/extensions/create-sql-extension.d.ts +17 -0
  15. package/dist/codemirror/extensions/create-sql-extension.d.ts.map +1 -0
  16. package/dist/codemirror/extensions/create-sql-extension.js +20 -0
  17. package/dist/codemirror/extensions/create-sql-extension.js.map +1 -0
  18. package/dist/codemirror/extensions/duck-db/duck-db.d.ts +9 -0
  19. package/dist/codemirror/extensions/duck-db/duck-db.d.ts.map +1 -0
  20. package/dist/codemirror/extensions/duck-db/duck-db.js +27 -0
  21. package/dist/codemirror/extensions/duck-db/duck-db.js.map +1 -0
  22. package/dist/codemirror/extensions/duck-db/duckdb-keywords.d.ts +2 -0
  23. package/dist/codemirror/extensions/duck-db/duckdb-keywords.d.ts.map +1 -0
  24. package/dist/codemirror/extensions/duck-db/duckdb-keywords.js +487 -0
  25. package/dist/codemirror/extensions/duck-db/duckdb-keywords.js.map +1 -0
  26. package/dist/codemirror/extensions/duck-db/duckdb-sql-extension.d.ts +5 -0
  27. package/dist/codemirror/extensions/duck-db/duckdb-sql-extension.d.ts.map +1 -0
  28. package/dist/codemirror/extensions/duck-db/duckdb-sql-extension.js +36 -0
  29. package/dist/codemirror/extensions/duck-db/duckdb-sql-extension.js.map +1 -0
  30. package/dist/codemirror/extensions/duck-db/duckdb-sql.d.ts +5 -0
  31. package/dist/codemirror/extensions/duck-db/duckdb-sql.d.ts.map +1 -0
  32. package/dist/codemirror/extensions/duck-db/duckdb-sql.js +11 -0
  33. package/dist/codemirror/extensions/duck-db/duckdb-sql.js.map +1 -0
  34. package/dist/codemirror/extensions/duck-db/index.d.ts +2 -0
  35. package/dist/codemirror/extensions/duck-db/index.d.ts.map +1 -0
  36. package/dist/codemirror/extensions/duck-db/index.js +2 -0
  37. package/dist/codemirror/extensions/duck-db/index.js.map +1 -0
  38. package/dist/codemirror/extensions/hover.d.ts +11 -0
  39. package/dist/codemirror/extensions/hover.d.ts.map +1 -0
  40. package/dist/codemirror/extensions/hover.js +55 -0
  41. package/dist/codemirror/extensions/hover.js.map +1 -0
  42. package/dist/codemirror/extensions/sql-keymap.d.ts +4 -0
  43. package/dist/codemirror/extensions/sql-keymap.d.ts.map +1 -0
  44. package/dist/codemirror/extensions/sql-keymap.js +25 -0
  45. package/dist/codemirror/extensions/sql-keymap.js.map +1 -0
  46. package/dist/codemirror/themes/sql-theme.d.ts +7 -0
  47. package/dist/codemirror/themes/sql-theme.d.ts.map +1 -0
  48. package/dist/codemirror/themes/sql-theme.js +55 -0
  49. package/dist/codemirror/themes/sql-theme.js.map +1 -0
  50. package/dist/codemirror/themes/sql-tooltip-theme.d.ts +7 -0
  51. package/dist/codemirror/themes/sql-tooltip-theme.d.ts.map +1 -0
  52. package/dist/codemirror/themes/sql-tooltip-theme.js +21 -0
  53. package/dist/codemirror/themes/sql-tooltip-theme.js.map +1 -0
  54. package/dist/codemirror/utils/schema-converter.d.ts +5 -0
  55. package/dist/codemirror/utils/schema-converter.d.ts.map +1 -0
  56. package/dist/codemirror/utils/schema-converter.js +9 -0
  57. package/dist/codemirror/utils/schema-converter.js.map +1 -0
  58. package/dist/components/CreateTableModal.d.ts.map +1 -1
  59. package/dist/components/CreateTableModal.js +5 -11
  60. package/dist/components/CreateTableModal.js.map +1 -1
  61. package/dist/components/FunctionDocumentation.d.ts +7 -0
  62. package/dist/components/FunctionDocumentation.d.ts.map +1 -0
  63. package/dist/components/FunctionDocumentation.js +44 -0
  64. package/dist/components/FunctionDocumentation.js.map +1 -0
  65. package/dist/components/QueryEditorPanelActions.d.ts.map +1 -1
  66. package/dist/components/QueryEditorPanelActions.js +3 -37
  67. package/dist/components/QueryEditorPanelActions.js.map +1 -1
  68. package/dist/components/QueryEditorPanelEditor.d.ts.map +1 -1
  69. package/dist/components/QueryEditorPanelEditor.js +11 -34
  70. package/dist/components/QueryEditorPanelEditor.js.map +1 -1
  71. package/dist/components/SchemaExplorer.d.ts +25 -0
  72. package/dist/components/SchemaExplorer.d.ts.map +1 -0
  73. package/dist/components/SchemaExplorer.js +20 -0
  74. package/dist/components/SchemaExplorer.js.map +1 -0
  75. package/dist/components/SqlColumnTooltip.d.ts +12 -0
  76. package/dist/components/SqlColumnTooltip.d.ts.map +1 -0
  77. package/dist/components/SqlColumnTooltip.js +15 -0
  78. package/dist/components/SqlColumnTooltip.js.map +1 -0
  79. package/dist/components/SqlColumnsTable.d.ts +10 -0
  80. package/dist/components/SqlColumnsTable.d.ts.map +1 -0
  81. package/dist/components/SqlColumnsTable.js +10 -0
  82. package/dist/components/SqlColumnsTable.js.map +1 -0
  83. package/dist/components/SqlTableTooltip.d.ts +9 -0
  84. package/dist/components/SqlTableTooltip.d.ts.map +1 -0
  85. package/dist/components/SqlTableTooltip.js +13 -0
  86. package/dist/components/SqlTableTooltip.js.map +1 -0
  87. package/dist/components/TableStructurePanel.d.ts +6 -3
  88. package/dist/components/TableStructurePanel.d.ts.map +1 -1
  89. package/dist/components/TableStructurePanel.js +8 -7
  90. package/dist/components/TableStructurePanel.js.map +1 -1
  91. package/dist/index.d.ts +21 -1
  92. package/dist/index.d.ts.map +1 -1
  93. package/dist/index.js +10 -0
  94. package/dist/index.js.map +1 -1
  95. package/dist/utils/qualified-name-parser.d.ts +41 -0
  96. package/dist/utils/qualified-name-parser.d.ts.map +1 -0
  97. package/dist/utils/qualified-name-parser.js +126 -0
  98. package/dist/utils/qualified-name-parser.js.map +1 -0
  99. 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((state) => state.sqlEditor.parseAndRunQuery);
83
- const createQueryTab = useRoomStore((state) => state.sqlEditor.createQueryTab);
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 <SqlMonacoEditor value={sql} onChange={(v) => setSql(v ?? '')} height="320px" />;
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;AAC7D,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,yBAAyB,CAAC;AAI/D,OAAO,KAAgD,MAAM,OAAO,CAAC;AAOrE,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;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM;QACvB,YAAY,EAAE,SAAS,EAAE,CAAC;KAC3B,CAAC;CACH;AA+ND;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAiG1D,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"}
@@ -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 { getFunctionSuggestions } from './constants/functionSuggestions';
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 functionSuggestions = await getFunctionSuggestions(ctx.connector, word.word);
106
- for (const { name, documentation } of functionSuggestions) {
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: documentation,
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 model = editor.getModel?.();
232
- if (model) {
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
- if (model) {
244
- editor.onDidDispose(() => {
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,2 @@
1
+ export declare const DUCKDB_SQL_KEYWORDS: string[];
2
+ //# sourceMappingURL=duckdb-keywords.d.ts.map
@@ -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"}