@sqlrooms/sql-editor 0.5.1 → 0.7.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 +291 -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 +2 -2
  55. package/dist/index.d.ts.map +1 -1
  56. package/dist/index.js +2 -2
  57. package/dist/index.js.map +1 -1
  58. package/package.json +16 -11
package/README.md ADDED
@@ -0,0 +1,291 @@
1
+ # SQL Editor
2
+
3
+ A powerful SQL editor component for SQLRooms applications. This package provides React components and hooks for creating interactive SQL query interfaces with Monaco editor integration, table management, and results visualization.
4
+
5
+ ## Features
6
+
7
+ - 🔍 **Advanced SQL Editing**: Monaco-based SQL editor with syntax highlighting and auto-completion
8
+ - 📊 **Data Visualization**: View query results in interactive data tables
9
+ - 📑 **Multiple Tabs**: Support for multiple query tabs with save/rename/delete functionality
10
+ - 🔄 **State Management**: Zustand-based state management for SQL editor state
11
+ - 📦 **Table Management**: Browser for tables in the database with schema information
12
+ - 📤 **Data Export**: Export query results to CSV files
13
+ - 📝 **Documentation**: Optional documentation panel for SQL reference
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npm install @sqlrooms/sql-editor
19
+ ```
20
+
21
+ ## Basic Usage
22
+
23
+ ### Simple SQL Editor
24
+
25
+ ```tsx
26
+ import {SqlEditor} from '@sqlrooms/sql-editor';
27
+
28
+ function MySqlEditor() {
29
+ const [isOpen, setIsOpen] = useState(true);
30
+
31
+ return <SqlEditor isOpen={isOpen} onClose={() => setIsOpen(false)} />;
32
+ }
33
+ ```
34
+
35
+ ### With Custom Schema and Documentation
36
+
37
+ ```tsx
38
+ import {SqlEditor} from '@sqlrooms/sql-editor';
39
+
40
+ function AdvancedSqlEditor() {
41
+ const [isOpen, setIsOpen] = useState(true);
42
+
43
+ // Custom documentation component
44
+ const Documentation = () => (
45
+ <div className="p-4">
46
+ <h2 className="text-xl font-bold mb-4">SQL Reference</h2>
47
+ <div className="space-y-4">
48
+ <div>
49
+ <h3 className="text-lg font-semibold">SELECT</h3>
50
+ <p>Retrieves data from a table</p>
51
+ <pre className="bg-gray-100 p-2 rounded mt-2">
52
+ SELECT column1, column2 FROM table_name;
53
+ </pre>
54
+ </div>
55
+ {/* More documentation items */}
56
+ </div>
57
+ </div>
58
+ );
59
+
60
+ return (
61
+ <SqlEditor
62
+ isOpen={isOpen}
63
+ onClose={() => setIsOpen(false)}
64
+ schema="analytics"
65
+ documentationPanel={<Documentation />}
66
+ />
67
+ );
68
+ }
69
+ ```
70
+
71
+ ## Available Components
72
+
73
+ ### SqlEditor
74
+
75
+ The main component providing a full-featured SQL editor interface.
76
+
77
+ ```tsx
78
+ import {SqlEditor} from '@sqlrooms/sql-editor';
79
+
80
+ <SqlEditor
81
+ isOpen={boolean}
82
+ onClose={() => void}
83
+ schema="main"
84
+ documentationPanel={ReactNode}
85
+ />
86
+ ```
87
+
88
+ ### SqlMonacoEditor
89
+
90
+ A standalone SQL-specific Monaco editor component.
91
+
92
+ ```tsx
93
+ import {SqlMonacoEditor} from '@sqlrooms/sql-editor';
94
+
95
+ <SqlMonacoEditor
96
+ value="SELECT * FROM users"
97
+ onChange={(value) => console.log(value)}
98
+ onExecuteQuery={() => executeQuery()}
99
+ />;
100
+ ```
101
+
102
+ ### SqlEditorModal
103
+
104
+ A modal wrapper around the SQL editor.
105
+
106
+ ```tsx
107
+ import {SqlEditorModal} from '@sqlrooms/sql-editor';
108
+
109
+ <SqlEditorModal isOpen={isOpen} onClose={() => setIsOpen(false)} />;
110
+ ```
111
+
112
+ ### CreateTableModal
113
+
114
+ A modal for creating new tables from SQL queries.
115
+
116
+ ```tsx
117
+ import {CreateTableModal} from '@sqlrooms/sql-editor';
118
+
119
+ <CreateTableModal
120
+ isOpen={isOpen}
121
+ onClose={() => setIsOpen(false)}
122
+ onCreateTable={(tableName) => console.log(`Created table: ${tableName}`)}
123
+ tableData={queryResults}
124
+ />;
125
+ ```
126
+
127
+ ### SqlQueryDataSourcesPanel
128
+
129
+ A panel showing available data sources for SQL queries.
130
+
131
+ ```tsx
132
+ import {SqlQueryDataSourcesPanel} from '@sqlrooms/sql-editor';
133
+
134
+ <SqlQueryDataSourcesPanel
135
+ onSelectTable={(tableName) => {
136
+ console.log(`Selected table: ${tableName}`);
137
+ }}
138
+ />;
139
+ ```
140
+
141
+ ## State Management
142
+
143
+ The SQL editor provides a Zustand slice for managing state. You can use it in two ways:
144
+
145
+ ### Using in a Combined SQLRooms Store
146
+
147
+ This approach is recommended when integrating multiple SQLRooms components:
148
+
149
+ ```tsx
150
+ import {
151
+ createSqlEditorSlice,
152
+ createDefaultSqlEditorConfig,
153
+ SqlEditorSliceState,
154
+ SqlEditorSliceConfig,
155
+ } from '@sqlrooms/sql-editor';
156
+ import {
157
+ createProjectSlice,
158
+ createProjectStore,
159
+ ProjectState,
160
+ } from '@sqlrooms/project-builder';
161
+ import {BaseProjectConfig} from '@sqlrooms/project-config';
162
+ import {
163
+ createAiSlice,
164
+ createDefaultAiConfig,
165
+ AiSliceState,
166
+ AiSliceConfig,
167
+ } from '@sqlrooms/ai';
168
+ import {z} from 'zod';
169
+
170
+ // 1. Define combined config schema
171
+ export const AppConfig =
172
+ BaseProjectConfig.merge(SqlEditorSliceConfig).merge(AiSliceConfig);
173
+ export type AppConfig = z.infer<typeof AppConfig>;
174
+
175
+ // 2. Define combined state type
176
+ export type AppState = ProjectState<AppConfig> &
177
+ SqlEditorSliceState &
178
+ AiSliceState;
179
+
180
+ // 3. Create combined store
181
+ export const {projectStore, useProjectStore} = createProjectStore<
182
+ AppConfig,
183
+ AppState
184
+ >((set, get, store) => ({
185
+ // Base project slice
186
+ ...createProjectSlice<AppConfig>({
187
+ project: {
188
+ config: {
189
+ title: 'SQL Workspace',
190
+ // ... other project config
191
+ ...createDefaultSqlEditorConfig(),
192
+ ...createDefaultAiConfig(),
193
+ },
194
+ // ... panels config
195
+ },
196
+ })(set, get, store),
197
+
198
+ // Sql editor slice
199
+ ...createSqlEditorSlice()(set, get, store),
200
+
201
+ // Ai slice
202
+ ...createAiSlice()(set, get, store),
203
+ }));
204
+
205
+ // 4. Use the store in components
206
+ function MyComponent() {
207
+ // Access SQL editor state and actions
208
+ const executeQuery = useProjectStore((state) => state.executeQuery);
209
+ const createQueryTab = useProjectStore((state) => state.createQueryTab);
210
+
211
+ // Use actions
212
+ const handleExecute = () => {
213
+ executeQuery('SELECT * FROM users LIMIT 10');
214
+ };
215
+
216
+ return (
217
+ <div>
218
+ <button onClick={handleExecute}>Run Query</button>
219
+ <SqlEditor store={useProjectStore} />
220
+ </div>
221
+ );
222
+ }
223
+ ```
224
+
225
+ ### Standalone SQL Editor Store
226
+
227
+ For simpler use cases where you only need the SQL editor:
228
+
229
+ ```tsx
230
+ // Create default configuration
231
+ const config = createDefaultSqlEditorConfig();
232
+
233
+ // Create a store with the SQL editor slice
234
+ const useStore = createProjectStore({
235
+ sqlEditor: createSqlEditorSlice(config),
236
+ });
237
+
238
+ // Use the store in components with the provided selector hook
239
+ const {executeQuery, getCurrentQuery} = useStoreWithSqlEditor(useStore);
240
+ ```
241
+
242
+ ### Available State Actions
243
+
244
+ - `executeQuery(query: string, schema?: string)`: Execute a SQL query
245
+ - `exportResultsToCsv(results: Table, filename?: string)`: Export results to CSV
246
+ - `createQueryTab(initialQuery?: string)`: Create a new query tab
247
+ - `deleteQueryTab(queryId: string)`: Delete a query tab
248
+ - `renameQueryTab(queryId: string, newName: string)`: Rename a query tab
249
+ - `updateQueryText(queryId: string, queryText: string)`: Update query text
250
+ - `setSelectedQueryId(queryId: string)`: Set the selected query tab
251
+ - `getCurrentQuery(defaultQuery?: string)`: Get current query text
252
+
253
+ ## Configuration
254
+
255
+ The SQL editor can be configured through the Zustand store.
256
+
257
+ ```tsx
258
+ const config = {
259
+ sqlEditor: {
260
+ queries: [
261
+ {id: 'default', name: 'Untitled', query: 'SELECT * FROM users LIMIT 10;'},
262
+ ],
263
+ selectedQueryId: 'default',
264
+ },
265
+ };
266
+ ```
267
+
268
+ ## Integration with DuckDB
269
+
270
+ This package integrates with `@sqlrooms/duckdb` for query execution and table management.
271
+
272
+ ```tsx
273
+ import {getDuckDb} from '@sqlrooms/duckdb';
274
+ import {Table} from 'apache-arrow';
275
+
276
+ // Execute a query directly
277
+ async function runQuery(query: string): Promise<Table> {
278
+ const db = await getDuckDb();
279
+ return db.query(query);
280
+ }
281
+ ```
282
+
283
+ ## Advanced Features
284
+
285
+ - **Custom Monaco Configuration**: Customize editor settings and SQL language support
286
+ - **Tab Management**: Create, rename, and delete query tabs
287
+ - **Table Creation**: Create new tables from query results
288
+ - **Table Schema Inspection**: View table schemas and column types
289
+ - **Export Functionality**: Export query results to various formats
290
+
291
+ For more information, visit the SQLRooms documentation.
@@ -1 +1 @@
1
- {"version":3,"file":"CreateTableModal.d.ts","sourceRoot":"","sources":["../src/CreateTableModal.tsx"],"names":[],"mappings":"AAoBA,OAAO,EAAC,kBAAkB,EAAC,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAC,EAAE,EAAc,MAAM,OAAO,CAAC;AAkBtC,MAAM,MAAM,qBAAqB,GAAG;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,cAAc,CAAC,EAAE,kBAAkB,CAAC;IACpC,qBAAqB,EAAE,CACrB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,YAAY,CAAC,EAAE,MAAM,KAClB,OAAO,CAAC,IAAI,CAAC,CAAC;CACpB,CAAC;AAEF,QAAA,MAAM,gBAAgB,EAAE,EAAE,CAAC,qBAAqB,CA0G/C,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"CreateTableModal.d.ts","sourceRoot":"","sources":["../src/CreateTableModal.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAC,kBAAkB,EAAC,MAAM,0BAA0B,CAAC;AAmB5D,OAAO,EAAC,EAAE,EAAc,MAAM,OAAO,CAAC;AAkBtC,MAAM,MAAM,qBAAqB,GAAG;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,cAAc,CAAC,EAAE,kBAAkB,CAAC;IACpC,qBAAqB,EAAE,CACrB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,YAAY,CAAC,EAAE,MAAM,KAClB,OAAO,CAAC,IAAI,CAAC,CAAC;CACpB,CAAC;AAEF,QAAA,MAAM,gBAAgB,EAAE,EAAE,CAAC,qBAAqB,CAiH/C,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
@@ -1,10 +1,11 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Button, Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, Form, FormControl, FormField, FormItem, FormLabel, FormMessage, Input, Textarea, Alert, AlertDescription, } from '@sqlrooms/ui';
2
+ import { zodResolver } from '@hookform/resolvers/zod';
3
3
  import { DuckQueryError } from '@sqlrooms/duckdb';
4
+ import { Alert, AlertDescription, Button, Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, Form, FormControl, FormField, FormItem, FormLabel, FormMessage, Input, } from '@sqlrooms/ui';
4
5
  import { useCallback } from 'react';
5
6
  import { useForm } from 'react-hook-form';
6
7
  import * as z from 'zod';
7
- import { zodResolver } from '@hookform/resolvers/zod';
8
+ import { SqlMonacoEditor } from './SqlMonacoEditor';
8
9
  const VALID_TABLE_OR_COLUMN_REGEX = /^[a-zA-Z_][a-zA-Z0-9_]{0,62}$/;
9
10
  const formSchema = z.object({
10
11
  tableName: z
@@ -17,7 +18,7 @@ const CreateTableModal = (props) => {
17
18
  const { editDataSource, isOpen, onClose, onAddOrUpdateSqlQuery } = props;
18
19
  const form = useForm({
19
20
  resolver: zodResolver(formSchema),
20
- defaultValues: {
21
+ values: {
21
22
  tableName: editDataSource?.tableName ?? '',
22
23
  query: editDataSource?.sqlQuery ?? props.query.trim(),
23
24
  },
@@ -46,7 +47,12 @@ const CreateTableModal = (props) => {
46
47
  // @ts-ignore
47
48
  , {
48
49
  // @ts-ignore
49
- control: form.control, name: "query", render: ({ field }) => (_jsxs(FormItem, { children: [_jsx(FormLabel, { children: "SQL query:" }), _jsx(FormControl, { children: _jsx(Textarea, { ...field, className: "font-mono text-sm bg-secondary min-h-[200px]" }) }), _jsx(FormMessage, {})] })) }), _jsxs(DialogFooter, { children: [_jsx(Button, { type: "button", variant: "outline", onClick: onClose, children: "Cancel" }), _jsx(Button, { type: "submit", disabled: form.formState.isSubmitting, children: editDataSource ? 'Update' : 'Create' })] })] }) }) }) }));
50
+ control: form.control, name: "query", render: ({ field }) => (_jsxs(FormItem, { children: [_jsx(FormLabel, { children: "SQL query:" }), _jsx(FormControl, { children: _jsx(SqlMonacoEditor, { value: field.value, onChange: field.onChange, className: "min-h-[200px]", options: {
51
+ scrollBeyondLastLine: false,
52
+ automaticLayout: true,
53
+ minimap: { enabled: false },
54
+ wordWrap: 'on',
55
+ } }) }), _jsx(FormMessage, {})] })) }), _jsxs(DialogFooter, { children: [_jsx(Button, { type: "button", variant: "outline", onClick: onClose, children: "Cancel" }), _jsx(Button, { type: "submit", disabled: form.formState.isSubmitting, children: editDataSource ? 'Update' : 'Create' })] })] }) }) }) }));
50
56
  };
51
57
  export default CreateTableModal;
52
58
  //# sourceMappingURL=CreateTableModal.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CreateTableModal.js","sourceRoot":"","sources":["../src/CreateTableModal.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n Button,\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n Form,\n FormControl,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n Input,\n Textarea,\n Alert,\n AlertDescription,\n} from '@sqlrooms/ui';\nimport {DuckQueryError} from '@sqlrooms/duckdb';\nimport {SqlQueryDataSource} from '@sqlrooms/project-config';\nimport {FC, useCallback} from 'react';\nimport {useForm} from 'react-hook-form';\nimport * as z from 'zod';\nimport {zodResolver} from '@hookform/resolvers/zod';\n\nconst VALID_TABLE_OR_COLUMN_REGEX = /^[a-zA-Z_][a-zA-Z0-9_]{0,62}$/;\n\nconst formSchema = z.object({\n tableName: z\n .string()\n .min(1, 'Table name is required')\n .regex(\n VALID_TABLE_OR_COLUMN_REGEX,\n 'Only letters, digits and underscores are allowed; should not start with a digit',\n ),\n query: z.string().min(1, 'Query is required'),\n});\n\nexport type CreateTableModalProps = {\n query: string;\n isOpen: boolean;\n onClose: () => void;\n editDataSource?: SqlQueryDataSource;\n onAddOrUpdateSqlQuery: (\n tableName: string,\n query: string,\n oldTableName?: string,\n ) => Promise<void>;\n};\n\nconst CreateTableModal: FC<CreateTableModalProps> = (props) => {\n const {editDataSource, isOpen, onClose, onAddOrUpdateSqlQuery} = props;\n\n const form = useForm<z.infer<typeof formSchema>>({\n resolver: zodResolver(formSchema),\n defaultValues: {\n tableName: editDataSource?.tableName ?? '',\n query: editDataSource?.sqlQuery ?? props.query.trim(),\n },\n });\n\n const onSubmit = useCallback(\n async (values: z.infer<typeof formSchema>) => {\n try {\n const {tableName, query} = values;\n await onAddOrUpdateSqlQuery(\n tableName,\n query,\n editDataSource?.tableName,\n );\n form.reset();\n onClose();\n } catch (err) {\n form.setError('root', {\n type: 'manual',\n message:\n err instanceof DuckQueryError ? err.getMessageForUser() : `${err}`,\n });\n }\n },\n [onAddOrUpdateSqlQuery, editDataSource?.tableName, onClose, form],\n );\n\n return (\n <Dialog open={isOpen} onOpenChange={(open) => !open && onClose()}>\n <DialogContent className=\"sm:max-w-[800px]\">\n {/* @ts-ignore */}\n <Form {...form}>\n <form onSubmit={form.handleSubmit(onSubmit)} className=\"space-y-4\">\n <DialogHeader>\n <DialogTitle>\n {editDataSource\n ? 'Edit table query'\n : 'Create table from query'}\n </DialogTitle>\n {!editDataSource && (\n <DialogDescription>\n Create a new table from the results of an SQL query.\n </DialogDescription>\n )}\n </DialogHeader>\n\n {form.formState.errors.root && (\n <Alert variant=\"destructive\">\n <AlertDescription>\n {form.formState.errors.root.message}\n </AlertDescription>\n </Alert>\n )}\n\n <FormField\n // @ts-ignore\n control={form.control}\n name=\"tableName\"\n render={({field}) => (\n <FormItem>\n <FormLabel>Table name:</FormLabel>\n <FormControl>\n <Input {...field} className=\"font-mono\" autoFocus />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <FormField\n // @ts-ignore\n control={form.control}\n name=\"query\"\n render={({field}) => (\n <FormItem>\n <FormLabel>SQL query:</FormLabel>\n <FormControl>\n <Textarea\n {...field}\n className=\"font-mono text-sm bg-secondary min-h-[200px]\"\n />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <DialogFooter>\n <Button type=\"button\" variant=\"outline\" onClick={onClose}>\n Cancel\n </Button>\n <Button type=\"submit\" disabled={form.formState.isSubmitting}>\n {editDataSource ? 'Update' : 'Create'}\n </Button>\n </DialogFooter>\n </form>\n </Form>\n </DialogContent>\n </Dialog>\n );\n};\n\nexport default CreateTableModal;\n"]}
1
+ {"version":3,"file":"CreateTableModal.js","sourceRoot":"","sources":["../src/CreateTableModal.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAC,cAAc,EAAC,MAAM,kBAAkB,CAAC;AAEhD,OAAO,EACL,KAAK,EACL,gBAAgB,EAChB,MAAM,EACN,MAAM,EACN,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,IAAI,EACJ,WAAW,EACX,SAAS,EACT,QAAQ,EACR,SAAS,EACT,WAAW,EACX,KAAK,GACN,MAAM,cAAc,CAAC;AACtB,OAAO,EAAK,WAAW,EAAC,MAAM,OAAO,CAAC;AACtC,OAAO,EAAC,OAAO,EAAC,MAAM,iBAAiB,CAAC;AACxC,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AACzB,OAAO,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAC;AAElD,MAAM,2BAA2B,GAAG,+BAA+B,CAAC;AAEpE,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1B,SAAS,EAAE,CAAC;SACT,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,EAAE,wBAAwB,CAAC;SAChC,KAAK,CACJ,2BAA2B,EAC3B,iFAAiF,CAClF;IACH,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,mBAAmB,CAAC;CAC9C,CAAC,CAAC;AAcH,MAAM,gBAAgB,GAA8B,CAAC,KAAK,EAAE,EAAE;IAC5D,MAAM,EAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,qBAAqB,EAAC,GAAG,KAAK,CAAC;IAEvE,MAAM,IAAI,GAAG,OAAO,CAA6B;QAC/C,QAAQ,EAAE,WAAW,CAAC,UAAU,CAAC;QACjC,MAAM,EAAE;YACN,SAAS,EAAE,cAAc,EAAE,SAAS,IAAI,EAAE;YAC1C,KAAK,EAAE,cAAc,EAAE,QAAQ,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE;SACtD;KACF,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG,WAAW,CAC1B,KAAK,EAAE,MAAkC,EAAE,EAAE;QAC3C,IAAI,CAAC;YACH,MAAM,EAAC,SAAS,EAAE,KAAK,EAAC,GAAG,MAAM,CAAC;YAClC,MAAM,qBAAqB,CACzB,SAAS,EACT,KAAK,EACL,cAAc,EAAE,SAAS,CAC1B,CAAC;YACF,IAAI,CAAC,KAAK,EAAE,CAAC;YACb,OAAO,EAAE,CAAC;QACZ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE;gBACpB,IAAI,EAAE,QAAQ;gBACd,OAAO,EACL,GAAG,YAAY,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,EAAE;aACrE,CAAC,CAAC;QACL,CAAC;IACH,CAAC,EACD,CAAC,qBAAqB,EAAE,cAAc,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,CAClE,CAAC;IAEF,OAAO,CACL,KAAC,MAAM,IAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI,OAAO,EAAE,YAC9D,KAAC,aAAa,IAAC,SAAS,EAAC,kBAAkB,YAEzC,KAAC,IAAI,OAAK,IAAI,YACZ,gBAAM,QAAQ,EAAE,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,EAAE,SAAS,EAAC,WAAW,aAChE,MAAC,YAAY,eACX,KAAC,WAAW,cACT,cAAc;wCACb,CAAC,CAAC,kBAAkB;wCACpB,CAAC,CAAC,yBAAyB,GACjB,EACb,CAAC,cAAc,IAAI,CAClB,KAAC,iBAAiB,uEAEE,CACrB,IACY,EAEd,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,IAAI,CAC7B,KAAC,KAAK,IAAC,OAAO,EAAC,aAAa,YAC1B,KAAC,gBAAgB,cACd,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,GAClB,GACb,CACT,EAED,KAAC,SAAS;wBACR,aAAa;;4BAAb,aAAa;4BACb,OAAO,EAAE,IAAI,CAAC,OAAO,EACrB,IAAI,EAAC,WAAW,EAChB,MAAM,EAAE,CAAC,EAAC,KAAK,EAAC,EAAE,EAAE,CAAC,CACnB,MAAC,QAAQ,eACP,KAAC,SAAS,8BAAwB,EAClC,KAAC,WAAW,cACV,KAAC,KAAK,OAAK,KAAK,EAAE,SAAS,EAAC,WAAW,EAAC,SAAS,SAAG,GACxC,EACd,KAAC,WAAW,KAAG,IACN,CACZ,GACD,EAEF,KAAC,SAAS;wBACR,aAAa;;4BAAb,aAAa;4BACb,OAAO,EAAE,IAAI,CAAC,OAAO,EACrB,IAAI,EAAC,OAAO,EACZ,MAAM,EAAE,CAAC,EAAC,KAAK,EAAC,EAAE,EAAE,CAAC,CACnB,MAAC,QAAQ,eACP,KAAC,SAAS,6BAAuB,EACjC,KAAC,WAAW,cACV,KAAC,eAAe,IACd,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,QAAQ,EAAE,KAAK,CAAC,QAAQ,EACxB,SAAS,EAAC,eAAe,EACzB,OAAO,EAAE;gDACP,oBAAoB,EAAE,KAAK;gDAC3B,eAAe,EAAE,IAAI;gDACrB,OAAO,EAAE,EAAC,OAAO,EAAE,KAAK,EAAC;gDACzB,QAAQ,EAAE,IAAI;6CACf,GACD,GACU,EACd,KAAC,WAAW,KAAG,IACN,CACZ,GACD,EAEF,MAAC,YAAY,eACX,KAAC,MAAM,IAAC,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAC,SAAS,EAAC,OAAO,EAAE,OAAO,uBAE/C,EACT,KAAC,MAAM,IAAC,IAAI,EAAC,QAAQ,EAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,YAAY,YACxD,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,GAC9B,IACI,IACV,GACF,GACO,GACT,CACV,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,gBAAgB,CAAC","sourcesContent":["import {zodResolver} from '@hookform/resolvers/zod';\nimport {DuckQueryError} from '@sqlrooms/duckdb';\nimport {SqlQueryDataSource} from '@sqlrooms/project-config';\nimport {\n Alert,\n AlertDescription,\n Button,\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n Form,\n FormControl,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n Input,\n} from '@sqlrooms/ui';\nimport {FC, useCallback} from 'react';\nimport {useForm} from 'react-hook-form';\nimport * as z from 'zod';\nimport {SqlMonacoEditor} from './SqlMonacoEditor';\n\nconst VALID_TABLE_OR_COLUMN_REGEX = /^[a-zA-Z_][a-zA-Z0-9_]{0,62}$/;\n\nconst formSchema = z.object({\n tableName: z\n .string()\n .min(1, 'Table name is required')\n .regex(\n VALID_TABLE_OR_COLUMN_REGEX,\n 'Only letters, digits and underscores are allowed; should not start with a digit',\n ),\n query: z.string().min(1, 'Query is required'),\n});\n\nexport type CreateTableModalProps = {\n query: string;\n isOpen: boolean;\n onClose: () => void;\n editDataSource?: SqlQueryDataSource;\n onAddOrUpdateSqlQuery: (\n tableName: string,\n query: string,\n oldTableName?: string,\n ) => Promise<void>;\n};\n\nconst CreateTableModal: FC<CreateTableModalProps> = (props) => {\n const {editDataSource, isOpen, onClose, onAddOrUpdateSqlQuery} = props;\n\n const form = useForm<z.infer<typeof formSchema>>({\n resolver: zodResolver(formSchema),\n values: {\n tableName: editDataSource?.tableName ?? '',\n query: editDataSource?.sqlQuery ?? props.query.trim(),\n },\n });\n\n const onSubmit = useCallback(\n async (values: z.infer<typeof formSchema>) => {\n try {\n const {tableName, query} = values;\n await onAddOrUpdateSqlQuery(\n tableName,\n query,\n editDataSource?.tableName,\n );\n form.reset();\n onClose();\n } catch (err) {\n form.setError('root', {\n type: 'manual',\n message:\n err instanceof DuckQueryError ? err.getMessageForUser() : `${err}`,\n });\n }\n },\n [onAddOrUpdateSqlQuery, editDataSource?.tableName, onClose, form],\n );\n\n return (\n <Dialog open={isOpen} onOpenChange={(open) => !open && onClose()}>\n <DialogContent className=\"sm:max-w-[800px]\">\n {/* @ts-ignore */}\n <Form {...form}>\n <form onSubmit={form.handleSubmit(onSubmit)} className=\"space-y-4\">\n <DialogHeader>\n <DialogTitle>\n {editDataSource\n ? 'Edit table query'\n : 'Create table from query'}\n </DialogTitle>\n {!editDataSource && (\n <DialogDescription>\n Create a new table from the results of an SQL query.\n </DialogDescription>\n )}\n </DialogHeader>\n\n {form.formState.errors.root && (\n <Alert variant=\"destructive\">\n <AlertDescription>\n {form.formState.errors.root.message}\n </AlertDescription>\n </Alert>\n )}\n\n <FormField\n // @ts-ignore\n control={form.control}\n name=\"tableName\"\n render={({field}) => (\n <FormItem>\n <FormLabel>Table name:</FormLabel>\n <FormControl>\n <Input {...field} className=\"font-mono\" autoFocus />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <FormField\n // @ts-ignore\n control={form.control}\n name=\"query\"\n render={({field}) => (\n <FormItem>\n <FormLabel>SQL query:</FormLabel>\n <FormControl>\n <SqlMonacoEditor\n value={field.value}\n onChange={field.onChange}\n className=\"min-h-[200px]\"\n options={{\n scrollBeyondLastLine: false,\n automaticLayout: true,\n minimap: {enabled: false},\n wordWrap: 'on',\n }}\n />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <DialogFooter>\n <Button type=\"button\" variant=\"outline\" onClick={onClose}>\n Cancel\n </Button>\n <Button type=\"submit\" disabled={form.formState.isSubmitting}>\n {editDataSource ? 'Update' : 'Create'}\n </Button>\n </DialogFooter>\n </form>\n </Form>\n </DialogContent>\n </Dialog>\n );\n};\n\nexport default CreateTableModal;\n"]}
@@ -9,19 +9,6 @@ export type SqlEditorProps = {
9
9
  /** Callback fired when the SQL editor should be closed */
10
10
  onClose: () => void;
11
11
  };
12
- /**
13
- * A full-featured SQL editor component with query execution, table management, and results visualization.
14
- *
15
- * Features:
16
- * - Multiple query tabs with save/rename/delete functionality
17
- * - Query execution with results displayed in a data table
18
- * - Table browser showing available tables in the schema
19
- * - Export results to CSV
20
- * - Create new tables from query results
21
- * - Optional SQL documentation panel
22
- * - Keyboard shortcuts (Cmd/Ctrl + Enter to run queries)
23
- *
24
- */
25
- declare const SqlEditor: React.FC<SqlEditorProps>;
12
+ declare const SqlEditor: React.NamedExoticComponent<SqlEditorProps>;
26
13
  export default SqlEditor;
27
14
  //# sourceMappingURL=SqlEditor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SqlEditor.d.ts","sourceRoot":"","sources":["../src/SqlEditor.tsx"],"names":[],"mappings":"AAsCA,OAAO,KAAiD,MAAM,OAAO,CAAC;AAStE,MAAM,MAAM,cAAc,GAAG;IAC3B,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,kDAAkD;IAClD,MAAM,EAAE,OAAO,CAAC;IAEhB,uEAAuE;IACvE,kBAAkB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAErC,0DAA0D;IAC1D,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,QAAA,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,cAAc,CAqcvC,CAAC;AAEF,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"SqlEditor.d.ts","sourceRoot":"","sources":["../src/SqlEditor.tsx"],"names":[],"mappings":"AAwBA,OAAO,KAAyC,MAAM,OAAO,CAAC;AAiB9D,MAAM,MAAM,cAAc,GAAG;IAC3B,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,kDAAkD;IAClD,MAAM,EAAE,OAAO,CAAC;IAEhB,uEAAuE;IACvE,kBAAkB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAErC,0DAA0D;IAC1D,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AA2aF,QAAA,MAAM,SAAS,4CAA4B,CAAC;AAE5C,eAAe,SAAS,CAAC"}