@playwright-labs/ts-plugin-sql
v1.0.0
Published
TypeScript language service plugin for SQL tagged template literals — autocomplete, diagnostics, and hover info
Maintainers
Readme
@playwright-labs/ts-plugin-sql
TypeScript language service plugin for SQL tagged template literals — autocomplete, real-time diagnostics, and hover info directly in your editor.
What it does
When you write SQL inside the sql tag, the plugin enhances your editor with:
| Feature | Description |
|---|---|
| Autocompletion | Table names, column names (filtered by tables in scope), and SQL keywords |
| Diagnostics | Structural validation — missing FROM, wrong UPDATE/INSERT syntax, etc. |
| Hover info | Hover over a table or column name to see its schema definition |
All features are schema-aware: the plugin reads your actual database schema (either from a generated file or inline JSON) so suggestions always reflect your real tables and columns.
Relationship to sql-core and fixture-sql
This package is part of a three-package system. See the diagram below for how they fit together.
┌─────────────────────────────────────────────────────────────────┐
│ @playwright-labs/sql-core │
│ ───────────────────────────────────────────────────────────── │
│ • sql("…") / sql`…` / sql(["…"]) — typed sql function │
│ • SqlClient / SqlAdapter interfaces │
│ • SQLType.ts — compile-time FSM: validates SQL grammar, │
│ infers ? / $N param tuples, catches gaps in $N sequences │
│ • Adapters: sqlite / pg / mysql │
└──────────────┬──────────────────────────┬───────────────────────┘
│ │
▼ ▼
┌──────────────────────────┐ ┌──────────────────────────────────┐
│ @playwright-labs/ │ │ @playwright-labs/ts-plugin-sql │
│ fixture-sql │ │ ────────────────────────────── │
│ ────────────────────── │ │ Re-exports sql from sql-core. │
│ Re-exports sql from │ │ Adds TypeScript language server │
│ sql-core. Adds │ │ plugin that provides: │
│ Playwright fixtures, │ │ • SQL keyword completions │
│ auto-cleanup, and │ │ • Table/column completions │
│ custom matchers. │ │ from your schema file │
│ │ │ • Structural diagnostics │
└──────────────────────────┘ │ • Hover info │
└──────────────────────────────────┘sql re-export: this package re-exports the sql function from @playwright-labs/sql-core. You can import sql from either package — they are the same function.
Schema workflow:
live DB ──► pnpm fixture-sql pull ──► db-types.ts ──► tsconfig "schemaFile" ──► editor features
│
└──► import type { UsersRow } ──► typed query resultsInstallation
pnpm add -D @playwright-labs/ts-plugin-sqlTypeScript is a peer dependency (>=5.0.0):
pnpm add -D typescriptConfiguration
Add the plugin to your tsconfig.json plugins array:
{
"compilerOptions": {
"plugins": [
{
"name": "@playwright-labs/ts-plugin-sql",
"tag": "sql",
"schemaFile": "./src/db-types.ts"
}
]
}
}Options
| Option | Type | Default | Description |
|---|---|---|---|
| tag | string | "sql" | Name of the tagged template literal to enhance |
| schemaFile | string | — | Path to a generated db-types.ts file (see below) |
| schema | object | — | Inline schema as a JSON object (alternative to schemaFile) |
schemaFile takes precedence over schema when both are present.
Editor setup
The plugin runs inside TypeScript's language server (tsserver). Most editors that support TypeScript will pick it up automatically once tsconfig.json is configured.
VS Code: Make sure you are using the workspace TypeScript version, not VS Code's built-in one. Open the command palette and run TypeScript: Select TypeScript Version → Use Workspace Version.
Schema
The plugin needs to know your table and column structure to provide schema-aware completions and hover info.
Option A — Generated schema file (recommended)
Use the pull CLI from @playwright-labs/fixture-sql to introspect a live database and generate typed row interfaces:
pnpm fixture-sql pull --adapter sqlite --url ./dev.db --out ./src/db-types.ts
pnpm fixture-sql pull --adapter pg --url postgresql://user:pass@localhost/mydb --out ./src/db-types.ts
pnpm fixture-sql pull --adapter mysql --url mysql://user:pass@localhost/mydb --out ./src/db-types.tsThe generated file looks like this:
// Auto-generated by @playwright-labs/fixture-sql/bin/pull
export interface UsersRow {
id: number;
name: string;
email: string | null;
}
export interface PostsRow {
id: number;
user_id: number;
title: string;
body: string | null;
}
export type Tables = {
users: UsersRow;
posts: PostsRow;
};Point schemaFile at this file and the plugin reads it automatically:
{
"compilerOptions": {
"plugins": [
{
"name": "@playwright-labs/ts-plugin-sql",
"schemaFile": "./src/db-types.ts"
}
]
}
}Option B — Inline schema
Define the schema directly in tsconfig.json for small projects or when a live database is not available:
{
"compilerOptions": {
"plugins": [
{
"name": "@playwright-labs/ts-plugin-sql",
"schema": {
"users": {
"id": "number",
"name": "string",
"email": "string | null"
},
"posts": {
"id": "number",
"user_id": "number",
"title": "string"
}
}
}
]
}
}Usage
Import the sql tag from this package and wrap your SQL strings:
import { sql } from '@playwright-labs/ts-plugin-sql';
// Editor provides autocomplete, diagnostics, and hover inside this template
const query = sql`SELECT id, name FROM users WHERE id = ?`;The sql tag is a re-export of @playwright-labs/sql-core's sql. All three calling forms work:
import { sql } from '@playwright-labs/ts-plugin-sql';
// Tagged template — editor features active, returns string
const q1 = sql`SELECT * FROM users WHERE id = ?`;
// Plain string — compile-time type validation, returns SqlStatement<[unknown]>
const q2 = sql("SELECT * FROM users WHERE id = ?");
// Array form — same compile-time validation as plain string
const q3 = sql(["SELECT * FROM users WHERE id = ?"]);Features in detail
Autocompletion
Completions are context-aware based on the SQL keyword before the cursor:
- After
FROM,JOIN,INTO,UPDATE— table names from your schema - After
SELECT,WHERE,AND,OR,SET— column names from tables referenced in the query - Elsewhere — SQL keywords (
SELECT,WHERE,GROUP BY, etc.)
Diagnostics
The plugin validates SQL structure and reports errors as TypeScript diagnostics (shown as squiggly underlines in your editor):
// Error: SELECT requires a FROM clause
const bad = sql`SELECT id, name`;
// OK
const good = sql`SELECT id, name FROM users`;Validated statement shapes:
SELECT … FROM <table> [JOIN] [WHERE] [GROUP BY] [ORDER BY] [LIMIT]UPDATE <table> SET … [WHERE]DELETE FROM <table> [WHERE]INSERT INTO <table> … VALUES (…)CREATE TABLE <name> (…)
Hover info
Hovering over a table or column name inside a sql template shows schema information:
- Table name → shows the full list of columns with their types
- Column name → shows the column's type and which table it belongs to
Full integration example
import { test, expect } from '@playwright-labs/fixture-sql';
import { pgAdapter } from '@playwright-labs/fixture-sql/pg';
import { sql } from '@playwright-labs/ts-plugin-sql';
import type { UsersRow } from './db-types.js';
test.use({ sqlAdapter: pgAdapter(process.env.DATABASE_URL!) });
test('typed query with IDE support', async ({ sql: client }) => {
// Plugin provides completions and diagnostics here:
const { rows } = await client.query<UsersRow>(
sql("SELECT id, name FROM users WHERE id = $1"),
[1],
);
expect(rows[0]!.name).toBe('Alice');
});License
MIT
