@axiomdb/babel-plugin
v0.1.1
Published
Babel plugin that transforms sql`` tagged templates into AxiomDB builder calls
Readme
@axiomdb/babel-plugin
Babel plugin that transforms sql tagged templates and dialect tags (client.psql, client.mysql, client.mssql) into parameterized queries at build time.
Installation
npm install @axiomdb/babel-pluginUsage
Add to your Babel config:
{
"plugins": ["@axiomdb/babel-plugin"]
}Then write SQL using dialect tags on a client instance:
const users = await client.psql`
SELECT id, name FROM users WHERE active = ${true}
`;The plugin transforms this at build time into a parameterized client.__execute() call. Values are never interpolated into the SQL string.
How it works
The plugin handles two distinct tag styles:
Dialect tags (client.psql, client.mysql, client.mssql)
Dialect tags compile to a direct client.__execute(sql, params) call with dialect-appropriate placeholders:
// Input
const users = await client.psql`
SELECT id, name FROM users WHERE active = ${active}
`;
// Compiled output (PostgreSQL)
const users = await client.__execute(
"SELECT id, name FROM users WHERE active = $1",
[active]
);
// MySQL uses ?
// MSSQL uses @p1, @p2, ...Plain sql tag
The sql tag compiles to a query builder chain from @axiomdb/core. This is useful for programmatic query construction without a database client:
// Input
const query = sql`SELECT id, name FROM users WHERE active = ${true}`;
// Compiled output (simplified)
table("users")
.select({ id: true, name: true })
.where({ column: "active", op: EQ, value: true })
.execute();The plain sql tag only supports single statements. Multi-statement SQL requires a dialect tag.
Plugin options
{
"plugins": [
["@axiomdb/babel-plugin", {
"tag": "sql",
"importSource": "@axiomdb/core",
"execute": true,
"dialectTags": ["psql", "mysql", "mssql"],
"validate": false,
"schemaPath": "./axiomdb-schema.json"
}]
]
}| Option | Default | Description |
|--------|---------|-------------|
| tag | "sql" | Identifier name for the plain SQL tag |
| importSource | "@axiomdb/core" | Package to import query builder functions from |
| execute | true | Append .execute() to plain sql tag builder chains |
| dialectTags | ["psql", "mysql", "mssql"] | Member expression tag names recognized on client objects |
| validate | false | Enable runtime row validation (typically dev-only) |
| schemaPath | — | Path to axiomdb-schema.json (required when validate is true) |
Conditional fragments
Inside a dialect tag, interpolation expressions can contain sql fragments combined with &&, ||, ??, and ternary operators. When the condition is falsy, the fragment is omitted entirely from the SQL string and its parameters are excluded.
&& (conditional include)
const users = await client.psql`
SELECT id, name FROM users
WHERE deleted_at IS NULL
${search && sql`AND name ILIKE ${`%${search}%`}`}
ORDER BY created_at DESC
`;?? (nullish fallback)
const users = await client.psql`
SELECT id, name FROM users
${orderClause ?? sql`ORDER BY id ASC`}
`;Ternary (conditional branch)
const users = await client.psql`
SELECT id, name FROM users
${isAdmin ? sql`WHERE role = 'admin'` : sql`WHERE active = true`}
`;Multi-statement queries
Dialect tags support multiple SQL statements separated by semicolons. Results are returned as a tuple of arrays, one per statement.
const [revenue, recentOrders] = await client.psql`
SELECT SUM(total) AS total_revenue FROM orders WHERE status != ${excludedStatus};
SELECT id, total, status FROM orders ORDER BY created_at DESC LIMIT ${recentLimit}
`;Multi-statement SQL is compiled to a client.__executeBatch() call.
Bulk inserts
Pass an array of objects to a VALUES clause for multi-row inserts. The plugin extracts keys from the array type and expands them into parameterized value tuples.
const items = [
{ order_id: 1, product: "Widget", quantity: 3, price: 9.99 },
{ order_id: 1, product: "Gadget", quantity: 1, price: 24.99 },
];
await client.psql`
INSERT INTO order_items (order_id, product, quantity, price)
VALUES ${items}
`;Runtime validation
When validate is enabled with a schemaPath, the plugin generates validator functions that check result rows against the schema types at runtime. This is useful during development to catch schema mismatches early.
{
"plugins": [
["@axiomdb/babel-plugin", {
"validate": true,
"schemaPath": "./axiomdb-schema.json"
}]
]
}The schema JSON file is generated by @axiomdb/schema. When validation is active, the plugin also infers TypeScript types for query results and wraps them with type assertions.
Next.js
A built-in wrapper handles all the webpack/babel-loader configuration. Install babel-loader as a dev dependency, then:
// next.config.mjs
import { withAxiomDB } from "@axiomdb/babel-plugin/next";
export default withAxiomDB({});Options:
withAxiomDB(nextConfig, {
importSource: "@axiomdb/core", // default
include: ["src"], // paths to transform (default: ["src", "app", "pages"])
validate: true, // enable runtime row validation
schemaPath: "./schema.json", // path to axiomdb-schema.json
});License
MIT
