diff --git a/.cursorrules b/.cursorrules
new file mode 100644
index 0000000..a167dc3
--- /dev/null
+++ b/.cursorrules
@@ -0,0 +1,20 @@
+# Principles
+
+- Follow the project's existing conventions and patterns.
+- Prefer strong typing throughout the codebase.
+- Avoid using `any` or `unknown` types unless absolutely necessary.
+- Do not use type assertions; instead, define or refine types as needed.
+- Create and use explicit types or interfaces for complex structures.
+- Prefer using node-sql-parser's API and types for SQL parsing and analysis.
+
+# Code Style
+
+- Prefer concise code changes and minimal extra explanatory text.
+- Keep code changes minimal and focused on the requested functionality.
+
+# Development Workflow
+
+- Always use `pnpm test` or its variations to run tests.
+- Always use `pnpm lint` to run linting.
+- Always use `pnpm typecheck` to run typechecking.
+- Ensure all code changes pass tests, linting, and typechecking before merging.
diff --git a/.github/workflows/demo.yml b/.github/workflows/demo.yml
index 7c0b895..c8ce21c 100644
--- a/.github/workflows/demo.yml
+++ b/.github/workflows/demo.yml
@@ -16,7 +16,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
- name: ⎔ Setup pnpm
uses: pnpm/action-setup@v4
@@ -39,7 +39,7 @@ jobs:
uses: actions/configure-pages@v5
- name: 📤 Upload artifact
- uses: actions/upload-pages-artifact@v3
+ uses: actions/upload-pages-artifact@v4
with:
path: './demo/dist'
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 365889d..f73dd70 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -12,7 +12,7 @@ jobs:
release:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
with:
fetch-depth: 0
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index ab98c6e..5a20e21 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -21,7 +21,7 @@ jobs:
pull-requests: write
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
- name: ⎔ Setup pnpm
uses: pnpm/action-setup@v4
@@ -46,7 +46,7 @@ jobs:
security:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
- name: 🔍 Run CodeQL
uses: github/codeql-action/init@v3
@@ -60,7 +60,7 @@ jobs:
spelling:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
- name: 🔍 Spell Check Repo
- uses: crate-ci/typos@v1.35.3
+ uses: crate-ci/typos@v1.35.5
diff --git a/demo/custom-renderers.ts b/demo/custom-renderers.ts
index 1949c20..207d9a6 100644
--- a/demo/custom-renderers.ts
+++ b/demo/custom-renderers.ts
@@ -30,7 +30,7 @@ interface TableMetadata {
indexes: IndexMetadata[];
}
-export type Schema = "users" | "posts" | "orders" | "customers" | "categories";
+export type Schema = "users" | "posts" | "orders" | "customers" | "categories" | "Users_Posts";
export const tableTooltipRenderer = (data: NamespaceTooltipData) => {
// Show table name, columns, description, primary key, foreign key, index, unique, check, default, comment
@@ -292,6 +292,24 @@ function getTableMetadata(tableName: string): TableMetadata {
{ name: "idx_categories_parent", columns: ["parent_id"], unique: false },
],
},
+ Users_Posts: {
+ description: "User-Post relationships",
+ rowCount: "1,234",
+ columns: {
+ user_id: { type: "INT", notNull: true, foreignKey: true, comment: "User who posted" },
+ post_id: {
+ type: "INT",
+ notNull: true,
+ foreignKey: true,
+ comment: "Post being commented on",
+ },
+ },
+ foreignKeys: [
+ { column: "user_id", referencedTable: "users", referencedColumn: "id" },
+ { column: "post_id", referencedTable: "posts", referencedColumn: "id" },
+ ],
+ indexes: [{ name: "idx_users_posts_user", columns: ["user_id"], unique: false }],
+ },
};
return (
diff --git a/demo/data.ts b/demo/data.ts
new file mode 100644
index 0000000..d0d95c7
--- /dev/null
+++ b/demo/data.ts
@@ -0,0 +1,81 @@
+import type { Schema } from "./custom-renderers";
+
+// Default SQL content for the demo
+export const defaultSqlDoc = `-- Welcome to the SQL Editor Demo!
+-- Try editing the queries below to see real-time validation
+
+WITH cte_name AS (
+ SELECT * FROM users
+)
+
+-- Valid queries (no errors):
+SELECT id, name, email
+FROM users
+WHERE active = true
+ORDER BY created_at DESC;
+
+SELECT
+ u.name,
+ p.title,
+ p.created_at
+FROM users u
+JOIN posts p ON u.id = p.user_id
+WHERE u.status = 'active'
+ AND p.published = true
+LIMIT 10;
+
+-- Try editing these to create syntax errors:
+-- Uncomment the lines below to see error highlighting
+
+-- SELECT * FROM; -- Missing table name
+-- SELECT * FORM users; -- Typo in FROM keyword
+-- INSERT INTO VALUES (1, 2); -- Missing table name
+-- UPDATE SET name = 'test'; -- Missing table name
+
+-- Complex example with subquery:
+SELECT
+ customer_id,
+ order_date,
+ total_amount,
+ (SELECT AVG(total_amount) FROM orders) as avg_order_value
+FROM orders
+WHERE order_date >= '2024-01-01'
+ AND total_amount > (
+ SELECT AVG(total_amount) * 0.8
+ FROM orders
+ WHERE YEAR(order_date) = 2024
+ )
+ORDER BY total_amount DESC;
+`;
+
+export const schema: Record = {
+ // Users table
+ users: ["id", "name", "email", "active", "status", "created_at", "updated_at", "profile_id"],
+ // Posts table
+ posts: [
+ "id",
+ "title",
+ "content",
+ "user_id",
+ "published",
+ "created_at",
+ "updated_at",
+ "category_id",
+ ],
+ // Orders table
+ orders: [
+ "id",
+ "customer_id",
+ "order_date",
+ "total_amount",
+ "status",
+ "shipping_address",
+ "created_at",
+ ],
+ // Customers table (additional example)
+ customers: ["id", "first_name", "last_name", "email", "phone", "address", "city", "country"],
+ // Categories table
+ categories: ["id", "name", "description", "parent_id"],
+ // Users_Posts table
+ Users_Posts: ["user_id", "post_id"],
+};
diff --git a/demo/index.html b/demo/index.html
index 0dc206b..b038d16 100644
--- a/demo/index.html
+++ b/demo/index.html
@@ -34,7 +34,7 @@ SQL Editor with Diagnostics
-