diff --git a/.changeset/itchy-countries-worry.md b/.changeset/itchy-countries-worry.md
new file mode 100644
index 0000000000..9374512b23
--- /dev/null
+++ b/.changeset/itchy-countries-worry.md
@@ -0,0 +1,5 @@
+---
+"@latticexyz/explorer": patch
+---
+
+Explore page now has a full-featured SQL editor with syntax highlighting, autocomplete, and query validation.
diff --git a/packages/explorer/next.config.mjs b/packages/explorer/next.config.mjs
index 7811d5e71d..a4f4406e34 100644
--- a/packages/explorer/next.config.mjs
+++ b/packages/explorer/next.config.mjs
@@ -6,6 +6,7 @@ export default function config() {
output: "standalone",
webpack: (config) => {
config.externals.push("pino-pretty", "lokijs", "encoding");
+ config.resolve.fallback = { fs: false };
return config;
},
redirects: async () => {
diff --git a/packages/explorer/package.json b/packages/explorer/package.json
index e24b7e79fb..7198ccf340 100644
--- a/packages/explorer/package.json
+++ b/packages/explorer/package.json
@@ -44,6 +44,7 @@
"@latticexyz/store-indexer": "workspace:*",
"@latticexyz/store-sync": "workspace:*",
"@latticexyz/world": "workspace:*",
+ "@monaco-editor/react": "^4.6.0",
"@radix-ui/react-checkbox": "^1.1.1",
"@radix-ui/react-dialog": "^1.1.1",
"@radix-ui/react-label": "^2.1.0",
@@ -61,13 +62,16 @@
"cmdk": "1.0.0",
"debug": "^4.3.4",
"lucide-react": "^0.408.0",
+ "monaco-editor": "^0.52.0",
"next": "14.2.5",
+ "node-sql-parser": "^5.3.3",
"nuqs": "^1.19.2",
"query-string": "^9.1.0",
"react": "^18",
"react-dom": "^18",
"react-hook-form": "^7.52.1",
"sonner": "^1.5.0",
+ "sql-autocomplete": "^1.1.1",
"tailwind-merge": "^1.12.0",
"tsup": "^6.7.0",
"viem": "catalog:",
diff --git a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/Explorer.tsx b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/Explorer.tsx
index e408a7d9e0..f7d19fbf86 100644
--- a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/Explorer.tsx
+++ b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/Explorer.tsx
@@ -38,7 +38,7 @@ export function Explorer() {
return (
<>
- {indexer.type !== "sqlite" && }
+ {indexer.type !== "sqlite" && }
>
diff --git a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/SQLEditor.tsx b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/SQLEditor.tsx
index edffb85f7c..22b2a993f1 100644
--- a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/SQLEditor.tsx
+++ b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/SQLEditor.tsx
@@ -1,46 +1,84 @@
+"use client";
+
import { PlayIcon } from "lucide-react";
import { useQueryState } from "nuqs";
-import { useEffect } from "react";
+import { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
+import { Table } from "@latticexyz/config";
+import Editor from "@monaco-editor/react";
import { Button } from "../../../../../../components/ui/Button";
-import { Form, FormControl, FormField, FormItem } from "../../../../../../components/ui/Form";
-import { Input } from "../../../../../../components/ui/Input";
+import { Form, FormField } from "../../../../../../components/ui/Form";
+import { cn } from "../../../../../../utils";
+import { monacoOptions } from "./consts";
+import { useMonacoSuggestions } from "./useMonacoSuggestions";
+import { useQueryValidator } from "./useQueryValidator";
+
+type Props = {
+ table?: Table;
+};
+
+export function SQLEditor({ table }: Props) {
+ const [isFocused, setIsFocused] = useState(false);
+ const [query, setQuery] = useQueryState("query", { defaultValue: "" });
+ const validateQuery = useQueryValidator(table);
+ useMonacoSuggestions(table);
-export function SQLEditor() {
- const [query, setQuery] = useQueryState("query");
const form = useForm({
defaultValues: {
- query: query || "",
+ query,
},
});
const handleSubmit = form.handleSubmit((data) => {
- setQuery(data.query);
+ if (validateQuery(data.query)) {
+ setQuery(data.query);
+ }
});
useEffect(() => {
- form.reset({ query: query || "" });
+ form.reset({ query });
}, [query, form]);
return (
);
diff --git a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/consts.ts b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/consts.ts
new file mode 100644
index 0000000000..cca942027f
--- /dev/null
+++ b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/consts.ts
@@ -0,0 +1,41 @@
+import { editor } from "monaco-editor/esm/vs/editor/editor.api";
+
+export const monacoOptions: editor.IStandaloneEditorConstructionOptions = {
+ fontSize: 14,
+ fontWeight: "normal",
+ wordWrap: "off",
+ lineNumbers: "off",
+ lineNumbersMinChars: 0,
+ overviewRulerLanes: 0,
+ overviewRulerBorder: false,
+ hideCursorInOverviewRuler: true,
+ lineDecorationsWidth: 0,
+ glyphMargin: false,
+ folding: false,
+ scrollBeyondLastColumn: 0,
+ scrollbar: {
+ horizontal: "hidden",
+ vertical: "hidden",
+ alwaysConsumeMouseWheel: false,
+ handleMouseWheel: false,
+ },
+ find: {
+ addExtraSpaceOnTop: false,
+ autoFindInSelection: "never",
+ seedSearchStringFromSelection: "never",
+ },
+ minimap: { enabled: false },
+ wordBasedSuggestions: "off",
+ links: false,
+ occurrencesHighlight: "off",
+ cursorStyle: "line-thin",
+ renderLineHighlight: "none",
+ contextmenu: false,
+ roundedSelection: false,
+ hover: {
+ delay: 100,
+ },
+ acceptSuggestionOnEnter: "on",
+ automaticLayout: true,
+ fixedOverflowWidgets: true,
+};
diff --git a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/useMonacoErrorMarker.ts b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/useMonacoErrorMarker.ts
new file mode 100644
index 0000000000..27134fc3dd
--- /dev/null
+++ b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/useMonacoErrorMarker.ts
@@ -0,0 +1,23 @@
+import { useCallback } from "react";
+import { useMonaco } from "@monaco-editor/react";
+
+export function useMonacoErrorMarker() {
+ const monaco = useMonaco();
+ return useCallback(
+ ({ message, startColumn, endColumn }: { message: string; startColumn: number; endColumn: number }) => {
+ if (monaco) {
+ monaco.editor.setModelMarkers(monaco.editor.getModels()[0], "sql", [
+ {
+ severity: monaco.MarkerSeverity.Error,
+ message,
+ startLineNumber: 1,
+ startColumn,
+ endLineNumber: 1,
+ endColumn,
+ },
+ ]);
+ }
+ },
+ [monaco],
+ );
+}
diff --git a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/useMonacoSuggestions.ts b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/useMonacoSuggestions.ts
new file mode 100644
index 0000000000..d4c736b8d4
--- /dev/null
+++ b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/useMonacoSuggestions.ts
@@ -0,0 +1,60 @@
+import { useEffect } from "react";
+import { Table } from "@latticexyz/config";
+import { useMonaco } from "@monaco-editor/react";
+import { useQueryAutocomplete } from "./useQueryAutocomplete";
+
+const monacoSuggestionsMap = {
+ KEYWORD: "Keyword",
+ TABLE: "Field",
+ COLUMN: "Field",
+} as const;
+
+export function useMonacoSuggestions(table?: Table) {
+ const monaco = useMonaco();
+ const queryAutocomplete = useQueryAutocomplete(table);
+
+ useEffect(() => {
+ if (!monaco) return;
+
+ const provider = monaco.languages.registerCompletionItemProvider("sql", {
+ triggerCharacters: [" ", ".", ","],
+
+ provideCompletionItems: (model, position) => {
+ if (!queryAutocomplete) {
+ return { suggestions: [] };
+ }
+
+ const textUntilPosition = model.getValueInRange({
+ startLineNumber: 1,
+ startColumn: 1,
+ endLineNumber: position.lineNumber,
+ endColumn: position.column,
+ });
+
+ const word = model.getWordUntilPosition(position);
+ const range = {
+ startLineNumber: position.lineNumber,
+ startColumn: word.startColumn,
+ endLineNumber: position.lineNumber,
+ endColumn: word.endColumn,
+ };
+
+ const suggestions = queryAutocomplete
+ .autocomplete(textUntilPosition)
+ .map(({ value, optionType }) => ({
+ label: value,
+ kind: monaco.languages.CompletionItemKind[monacoSuggestionsMap[optionType]],
+ insertText: value,
+ range,
+ // move keyword optionType to the top of suggestions list
+ sortText: optionType !== "KEYWORD" ? "0" : "1",
+ }))
+ .filter(({ label }) => !!label);
+
+ return { suggestions };
+ },
+ });
+
+ return () => provider.dispose();
+ }, [monaco, queryAutocomplete]);
+}
diff --git a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/useQueryAutocomplete.ts b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/useQueryAutocomplete.ts
new file mode 100644
index 0000000000..14027d594b
--- /dev/null
+++ b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/useQueryAutocomplete.ts
@@ -0,0 +1,21 @@
+import { useParams } from "next/navigation";
+import { SQLAutocomplete, SQLDialect } from "sql-autocomplete";
+import { Address } from "viem";
+import { useMemo } from "react";
+import { Table } from "@latticexyz/config";
+import { useChain } from "../../../../hooks/useChain";
+import { constructTableName } from "../../../../utils/constructTableName";
+
+export function useQueryAutocomplete(table?: Table) {
+ const { id: chainId } = useChain();
+ const { worldAddress } = useParams<{ worldAddress: Address }>();
+
+ return useMemo(() => {
+ if (!table || !worldAddress || !chainId) return null;
+
+ const tableName = constructTableName(table, worldAddress as Address, chainId);
+ const columnNames = Object.keys(table.schema);
+
+ return new SQLAutocomplete(SQLDialect.PLpgSQL, [tableName], columnNames);
+ }, [table, worldAddress, chainId]);
+}
diff --git a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/useQueryValidator.ts b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/useQueryValidator.ts
new file mode 100644
index 0000000000..3603419860
--- /dev/null
+++ b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/useQueryValidator.ts
@@ -0,0 +1,72 @@
+import { useParams } from "next/navigation";
+import { Parser } from "node-sql-parser";
+import { Address } from "viem";
+import { useCallback } from "react";
+import { Table } from "@latticexyz/config";
+import { useMonaco } from "@monaco-editor/react";
+import { useChain } from "../../../../hooks/useChain";
+import { constructTableName } from "../../../../utils/constructTableName";
+import { useMonacoErrorMarker } from "./useMonacoErrorMarker";
+
+const sqlParser = new Parser();
+
+export function useQueryValidator(table?: Table) {
+ const monaco = useMonaco();
+ const { worldAddress } = useParams();
+ const { id: chainId } = useChain();
+ const setErrorMarker = useMonacoErrorMarker();
+
+ return useCallback(
+ (value: string) => {
+ if (!monaco || !table) return true;
+
+ try {
+ const ast = sqlParser.astify(value);
+ if ("columns" in ast && Array.isArray(ast.columns)) {
+ for (const column of ast.columns) {
+ const columnName = column.expr.column;
+ if (!Object.keys(table.schema).includes(columnName)) {
+ setErrorMarker({
+ message: `Column '${columnName}' does not exist in the table schema.`,
+ startColumn: value.indexOf(columnName) + 1,
+ endColumn: value.indexOf(columnName) + columnName.length + 1,
+ });
+ return false;
+ }
+ }
+ }
+
+ if ("from" in ast && Array.isArray(ast.from)) {
+ for (const tableInfo of ast.from) {
+ if ("table" in tableInfo) {
+ const selectedTableName = tableInfo.table;
+ const tableName = constructTableName(table, worldAddress as Address, chainId);
+
+ if (selectedTableName !== tableName) {
+ setErrorMarker({
+ message: `Only '${tableName}' is available for this query.`,
+ startColumn: value.indexOf(selectedTableName) + 1,
+ endColumn: value.indexOf(selectedTableName) + selectedTableName.length + 1,
+ });
+ return false;
+ }
+ }
+ }
+ }
+
+ monaco.editor.setModelMarkers(monaco.editor.getModels()[0], "sql", []);
+ return true;
+ } catch (error) {
+ if (error instanceof Error) {
+ setErrorMarker({
+ message: error.message,
+ startColumn: 1,
+ endColumn: value.length + 1,
+ });
+ }
+ return false;
+ }
+ },
+ [monaco, table, setErrorMarker, worldAddress, chainId],
+ );
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 0608188316..4702c78d44 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -6,18 +6,6 @@ settings:
catalogs:
default:
- '@ark/attest':
- specifier: 0.12.1
- version: 0.12.1
- '@ark/util':
- specifier: 0.2.2
- version: 0.2.2
- abitype:
- specifier: 1.0.6
- version: 1.0.6
- arktype:
- specifier: 2.0.0-beta.6
- version: 2.0.0-beta.6
viem:
specifier: 2.21.19
version: 2.21.19
@@ -495,6 +483,9 @@ importers:
'@latticexyz/world':
specifier: workspace:*
version: link:../world
+ '@monaco-editor/react':
+ specifier: ^4.6.0
+ version: 4.6.0(monaco-editor@0.52.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
'@radix-ui/react-checkbox':
specifier: ^1.1.1
version: 1.1.1(@types/react-dom@18.2.7)(@types/react@18.2.22)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
@@ -546,9 +537,15 @@ importers:
lucide-react:
specifier: ^0.408.0
version: 0.408.0(react@18.2.0)
+ monaco-editor:
+ specifier: ^0.52.0
+ version: 0.52.0
next:
specifier: 14.2.5
version: 14.2.5(@babel/core@7.25.2)(@opentelemetry/api@1.8.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ node-sql-parser:
+ specifier: ^5.3.3
+ version: 5.3.3
nuqs:
specifier: ^1.19.2
version: 1.19.2(next@14.2.5(@babel/core@7.25.2)(@opentelemetry/api@1.8.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))
@@ -567,6 +564,9 @@ importers:
sonner:
specifier: ^1.5.0
version: 1.5.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ sql-autocomplete:
+ specifier: ^1.1.1
+ version: 1.1.1
tailwind-merge:
specifier: ^1.12.0
version: 1.12.0
@@ -821,10 +821,10 @@ importers:
version: 8.3.4
jest:
specifier: ^29.3.1
- version: 29.5.0(@types/node@18.15.11)
+ version: 29.5.0(@types/node@20.12.12)
ts-jest:
specifier: ^29.0.5
- version: 29.0.5(@babel/core@7.21.4)(@jest/types@29.6.3)(babel-jest@29.5.0(@babel/core@7.21.4))(jest@29.5.0(@types/node@18.15.11))(typescript@5.4.2)
+ version: 29.0.5(@babel/core@7.25.2)(@jest/types@29.6.3)(babel-jest@29.5.0(@babel/core@7.25.2))(jest@29.5.0(@types/node@20.12.12))(typescript@5.4.2)
tsup:
specifier: ^6.7.0
version: 6.7.0(postcss@8.4.47)(typescript@5.4.2)
@@ -1200,10 +1200,10 @@ importers:
version: 27.4.1
jest:
specifier: ^29.3.1
- version: 29.5.0(@types/node@20.12.12)
+ version: 29.5.0(@types/node@18.15.11)
ts-jest:
specifier: ^29.0.5
- version: 29.0.5(@babel/core@7.25.2)(@jest/types@29.6.3)(babel-jest@29.5.0(@babel/core@7.25.2))(jest@29.5.0(@types/node@20.12.12))(typescript@5.4.2)
+ version: 29.0.5(@babel/core@7.21.4)(@jest/types@29.6.3)(babel-jest@29.5.0(@babel/core@7.21.4))(jest@29.5.0(@types/node@18.15.11))(typescript@5.4.2)
tsup:
specifier: ^6.7.0
version: 6.7.0(postcss@8.4.47)(typescript@5.4.2)
@@ -3484,6 +3484,18 @@ packages:
resolution: {integrity: sha512-g2REf+xSt0OZfMoNNdC4+/Yy8eP3KUqvIArel54XRFKPoXbHI6+YjFfrLtfykWBjffOp7DTfIc3Kvk5TLfuiyg==}
engines: {node: '>=16.0.0'}
+ '@monaco-editor/loader@1.4.0':
+ resolution: {integrity: sha512-00ioBig0x642hytVspPl7DbQyaSWRaolYie/UFNjoTdvoKPzo6xrXLhTk9ixgIKcLH5b5vDOjVNiGyY+uDCUlg==}
+ peerDependencies:
+ monaco-editor: '>= 0.21.0 < 1'
+
+ '@monaco-editor/react@4.6.0':
+ resolution: {integrity: sha512-RFkU9/i7cN2bsq/iTkurMWOEErmYcY6JiQI3Jn+WeR/FGISH8JbHERjpS9oRuSOPvDMJI0Z8nJeKkbOs9sBYQw==}
+ peerDependencies:
+ monaco-editor: '>= 0.25.0 < 1'
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0
+ react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+
'@motionone/animation@10.18.0':
resolution: {integrity: sha512-9z2p5GFGCm0gBsZbi8rVMOAJCtw1WqBTIPw3ozk06gDvZInBPIsQcHgYogEJ4yuHJ+akuW8g1SEIOpTOvYs8hw==}
@@ -5206,6 +5218,9 @@ packages:
'@types/openurl@1.0.0':
resolution: {integrity: sha512-fUHH4T8FmEl3NBtGbUYYzMo1Ev47uVCVEGVjVNjorOMzgjls6zH82yr/zqkkcEOHY2HUC5PZ8dRFwGed/NR7wQ==}
+ '@types/pegjs@0.10.6':
+ resolution: {integrity: sha512-eLYXDbZWXh2uxf+w8sXS8d6KSoXTswfps6fvCUuVAGN8eRpfe7h9eSRydxiSJvo9Bf+GzifsDOr9TMQlmJdmkw==}
+
'@types/prettier@2.7.2':
resolution: {integrity: sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==}
@@ -5670,9 +5685,15 @@ packages:
resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==}
engines: {node: '>=12'}
+ antlr4-c3@1.1.16:
+ resolution: {integrity: sha512-3CZQ54JPyo6lkZYDOXaKUsy5KNFucveocvRy+03R7zJQbYOUr4Z6lFeBWzkxJXLitc7yQYe7OHbB6snyp7IJvQ==}
+
antlr4@4.7.1:
resolution: {integrity: sha512-haHyTW7Y9joE5MVs37P2lNYfU2RWBLfcRDD8OWldcdZm5TiCE91B5Xl1oWSwiDUSd4rlExpt2pu1fksYQjRBYQ==}
+ antlr4ts-sql@1.1.0:
+ resolution: {integrity: sha512-94+8/+hsPI/OLG0WRGqW88/gqz+xxrSLSz/jGqS8Xl7tYWwUj/cBB4D/QRmNezYLqEaUzMHhTeQn5hzrpC2wNQ==}
+
antlr4ts@0.5.0-alpha.4:
resolution: {integrity: sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==}
@@ -5917,6 +5938,10 @@ packages:
better-sqlite3@8.6.0:
resolution: {integrity: sha512-jwAudeiTMTSyby+/SfbHDebShbmC2MCH8mU2+DXi0WJfv13ypEJm47cd3kljmy/H130CazEvkf2Li//ewcMJ1g==}
+ big-integer@1.6.52:
+ resolution: {integrity: sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==}
+ engines: {node: '>=0.6'}
+
binary-extensions@2.2.0:
resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==}
engines: {node: '>=8'}
@@ -7039,11 +7064,13 @@ packages:
eslint@5.16.0:
resolution: {integrity: sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==}
engines: {node: ^6.14.0 || ^8.10.0 || >=9.10.0}
+ deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options.
hasBin: true
eslint@8.57.0:
resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options.
hasBin: true
espree@5.0.1:
@@ -8868,6 +8895,9 @@ packages:
modern-ahocorasick@1.0.1:
resolution: {integrity: sha512-yoe+JbhTClckZ67b2itRtistFKf8yPYelHLc7e5xAwtNAXxM6wJTUx2C7QeVSJFDzKT7bCIFyBVybPMKvmB9AA==}
+ monaco-editor@0.52.0:
+ resolution: {integrity: sha512-OeWhNpABLCeTqubfqLMXGsqf6OmPU6pHM85kF3dhy6kq5hnhuVS1p3VrEW/XhWHc71P2tHyS5JFySD8mgs1crw==}
+
motion@10.16.2:
resolution: {integrity: sha512-p+PurYqfUdcJZvtnmAqu5fJgV2kR0uLFQuBKtLeFVTrYEVllI99tiOTSefVNYuip9ELTEkepIIDftNdze76NAQ==}
@@ -9014,6 +9044,10 @@ packages:
node-releases@2.0.18:
resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==}
+ node-sql-parser@5.3.3:
+ resolution: {integrity: sha512-KRVnneHhy5zaylFmtojHxpXqjmThFSOn7n6x1J/38gTE6NL5Wj/yY7hjbFqpYcpPwIpXM7sFDnvV3ejxmoPAJQ==}
+ engines: {node: '>=8'}
+
node-stream-zip@1.15.0:
resolution: {integrity: sha512-LN4fydt9TqhZhThkZIVQnF9cwjU3qmUH9h78Mx/K7d3VvfRqqwthLwJEUOEL0QPZ0XQmNN7be5Ggit5+4dq3Bw==}
engines: {node: '>=0.12.0'}
@@ -10430,6 +10464,9 @@ packages:
sprintf-js@1.0.3:
resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==}
+ sql-autocomplete@1.1.1:
+ resolution: {integrity: sha512-0Fz1utcPC5m6qQiFDhIgyqNk8J0DyGBtv59++uUjkjM9vOdv6ugGuM+ZcjY0qyG9ofLmT6wLHSpx+2h6jm0t6Q==}
+
sql.js@1.8.0:
resolution: {integrity: sha512-3HD8pSkZL+5YvYUI8nlvNILs61ALqq34xgmF+BHpqxe68yZIJ1H+sIVIODvni25+CcxHUxDyrTJUL0lE/m7afw==}
@@ -10451,6 +10488,9 @@ packages:
resolution: {integrity: sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==}
engines: {node: '>=6'}
+ state-local@1.0.7:
+ resolution: {integrity: sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==}
+
statuses@1.5.0:
resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==}
engines: {node: '>= 0.6'}
@@ -11927,7 +11967,7 @@ snapshots:
'@smithy/util-middleware': 2.2.0
'@smithy/util-retry': 2.2.0
'@smithy/util-utf8': 2.3.0
- tslib: 2.6.2
+ tslib: 2.7.0
transitivePeerDependencies:
- aws-crt
@@ -11939,7 +11979,7 @@ snapshots:
'@smithy/smithy-client': 2.5.1
'@smithy/types': 2.12.0
fast-xml-parser: 4.2.5
- tslib: 2.6.2
+ tslib: 2.7.0
'@aws-sdk/credential-provider-env@3.535.0':
dependencies:
@@ -11990,7 +12030,7 @@ snapshots:
'@smithy/property-provider': 2.2.0
'@smithy/shared-ini-file-loader': 2.4.0
'@smithy/types': 2.12.0
- tslib: 2.6.2
+ tslib: 2.7.0
transitivePeerDependencies:
- aws-crt
@@ -12031,20 +12071,20 @@ snapshots:
'@aws-sdk/types': 3.535.0
'@smithy/protocol-http': 3.3.0
'@smithy/types': 2.12.0
- tslib: 2.6.2
+ tslib: 2.7.0
'@aws-sdk/middleware-logger@3.535.0':
dependencies:
'@aws-sdk/types': 3.535.0
'@smithy/types': 2.12.0
- tslib: 2.6.2
+ tslib: 2.7.0
'@aws-sdk/middleware-recursion-detection@3.535.0':
dependencies:
'@aws-sdk/types': 3.535.0
'@smithy/protocol-http': 3.3.0
'@smithy/types': 2.12.0
- tslib: 2.6.2
+ tslib: 2.7.0
'@aws-sdk/middleware-user-agent@3.540.0':
dependencies:
@@ -12052,7 +12092,7 @@ snapshots:
'@aws-sdk/util-endpoints': 3.540.0
'@smithy/protocol-http': 3.3.0
'@smithy/types': 2.12.0
- tslib: 2.6.2
+ tslib: 2.7.0
'@aws-sdk/region-config-resolver@3.535.0':
dependencies:
@@ -12061,7 +12101,7 @@ snapshots:
'@smithy/types': 2.12.0
'@smithy/util-config-provider': 2.3.0
'@smithy/util-middleware': 2.2.0
- tslib: 2.6.2
+ tslib: 2.7.0
'@aws-sdk/token-providers@3.556.0(@aws-sdk/credential-provider-node@3.556.0)':
dependencies:
@@ -12078,14 +12118,14 @@ snapshots:
'@aws-sdk/types@3.535.0':
dependencies:
'@smithy/types': 2.12.0
- tslib: 2.6.2
+ tslib: 2.7.0
'@aws-sdk/util-endpoints@3.540.0':
dependencies:
'@aws-sdk/types': 3.535.0
'@smithy/types': 2.12.0
'@smithy/util-endpoints': 1.2.0
- tslib: 2.6.2
+ tslib: 2.7.0
'@aws-sdk/util-locate-window@3.535.0':
dependencies:
@@ -12096,14 +12136,14 @@ snapshots:
'@aws-sdk/types': 3.535.0
'@smithy/types': 2.12.0
bowser: 2.11.0
- tslib: 2.6.2
+ tslib: 2.7.0
'@aws-sdk/util-user-agent-node@3.535.0':
dependencies:
'@aws-sdk/types': 3.535.0
'@smithy/node-config-provider': 2.3.0
'@smithy/types': 2.12.0
- tslib: 2.6.2
+ tslib: 2.7.0
'@aws-sdk/util-utf8-browser@3.259.0':
dependencies:
@@ -12385,7 +12425,7 @@ snapshots:
'@babel/helper-validator-identifier': 7.24.7
chalk: 2.4.2
js-tokens: 4.0.0
- picocolors: 1.0.1
+ picocolors: 1.1.0
'@babel/parser@7.21.4':
dependencies:
@@ -14370,6 +14410,18 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ '@monaco-editor/loader@1.4.0(monaco-editor@0.52.0)':
+ dependencies:
+ monaco-editor: 0.52.0
+ state-local: 1.0.7
+
+ '@monaco-editor/react@4.6.0(monaco-editor@0.52.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
+ dependencies:
+ '@monaco-editor/loader': 1.4.0(monaco-editor@0.52.0)
+ monaco-editor: 0.52.0
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+
'@motionone/animation@10.18.0':
dependencies:
'@motionone/easing': 10.18.0
@@ -15882,7 +15934,7 @@ snapshots:
'@smithy/types': 2.12.0
'@smithy/util-config-provider': 2.3.0
'@smithy/util-middleware': 2.2.0
- tslib: 2.6.2
+ tslib: 2.7.0
'@smithy/core@1.4.2':
dependencies:
@@ -15893,7 +15945,7 @@ snapshots:
'@smithy/smithy-client': 2.5.1
'@smithy/types': 2.12.0
'@smithy/util-middleware': 2.2.0
- tslib: 2.6.2
+ tslib: 2.7.0
'@smithy/credential-provider-imds@2.3.0':
dependencies:
@@ -15909,19 +15961,19 @@ snapshots:
'@smithy/querystring-builder': 2.2.0
'@smithy/types': 2.12.0
'@smithy/util-base64': 2.3.0
- tslib: 2.6.2
+ tslib: 2.7.0
'@smithy/hash-node@2.2.0':
dependencies:
'@smithy/types': 2.12.0
'@smithy/util-buffer-from': 2.2.0
'@smithy/util-utf8': 2.3.0
- tslib: 2.6.2
+ tslib: 2.7.0
'@smithy/invalid-dependency@2.2.0':
dependencies:
'@smithy/types': 2.12.0
- tslib: 2.6.2
+ tslib: 2.7.0
'@smithy/is-array-buffer@2.2.0':
dependencies:
@@ -15931,7 +15983,7 @@ snapshots:
dependencies:
'@smithy/protocol-http': 3.3.0
'@smithy/types': 2.12.0
- tslib: 2.6.2
+ tslib: 2.7.0
'@smithy/middleware-endpoint@2.5.1':
dependencies:
@@ -15941,7 +15993,7 @@ snapshots:
'@smithy/types': 2.12.0
'@smithy/url-parser': 2.2.0
'@smithy/util-middleware': 2.2.0
- tslib: 2.6.2
+ tslib: 2.7.0
'@smithy/middleware-retry@2.3.1':
dependencies:
@@ -15952,25 +16004,25 @@ snapshots:
'@smithy/types': 2.12.0
'@smithy/util-middleware': 2.2.0
'@smithy/util-retry': 2.2.0
- tslib: 2.6.2
+ tslib: 2.7.0
uuid: 9.0.1
'@smithy/middleware-serde@2.3.0':
dependencies:
'@smithy/types': 2.12.0
- tslib: 2.6.2
+ tslib: 2.7.0
'@smithy/middleware-stack@2.2.0':
dependencies:
'@smithy/types': 2.12.0
- tslib: 2.6.2
+ tslib: 2.7.0
'@smithy/node-config-provider@2.3.0':
dependencies:
'@smithy/property-provider': 2.2.0
'@smithy/shared-ini-file-loader': 2.4.0
'@smithy/types': 2.12.0
- tslib: 2.6.2
+ tslib: 2.7.0
'@smithy/node-http-handler@2.5.0':
dependencies:
@@ -15978,7 +16030,7 @@ snapshots:
'@smithy/protocol-http': 3.3.0
'@smithy/querystring-builder': 2.2.0
'@smithy/types': 2.12.0
- tslib: 2.6.2
+ tslib: 2.7.0
'@smithy/property-provider@2.2.0':
dependencies:
@@ -15988,7 +16040,7 @@ snapshots:
'@smithy/protocol-http@3.3.0':
dependencies:
'@smithy/types': 2.12.0
- tslib: 2.6.2
+ tslib: 2.7.0
'@smithy/querystring-builder@2.2.0':
dependencies:
@@ -16018,7 +16070,7 @@ snapshots:
'@smithy/util-middleware': 2.2.0
'@smithy/util-uri-escape': 2.2.0
'@smithy/util-utf8': 2.3.0
- tslib: 2.6.2
+ tslib: 2.7.0
'@smithy/smithy-client@2.5.1':
dependencies:
@@ -16027,36 +16079,36 @@ snapshots:
'@smithy/protocol-http': 3.3.0
'@smithy/types': 2.12.0
'@smithy/util-stream': 2.2.0
- tslib: 2.6.2
+ tslib: 2.7.0
'@smithy/types@2.12.0':
dependencies:
- tslib: 2.6.2
+ tslib: 2.7.0
'@smithy/url-parser@2.2.0':
dependencies:
'@smithy/querystring-parser': 2.2.0
'@smithy/types': 2.12.0
- tslib: 2.6.2
+ tslib: 2.7.0
'@smithy/util-base64@2.3.0':
dependencies:
'@smithy/util-buffer-from': 2.2.0
'@smithy/util-utf8': 2.3.0
- tslib: 2.6.2
+ tslib: 2.7.0
'@smithy/util-body-length-browser@2.2.0':
dependencies:
- tslib: 2.6.2
+ tslib: 2.7.0
'@smithy/util-body-length-node@2.3.0':
dependencies:
- tslib: 2.6.2
+ tslib: 2.7.0
'@smithy/util-buffer-from@2.2.0':
dependencies:
'@smithy/is-array-buffer': 2.2.0
- tslib: 2.6.2
+ tslib: 2.7.0
'@smithy/util-config-provider@2.3.0':
dependencies:
@@ -16068,7 +16120,7 @@ snapshots:
'@smithy/smithy-client': 2.5.1
'@smithy/types': 2.12.0
bowser: 2.11.0
- tslib: 2.6.2
+ tslib: 2.7.0
'@smithy/util-defaults-mode-node@2.3.1':
dependencies:
@@ -16078,13 +16130,13 @@ snapshots:
'@smithy/property-provider': 2.2.0
'@smithy/smithy-client': 2.5.1
'@smithy/types': 2.12.0
- tslib: 2.6.2
+ tslib: 2.7.0
'@smithy/util-endpoints@1.2.0':
dependencies:
'@smithy/node-config-provider': 2.3.0
'@smithy/types': 2.12.0
- tslib: 2.6.2
+ tslib: 2.7.0
'@smithy/util-hex-encoding@2.2.0':
dependencies:
@@ -16093,13 +16145,13 @@ snapshots:
'@smithy/util-middleware@2.2.0':
dependencies:
'@smithy/types': 2.12.0
- tslib: 2.6.2
+ tslib: 2.7.0
'@smithy/util-retry@2.2.0':
dependencies:
'@smithy/service-error-classification': 2.1.5
'@smithy/types': 2.12.0
- tslib: 2.6.2
+ tslib: 2.7.0
'@smithy/util-stream@2.2.0':
dependencies:
@@ -16119,7 +16171,7 @@ snapshots:
'@smithy/util-utf8@2.3.0':
dependencies:
'@smithy/util-buffer-from': 2.2.0
- tslib: 2.6.2
+ tslib: 2.7.0
'@snyk/github-codeowners@1.1.0':
dependencies:
@@ -16477,6 +16529,8 @@ snapshots:
dependencies:
'@types/node': 18.15.11
+ '@types/pegjs@0.10.6': {}
+
'@types/prettier@2.7.2': {}
'@types/prop-types@15.7.5': {}
@@ -17273,8 +17327,16 @@ snapshots:
ansi-styles@6.2.1: {}
+ antlr4-c3@1.1.16:
+ dependencies:
+ antlr4ts: 0.5.0-alpha.4
+
antlr4@4.7.1: {}
+ antlr4ts-sql@1.1.0:
+ dependencies:
+ antlr4ts: 0.5.0-alpha.4
+
antlr4ts@0.5.0-alpha.4: {}
any-promise@1.3.0: {}
@@ -17635,6 +17697,8 @@ snapshots:
bindings: 1.5.0
prebuild-install: 7.1.1
+ big-integer@1.6.52: {}
+
binary-extensions@2.2.0: {}
bindings@1.5.0:
@@ -18851,7 +18915,7 @@ snapshots:
debug: 4.3.7
enhanced-resolve: 5.17.1
eslint: 8.57.0
- eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.1.1(eslint@8.57.0)(typescript@5.4.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.1.1(eslint@8.57.0)(typescript@5.4.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0)
+ eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.1.1(eslint@8.57.0)(typescript@5.4.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.1.1(eslint@8.57.0)(typescript@5.4.2))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
fast-glob: 3.3.2
get-tsconfig: 4.7.5
@@ -18863,7 +18927,7 @@ snapshots:
- eslint-import-resolver-webpack
- supports-color
- eslint-module-utils@2.8.1(@typescript-eslint/parser@7.1.1(eslint@8.57.0)(typescript@5.4.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.1.1(eslint@8.57.0)(typescript@5.4.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0):
+ eslint-module-utils@2.8.1(@typescript-eslint/parser@7.1.1(eslint@8.57.0)(typescript@5.4.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0):
dependencies:
debug: 3.2.7
optionalDependencies:
@@ -18884,7 +18948,7 @@ snapshots:
doctrine: 2.1.0
eslint: 8.57.0
eslint-import-resolver-node: 0.3.9
- eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.1.1(eslint@8.57.0)(typescript@5.4.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.1.1(eslint@8.57.0)(typescript@5.4.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0)
+ eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.1.1(eslint@8.57.0)(typescript@5.4.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
hasown: 2.0.2
is-core-module: 2.15.0
is-glob: 4.0.3
@@ -21466,6 +21530,8 @@ snapshots:
modern-ahocorasick@1.0.1: {}
+ monaco-editor@0.52.0: {}
+
motion@10.16.2:
dependencies:
'@motionone/animation': 10.18.0
@@ -21600,6 +21666,11 @@ snapshots:
node-releases@2.0.18: {}
+ node-sql-parser@5.3.3:
+ dependencies:
+ '@types/pegjs': 0.10.6
+ big-integer: 1.6.52
+
node-stream-zip@1.15.0: {}
nopt@6.0.0:
@@ -23079,6 +23150,11 @@ snapshots:
sprintf-js@1.0.3: {}
+ sql-autocomplete@1.1.1:
+ dependencies:
+ antlr4-c3: 1.1.16
+ antlr4ts-sql: 1.1.0
+
sql.js@1.8.0: {}
ssri@9.0.1:
@@ -23097,6 +23173,8 @@ snapshots:
dependencies:
type-fest: 0.7.1
+ state-local@1.0.7: {}
+
statuses@1.5.0: {}
statuses@2.0.1: {}
@@ -23822,13 +23900,13 @@ snapshots:
dependencies:
browserslist: 4.23.0
escalade: 3.1.2
- picocolors: 1.0.0
+ picocolors: 1.1.0
update-browserslist-db@1.1.0(browserslist@4.23.3):
dependencies:
browserslist: 4.23.3
escalade: 3.1.2
- picocolors: 1.0.1
+ picocolors: 1.1.0
uqr@0.1.2: {}