@sqlrooms/sql-editor 0.6.0 → 0.8.0

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 (58) hide show
  1. package/README.md +409 -0
  2. package/dist/CreateTableModal.d.ts.map +1 -1
  3. package/dist/CreateTableModal.js +10 -4
  4. package/dist/CreateTableModal.js.map +1 -1
  5. package/dist/SqlEditor.d.ts +1 -14
  6. package/dist/SqlEditor.d.ts.map +1 -1
  7. package/dist/SqlEditor.js +111 -183
  8. package/dist/SqlEditor.js.map +1 -1
  9. package/dist/SqlEditorModal.d.ts.map +1 -1
  10. package/dist/SqlEditorModal.js +8 -4
  11. package/dist/SqlEditorModal.js.map +1 -1
  12. package/dist/SqlEditorSlice.d.ts +102 -5
  13. package/dist/SqlEditorSlice.d.ts.map +1 -1
  14. package/dist/SqlEditorSlice.js +107 -30
  15. package/dist/SqlEditorSlice.js.map +1 -1
  16. package/dist/SqlMonacoEditor.d.ts +30 -0
  17. package/dist/SqlMonacoEditor.d.ts.map +1 -0
  18. package/dist/SqlMonacoEditor.js +205 -0
  19. package/dist/SqlMonacoEditor.js.map +1 -0
  20. package/dist/SqlQueryDataSourcesPanel.js +2 -3
  21. package/dist/SqlQueryDataSourcesPanel.js.map +1 -1
  22. package/dist/components/internal/SqlMonacoEditor.d.ts +36 -0
  23. package/dist/components/internal/SqlMonacoEditor.d.ts.map +1 -0
  24. package/dist/components/internal/SqlMonacoEditor.js +219 -0
  25. package/dist/components/internal/SqlMonacoEditor.js.map +1 -0
  26. package/dist/constants/duckdb-dialect.d.ts +73 -0
  27. package/dist/constants/duckdb-dialect.d.ts.map +1 -0
  28. package/dist/constants/duckdb-dialect.js +392 -0
  29. package/dist/constants/duckdb-dialect.js.map +1 -0
  30. package/dist/constants/duckdb.d.ts +73 -0
  31. package/dist/constants/duckdb.d.ts.map +1 -0
  32. package/dist/constants/duckdb.js +392 -0
  33. package/dist/constants/duckdb.js.map +1 -0
  34. package/dist/hooks/index.d.ts +5 -0
  35. package/dist/hooks/index.d.ts.map +1 -0
  36. package/dist/hooks/index.js +5 -0
  37. package/dist/hooks/index.js.map +1 -0
  38. package/dist/hooks/useMonacoEditor.d.ts +13 -0
  39. package/dist/hooks/useMonacoEditor.d.ts.map +1 -0
  40. package/dist/hooks/useMonacoEditor.js +78 -0
  41. package/dist/hooks/useMonacoEditor.js.map +1 -0
  42. package/dist/hooks/useQueryExecution.d.ts +17 -0
  43. package/dist/hooks/useQueryExecution.d.ts.map +1 -0
  44. package/dist/hooks/useQueryExecution.js +61 -0
  45. package/dist/hooks/useQueryExecution.js.map +1 -0
  46. package/dist/hooks/useQueryTabManagement.d.ts +41 -0
  47. package/dist/hooks/useQueryTabManagement.d.ts.map +1 -0
  48. package/dist/hooks/useQueryTabManagement.js +95 -0
  49. package/dist/hooks/useQueryTabManagement.js.map +1 -0
  50. package/dist/hooks/useTableManagement.d.ts +14 -0
  51. package/dist/hooks/useTableManagement.d.ts.map +1 -0
  52. package/dist/hooks/useTableManagement.js +46 -0
  53. package/dist/hooks/useTableManagement.js.map +1 -0
  54. package/dist/index.d.ts +6 -2
  55. package/dist/index.d.ts.map +1 -1
  56. package/dist/index.js +6 -2
  57. package/dist/index.js.map +1 -1
  58. package/package.json +12 -9
@@ -1 +1 @@
1
- {"version":3,"file":"SqlQueryDataSourcesPanel.js","sourceRoot":"","sources":["../src/SqlQueryDataSourcesPanel.tsx"],"names":[],"mappings":"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","sourcesContent":["import {DataSourceStatus, useBaseProjectStore} from '@sqlrooms/project-builder';\nimport {SqlQueryDataSource} from '@sqlrooms/project-config';\nimport {\n Button,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@sqlrooms/ui';\nimport {\n EllipsisIcon,\n FileIcon,\n PencilIcon,\n PlusIcon,\n RefreshCcwIcon,\n XIcon,\n} from 'lucide-react';\nimport {FC, useCallback, useState} from 'react';\nimport CreateTableModal from './CreateTableModal';\nimport {useStoreWithSqlEditor} from './SqlEditorSlice';\n\nconst SqlQueryDataSourcesPanel: FC<{\n queryDataSources: SqlQueryDataSource[];\n}> = (props) => {\n const {queryDataSources} = props;\n const [selectedDataSource, setSelectedDataSource] =\n useState<SqlQueryDataSource>();\n const [isOpen, setIsOpen] = useState(false);\n const dataSourceStates = useBaseProjectStore(\n (state) => state.project.dataSourceStates,\n );\n const removeSqlQueryDataSource = useBaseProjectStore(\n (state) => state.project.removeSqlQueryDataSource,\n );\n\n const handleEdit = useCallback((dataSource: SqlQueryDataSource) => {\n setSelectedDataSource(dataSource);\n setIsOpen(true);\n }, []);\n\n const handleClose = useCallback(() => {\n setIsOpen(false);\n setSelectedDataSource(undefined);\n }, []);\n\n const handleRemove = useCallback(\n (dataSource: SqlQueryDataSource) => {\n const {tableName} = dataSource;\n removeSqlQueryDataSource(tableName);\n },\n [removeSqlQueryDataSource],\n );\n\n const addOrUpdateSqlQuery = useStoreWithSqlEditor(\n (state) => state.sqlEditor.addOrUpdateSqlQuery,\n );\n\n const isReadOnly = useBaseProjectStore((state) => state.project.isReadOnly);\n\n return (\n <div className=\"flex flex-col overflow-auto flex-grow\">\n <div className=\"flex flex-col items-stretch\">\n <Button\n variant=\"secondary\"\n size=\"sm\"\n onClick={() => setIsOpen(true)}\n disabled={isReadOnly}\n >\n <PlusIcon className=\"mr-2 h-4 w-4\" />\n Add\n </Button>\n </div>\n <CreateTableModal\n isOpen={isOpen}\n onClose={handleClose}\n editDataSource={selectedDataSource}\n query=\"\"\n onAddOrUpdateSqlQuery={addOrUpdateSqlQuery}\n />\n\n <div className=\"flex flex-col overflow-auto flex-grow\">\n {queryDataSources.map((dataSource) => (\n <div key={dataSource.tableName} className=\"p-2 flex flex-col gap-1\">\n <div className=\"flex gap-1 cursor-pointer flex-row items-center\">\n <div className=\"flex-none w-[15px]\">\n <FileIcon className=\"w-[15px]\" />\n </div>\n <div className=\"flex-1 overflow-hidden text-ellipsis\">\n <span className=\"text-xs break-words\">\n {dataSource.tableName}\n </span>\n </div>\n <div className=\"flex-none\">\n {!isReadOnly ? (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n size=\"icon\"\n variant=\"ghost\"\n className=\"h-6 w-6 text-muted-foreground\"\n >\n <EllipsisIcon className=\"h-5 w-5\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem onClick={() => handleEdit(dataSource)}>\n <PencilIcon className=\"mr-2 h-4 w-4\" />\n Edit\n </DropdownMenuItem>\n <DropdownMenuItem disabled>\n <RefreshCcwIcon className=\"mr-2 h-4 w-4\" />\n Refresh\n </DropdownMenuItem>\n <DropdownMenuItem\n onClick={() => handleRemove(dataSource)}\n >\n <XIcon className=\"mr-2 h-4 w-4\" />\n Remove from project\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n ) : null}\n </div>\n </div>\n <div className=\"flex flex-row gap-1 items-center\">\n {dataSourceStates[dataSource.tableName]?.status ===\n DataSourceStatus.ERROR ? (\n <div className=\"flex-1 bg-destructive/15 text-destructive text-xs p-1 rounded\">\n {dataSourceStates[dataSource.tableName]?.message}\n </div>\n ) : dataSourceStates[dataSource.tableName]?.status ===\n DataSourceStatus.FETCHING ? (\n <div className=\"w-full bg-secondary h-1 rounded overflow-hidden\">\n <div className=\"h-full bg-primary animate-pulse\" />\n </div>\n ) : null}\n </div>\n </div>\n ))}\n </div>\n </div>\n );\n};\n\nexport {SqlQueryDataSourcesPanel};\n"]}
1
+ {"version":3,"file":"SqlQueryDataSourcesPanel.js","sourceRoot":"","sources":["../src/SqlQueryDataSourcesPanel.tsx"],"names":[],"mappings":"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","sourcesContent":["import {DataSourceStatus, useBaseProjectStore} from '@sqlrooms/project-builder';\nimport {SqlQueryDataSource} from '@sqlrooms/project-config';\nimport {\n Button,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@sqlrooms/ui';\nimport {\n EllipsisIcon,\n FileIcon,\n PencilIcon,\n PlusIcon,\n RefreshCcwIcon,\n XIcon,\n} from 'lucide-react';\nimport {FC, useCallback, useState} from 'react';\nimport CreateTableModal from './CreateTableModal';\nimport {useStoreWithSqlEditor} from './SqlEditorSlice';\n\nconst SqlQueryDataSourcesPanel: FC<{\n queryDataSources: SqlQueryDataSource[];\n}> = (props) => {\n const {queryDataSources} = props;\n const [selectedDataSource, setSelectedDataSource] =\n useState<SqlQueryDataSource>();\n const [isOpen, setIsOpen] = useState(false);\n const dataSourceStates = useBaseProjectStore(\n (state) => state.project.dataSourceStates,\n );\n const removeSqlQueryDataSource = useBaseProjectStore(\n (state) => state.project.removeSqlQueryDataSource,\n );\n\n const handleEdit = useCallback((dataSource: SqlQueryDataSource) => {\n setSelectedDataSource(dataSource);\n setIsOpen(true);\n }, []);\n\n const handleClose = useCallback(() => {\n setIsOpen(false);\n setSelectedDataSource(undefined);\n }, []);\n\n const handleRemove = useCallback(\n (dataSource: SqlQueryDataSource) => {\n const {tableName} = dataSource;\n removeSqlQueryDataSource(tableName);\n },\n [removeSqlQueryDataSource],\n );\n\n const addOrUpdateSqlQueryDataSource = useBaseProjectStore(\n (state) => state.project.addOrUpdateSqlQueryDataSource,\n );\n\n const isReadOnly = useBaseProjectStore((state) => state.project.isReadOnly);\n\n return (\n <div className=\"flex flex-col overflow-auto flex-grow\">\n <div className=\"flex flex-col items-stretch\">\n <Button\n variant=\"secondary\"\n size=\"sm\"\n onClick={() => setIsOpen(true)}\n disabled={isReadOnly}\n >\n <PlusIcon className=\"mr-2 h-4 w-4\" />\n Add\n </Button>\n </div>\n <CreateTableModal\n isOpen={isOpen}\n onClose={handleClose}\n editDataSource={selectedDataSource}\n query=\"\"\n onAddOrUpdateSqlQuery={addOrUpdateSqlQueryDataSource}\n />\n\n <div className=\"flex flex-col overflow-auto flex-grow\">\n {queryDataSources.map((dataSource) => (\n <div key={dataSource.tableName} className=\"p-2 flex flex-col gap-1\">\n <div className=\"flex gap-1 cursor-pointer flex-row items-center\">\n <div className=\"flex-none w-[15px]\">\n <FileIcon className=\"w-[15px]\" />\n </div>\n <div className=\"flex-1 overflow-hidden text-ellipsis\">\n <span className=\"text-xs break-words\">\n {dataSource.tableName}\n </span>\n </div>\n <div className=\"flex-none\">\n {!isReadOnly ? (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n size=\"icon\"\n variant=\"ghost\"\n className=\"h-6 w-6 text-muted-foreground\"\n >\n <EllipsisIcon className=\"h-5 w-5\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem onClick={() => handleEdit(dataSource)}>\n <PencilIcon className=\"mr-2 h-4 w-4\" />\n Edit\n </DropdownMenuItem>\n <DropdownMenuItem disabled>\n <RefreshCcwIcon className=\"mr-2 h-4 w-4\" />\n Refresh\n </DropdownMenuItem>\n <DropdownMenuItem\n onClick={() => handleRemove(dataSource)}\n >\n <XIcon className=\"mr-2 h-4 w-4\" />\n Remove from project\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n ) : null}\n </div>\n </div>\n <div className=\"flex flex-row gap-1 items-center\">\n {dataSourceStates[dataSource.tableName]?.status ===\n DataSourceStatus.ERROR ? (\n <div className=\"flex-1 bg-destructive/15 text-destructive text-xs p-1 rounded\">\n {dataSourceStates[dataSource.tableName]?.message}\n </div>\n ) : dataSourceStates[dataSource.tableName]?.status ===\n DataSourceStatus.FETCHING ? (\n <div className=\"w-full bg-secondary h-1 rounded overflow-hidden\">\n <div className=\"h-full bg-primary animate-pulse\" />\n </div>\n ) : null}\n </div>\n </div>\n ))}\n </div>\n </div>\n );\n};\n\nexport {SqlQueryDataSourcesPanel};\n"]}
@@ -0,0 +1,36 @@
1
+ import React from 'react';
2
+ import type { MonacoEditorProps } from '@sqlrooms/monaco-editor';
3
+ export interface SqlMonacoEditorProps extends Omit<MonacoEditorProps, 'language'> {
4
+ /**
5
+ * Custom SQL keywords to add to the completion provider
6
+ */
7
+ customKeywords?: string[];
8
+ /**
9
+ * Custom SQL functions to add to the completion provider
10
+ */
11
+ customFunctions?: string[];
12
+ /**
13
+ * Table schemas for autocompletion
14
+ * Format: { tableName: { columnName: columnType, ... }, ... }
15
+ */
16
+ tableSchemas?: Record<string, Record<string, string>>;
17
+ /**
18
+ * Sample data for tables to enhance autocompletion
19
+ * Format: { tableName: [sampleDescription1, sampleDescription2, ...], ... }
20
+ */
21
+ tableSamples?: Record<string, string[]>;
22
+ /**
23
+ * Callback to get the latest table schemas and samples
24
+ * This is called from within provideCompletionItems to ensure we have the latest data
25
+ */
26
+ getLatestSchemas?: () => {
27
+ tableSchemas: Record<string, Record<string, string>>;
28
+ tableSamples: Record<string, string[]>;
29
+ };
30
+ }
31
+ /**
32
+ * A Monaco editor for editing SQL with DuckDB syntax highlighting and autocompletion
33
+ * This is an internal component used by SqlEditor
34
+ */
35
+ export declare const SqlMonacoEditor: React.FC<SqlMonacoEditorProps>;
36
+ //# sourceMappingURL=SqlMonacoEditor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SqlMonacoEditor.d.ts","sourceRoot":"","sources":["../../../src/components/internal/SqlMonacoEditor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAuC,MAAM,OAAO,CAAC;AAE5D,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,yBAAyB,CAAC;AAS/D,MAAM,WAAW,oBACf,SAAQ,IAAI,CAAC,iBAAiB,EAAE,UAAU,CAAC;IAC3C;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACtD;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACxC;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM;QACvB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;QACrD,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;KACxC,CAAC;CACH;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAwQ1D,CAAC"}
@@ -0,0 +1,219 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useCallback, useEffect, useRef } from 'react';
3
+ import { MonacoEditor } from '@sqlrooms/monaco-editor';
4
+ import { DUCKDB_KEYWORDS, DUCKDB_FUNCTIONS, SQL_LANGUAGE_CONFIGURATION, } from '../../constants/duckdb-dialect';
5
+ /**
6
+ * A Monaco editor for editing SQL with DuckDB syntax highlighting and autocompletion
7
+ * This is an internal component used by SqlEditor
8
+ */
9
+ export const SqlMonacoEditor = ({ customKeywords = [], customFunctions = [], tableSchemas = {}, tableSamples = {}, getLatestSchemas, onMount, className, ...props }) => {
10
+ // Store references to editor and monaco
11
+ const editorRef = useRef(null);
12
+ const monacoRef = useRef(null);
13
+ const disposableRef = useRef(null);
14
+ // Function to register the completion provider
15
+ const registerCompletionProvider = useCallback(() => {
16
+ if (!editorRef.current || !monacoRef.current)
17
+ return;
18
+ const monaco = monacoRef.current;
19
+ // Dispose previous provider if it exists
20
+ if (disposableRef.current) {
21
+ disposableRef.current.dispose();
22
+ }
23
+ // Register SQL completion provider
24
+ const disposable = monaco.languages.registerCompletionItemProvider('sql', {
25
+ triggerCharacters: [' ', '.', ',', '(', '='],
26
+ provideCompletionItems: (model, position) => {
27
+ try {
28
+ // Get the latest schemas and samples if the callback is provided
29
+ let currentSchemas = tableSchemas;
30
+ let currentSamples = tableSamples;
31
+ if (getLatestSchemas) {
32
+ const latest = getLatestSchemas();
33
+ currentSchemas = latest.tableSchemas;
34
+ currentSamples = latest.tableSamples;
35
+ }
36
+ const suggestions = [];
37
+ const word = model.getWordUntilPosition(position);
38
+ const range = {
39
+ startLineNumber: position.lineNumber,
40
+ endLineNumber: position.lineNumber,
41
+ startColumn: word.startColumn,
42
+ endColumn: word.endColumn,
43
+ };
44
+ // Get the text before the cursor to determine context
45
+ const lineContent = model.getLineContent(position.lineNumber);
46
+ const textBeforeCursor = lineContent
47
+ .substring(0, position.column - 1)
48
+ .trim()
49
+ .toLowerCase();
50
+ // Check if we're after a FROM, JOIN, or similar clause to prioritize table suggestions
51
+ const isTableContext = /\b(from|join|into|update|table)\s+\w*$/.test(textBeforeCursor);
52
+ // Check if we're after a table name and period to prioritize column suggestions
53
+ const isColumnContext = /\b(\w+)\.\w*$/.test(textBeforeCursor);
54
+ // Combine keywords and functions with custom ones
55
+ const keywords = [...DUCKDB_KEYWORDS, ...customKeywords];
56
+ const functions = [...DUCKDB_FUNCTIONS, ...customFunctions];
57
+ // Add keyword suggestions (if not in a specific context)
58
+ if (!isColumnContext) {
59
+ keywords.forEach((keyword) => {
60
+ suggestions.push({
61
+ label: keyword,
62
+ kind: monaco.languages.CompletionItemKind.Keyword,
63
+ insertText: keyword,
64
+ range: range,
65
+ detail: 'Keyword',
66
+ sortText: isTableContext ? 'z' + keyword : 'a' + keyword, // Lower priority in table context
67
+ });
68
+ });
69
+ }
70
+ // Add function suggestions (if not in a specific context)
71
+ if (!isColumnContext) {
72
+ functions.forEach((func) => {
73
+ suggestions.push({
74
+ label: func,
75
+ kind: monaco.languages.CompletionItemKind.Function,
76
+ insertText: func,
77
+ range: range,
78
+ detail: 'Function',
79
+ sortText: isTableContext ? 'z' + func : 'b' + func, // Lower priority in table context
80
+ });
81
+ });
82
+ }
83
+ // Add table and column suggestions from schemas
84
+ Object.entries(currentSchemas).forEach(([tableName, columns]) => {
85
+ // Get sample data for this table if available
86
+ const samples = currentSamples[tableName] || [];
87
+ const sampleText = samples.length > 0 ? `\nSample data:\n${samples.join('\n')}` : '';
88
+ // Add table suggestion
89
+ suggestions.push({
90
+ label: tableName,
91
+ kind: monaco.languages.CompletionItemKind.Class,
92
+ insertText: tableName,
93
+ range: range,
94
+ detail: 'Table',
95
+ documentation: {
96
+ value: `Table: ${tableName}${sampleText}`,
97
+ isTrusted: true,
98
+ },
99
+ sortText: isTableContext ? 'a' + tableName : 'c' + tableName, // Higher priority in table context
100
+ });
101
+ // Extract table name from context if we're in a column context
102
+ let contextTableName = '';
103
+ if (isColumnContext) {
104
+ const match = textBeforeCursor.match(/\b(\w+)\.\w*$/);
105
+ if (match && match[1]) {
106
+ contextTableName = match[1];
107
+ }
108
+ }
109
+ // Only add columns for the current table if we're in a column context
110
+ if (!isColumnContext || contextTableName === tableName) {
111
+ // Add column suggestions
112
+ Object.entries(columns).forEach(([columnName, columnType]) => {
113
+ // Find sample values for this column if available
114
+ const columnSample = samples.find((s) => s.startsWith(`${columnName}:`));
115
+ const sampleInfo = columnSample
116
+ ? `\nSample: ${columnSample.split(':')[1]?.trim() || ''}`
117
+ : '';
118
+ suggestions.push({
119
+ label: columnName,
120
+ kind: monaco.languages.CompletionItemKind.Field,
121
+ insertText: columnName,
122
+ range: range,
123
+ detail: `Column (${columnType})`,
124
+ documentation: {
125
+ value: `Column from table ${tableName}${sampleInfo}`,
126
+ isTrusted: true,
127
+ },
128
+ sortText: isColumnContext && contextTableName === tableName
129
+ ? 'a' + columnName
130
+ : 'd' + columnName,
131
+ });
132
+ // Only add table.column suggestions if not in a column context
133
+ if (!isColumnContext) {
134
+ suggestions.push({
135
+ label: `${tableName}.${columnName}`,
136
+ kind: monaco.languages.CompletionItemKind.Field,
137
+ insertText: `${tableName}.${columnName}`,
138
+ range: range,
139
+ detail: `Column (${columnType})`,
140
+ documentation: {
141
+ value: `Column from table ${tableName}${sampleInfo}`,
142
+ isTrusted: true,
143
+ },
144
+ sortText: 'e' + tableName + columnName,
145
+ });
146
+ }
147
+ });
148
+ }
149
+ });
150
+ return {
151
+ suggestions,
152
+ };
153
+ }
154
+ catch (error) {
155
+ console.error('Error in SQL completion provider:', error);
156
+ return { suggestions: [] };
157
+ }
158
+ },
159
+ });
160
+ // Store the disposable to clean up later
161
+ disposableRef.current = disposable;
162
+ }, [
163
+ customKeywords,
164
+ customFunctions,
165
+ tableSchemas,
166
+ tableSamples,
167
+ getLatestSchemas,
168
+ ]);
169
+ // Re-register completion provider when tableSchemas or tableSamples change
170
+ useEffect(() => {
171
+ if (editorRef.current && monacoRef.current) {
172
+ registerCompletionProvider();
173
+ }
174
+ }, [tableSchemas, tableSamples, registerCompletionProvider]);
175
+ // Handle editor mounting to configure SQL language features
176
+ const handleEditorDidMount = useCallback((editor, monaco) => {
177
+ // Store references
178
+ editorRef.current = editor;
179
+ monacoRef.current = monaco;
180
+ // Register SQL language if not already registered
181
+ if (!monaco.languages.getLanguages().some((lang) => lang.id === 'sql')) {
182
+ monaco.languages.register({ id: 'sql' });
183
+ }
184
+ // Combine keywords and functions with custom ones
185
+ const keywords = [...DUCKDB_KEYWORDS, ...customKeywords];
186
+ const functions = [...DUCKDB_FUNCTIONS, ...customFunctions];
187
+ // Set the language configuration
188
+ monaco.languages.setMonarchTokensProvider('sql', {
189
+ ...SQL_LANGUAGE_CONFIGURATION,
190
+ keywords,
191
+ builtinFunctions: functions,
192
+ }); // Using 'as any' to bypass the type checking issue
193
+ // Register the completion provider
194
+ registerCompletionProvider();
195
+ // Store the disposable to clean up later if needed
196
+ editor.onDidDispose(() => {
197
+ if (disposableRef.current) {
198
+ disposableRef.current.dispose();
199
+ }
200
+ });
201
+ // Call the original onMount if provided
202
+ if (onMount) {
203
+ onMount(editor, monaco);
204
+ }
205
+ }, [
206
+ customKeywords,
207
+ customFunctions,
208
+ tableSchemas,
209
+ tableSamples,
210
+ onMount,
211
+ registerCompletionProvider,
212
+ ]);
213
+ return (_jsx(MonacoEditor, { language: "sql", onMount: handleEditorDidMount, className: className, options: {
214
+ formatOnPaste: true,
215
+ formatOnType: true,
216
+ wordWrap: 'on',
217
+ }, ...props }));
218
+ };
219
+ //# sourceMappingURL=SqlMonacoEditor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SqlMonacoEditor.js","sourceRoot":"","sources":["../../../src/components/internal/SqlMonacoEditor.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, {useCallback, useEffect, useRef} from 'react';\nimport {MonacoEditor} from '@sqlrooms/monaco-editor';\nimport type {MonacoEditorProps} from '@sqlrooms/monaco-editor';\nimport type {OnMount} from '@monaco-editor/react';\nimport type * as Monaco from 'monaco-editor';\nimport {\n DUCKDB_KEYWORDS,\n DUCKDB_FUNCTIONS,\n SQL_LANGUAGE_CONFIGURATION,\n} from '../../constants/duckdb-dialect';\n\nexport interface SqlMonacoEditorProps\n extends Omit<MonacoEditorProps, 'language'> {\n /**\n * Custom SQL keywords to add to the completion provider\n */\n customKeywords?: string[];\n /**\n * Custom SQL functions to add to the completion provider\n */\n customFunctions?: string[];\n /**\n * Table schemas for autocompletion\n * Format: { tableName: { columnName: columnType, ... }, ... }\n */\n tableSchemas?: Record<string, Record<string, string>>;\n /**\n * Sample data for tables to enhance autocompletion\n * Format: { tableName: [sampleDescription1, sampleDescription2, ...], ... }\n */\n tableSamples?: Record<string, string[]>;\n /**\n * Callback to get the latest table schemas and samples\n * This is called from within provideCompletionItems to ensure we have the latest data\n */\n getLatestSchemas?: () => {\n tableSchemas: Record<string, Record<string, string>>;\n tableSamples: Record<string, string[]>;\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 customKeywords = [],\n customFunctions = [],\n tableSchemas = {},\n tableSamples = {},\n getLatestSchemas,\n onMount,\n className,\n ...props\n}) => {\n // Store references to editor and monaco\n const editorRef = useRef<any>(null);\n const monacoRef = useRef<any>(null);\n const disposableRef = useRef<any>(null);\n\n // Function to register the completion provider\n const registerCompletionProvider = useCallback(() => {\n if (!editorRef.current || !monacoRef.current) return;\n\n const monaco = monacoRef.current;\n\n // Dispose previous provider if it exists\n if (disposableRef.current) {\n disposableRef.current.dispose();\n }\n\n // Register SQL completion provider\n const disposable = monaco.languages.registerCompletionItemProvider('sql', {\n triggerCharacters: [' ', '.', ',', '(', '='],\n provideCompletionItems: (model: any, position: any) => {\n try {\n // Get the latest schemas and samples if the callback is provided\n let currentSchemas = tableSchemas;\n let currentSamples = tableSamples;\n\n if (getLatestSchemas) {\n const latest = getLatestSchemas();\n currentSchemas = latest.tableSchemas;\n currentSamples = latest.tableSamples;\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, ...customKeywords];\n const functions = [...DUCKDB_FUNCTIONS, ...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 }\n\n // Add table and column suggestions from schemas\n Object.entries(currentSchemas).forEach(([tableName, columns]) => {\n // Get sample data for this table if available\n const samples = currentSamples[tableName] || [];\n const sampleText =\n samples.length > 0 ? `\\nSample data:\\n${samples.join('\\n')}` : '';\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}${sampleText}`,\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 Object.entries(columns).forEach(([columnName, columnType]) => {\n // Find sample values for this column if available\n const columnSample = samples.find((s) =>\n s.startsWith(`${columnName}:`),\n );\n const sampleInfo = columnSample\n ? `\\nSample: ${columnSample.split(':')[1]?.trim() || ''}`\n : '';\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}${sampleInfo}`,\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}${sampleInfo}`,\n isTrusted: true,\n },\n sortText: 'e' + tableName + columnName,\n });\n }\n });\n }\n });\n\n return {\n suggestions,\n };\n } catch (error) {\n console.error('Error in SQL completion provider:', error);\n return {suggestions: []};\n }\n },\n });\n\n // Store the disposable to clean up later\n disposableRef.current = disposable;\n }, [\n customKeywords,\n customFunctions,\n tableSchemas,\n tableSamples,\n getLatestSchemas,\n ]);\n\n // Re-register completion provider when tableSchemas or tableSamples change\n useEffect(() => {\n if (editorRef.current && monacoRef.current) {\n registerCompletionProvider();\n }\n }, [tableSchemas, tableSamples, registerCompletionProvider]);\n\n // Handle editor mounting to configure SQL language features\n const handleEditorDidMount = useCallback<OnMount>(\n (editor, monaco) => {\n // Store references\n editorRef.current = editor;\n monacoRef.current = monaco;\n\n // Register SQL language if not already registered\n if (\n !monaco.languages.getLanguages().some((lang: any) => lang.id === 'sql')\n ) {\n monaco.languages.register({id: 'sql'});\n }\n\n // Combine keywords and functions with custom ones\n const keywords = [...DUCKDB_KEYWORDS, ...customKeywords];\n const functions = [...DUCKDB_FUNCTIONS, ...customFunctions];\n\n // Set the language configuration\n monaco.languages.setMonarchTokensProvider('sql', {\n ...SQL_LANGUAGE_CONFIGURATION,\n keywords,\n builtinFunctions: functions,\n } as any); // Using 'as any' to bypass the type checking issue\n\n // Register the completion provider\n registerCompletionProvider();\n\n // Store the disposable to clean up later if needed\n editor.onDidDispose(() => {\n if (disposableRef.current) {\n disposableRef.current.dispose();\n }\n });\n\n // Call the original onMount if provided\n if (onMount) {\n onMount(editor, monaco);\n }\n },\n [\n customKeywords,\n customFunctions,\n tableSchemas,\n tableSamples,\n onMount,\n registerCompletionProvider,\n ],\n );\n\n return (\n <MonacoEditor\n language=\"sql\"\n onMount={handleEditorDidMount}\n className={className}\n options={{\n formatOnPaste: true,\n formatOnType: true,\n wordWrap: 'on',\n }}\n {...props}\n />\n );\n};\n"]}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * DuckDB SQL language constants for Monaco Editor
3
+ */
4
+ export declare const DUCKDB_KEYWORDS: string[];
5
+ export declare const DUCKDB_FUNCTIONS: string[];
6
+ export declare const SQL_OPERATORS: string[];
7
+ export declare const SQL_VARIABLES: string[];
8
+ export declare const SQL_PSEUDO_COLUMNS: string[];
9
+ export declare const SQL_LANGUAGE_CONFIGURATION: {
10
+ defaultToken: string;
11
+ tokenPostfix: string;
12
+ ignoreCase: boolean;
13
+ brackets: {
14
+ open: string;
15
+ close: string;
16
+ token: string;
17
+ }[];
18
+ keywords: string[];
19
+ operators: string[];
20
+ builtinFunctions: string[];
21
+ builtinVariables: string[];
22
+ pseudoColumns: string[];
23
+ tokenizer: {
24
+ root: ((string | RegExp)[] | {
25
+ include: string;
26
+ } | (RegExp | {
27
+ cases: {
28
+ '@keywords': string;
29
+ '@operators': string;
30
+ '@builtinFunctions': string;
31
+ '@builtinVariables': string;
32
+ '@pseudoColumns': string;
33
+ '@default': string;
34
+ };
35
+ })[])[];
36
+ whitespace: (string | RegExp)[][];
37
+ comments: ((string | RegExp)[] | (RegExp | {
38
+ token: string;
39
+ next: string;
40
+ })[])[];
41
+ comment: ((string | RegExp)[] | (RegExp | {
42
+ token: string;
43
+ next: string;
44
+ })[])[];
45
+ numbers: (string | RegExp)[][];
46
+ strings: (RegExp | {
47
+ token: string;
48
+ next: string;
49
+ })[][];
50
+ string: ((string | RegExp)[] | (RegExp | {
51
+ token: string;
52
+ next: string;
53
+ })[])[];
54
+ stringDouble: ((string | RegExp)[] | (RegExp | {
55
+ token: string;
56
+ next: string;
57
+ })[])[];
58
+ complexIdentifiers: (RegExp | {
59
+ token: string;
60
+ next: string;
61
+ })[][];
62
+ bracketedIdentifier: ((string | RegExp)[] | (RegExp | {
63
+ token: string;
64
+ next: string;
65
+ })[])[];
66
+ quotedIdentifier: ((string | RegExp)[] | (RegExp | {
67
+ token: string;
68
+ next: string;
69
+ })[])[];
70
+ scopes: never[];
71
+ };
72
+ };
73
+ //# sourceMappingURL=duckdb-dialect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"duckdb-dialect.d.ts","sourceRoot":"","sources":["../../src/constants/duckdb-dialect.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,eAAO,MAAM,eAAe,UA6H3B,CAAC;AAGF,eAAO,MAAM,gBAAgB,UAgI5B,CAAC;AAGF,eAAO,MAAM,aAAa,UAyBzB,CAAC;AAGF,eAAO,MAAM,aAAa,UAUzB,CAAC;AAGF,eAAO,MAAM,kBAAkB,UAK9B,CAAC;AAGF,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsFtC,CAAC"}