sqlcx-orm 0.1.0 → 0.1.2

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 (2) hide show
  1. package/README.md +207 -0
  2. package/package.json +1 -1
package/README.md ADDED
@@ -0,0 +1,207 @@
1
+ # sqlcx
2
+
3
+ SQL-first, cross-language, type-safe code generator. Write SQL, get typed code.
4
+
5
+ ```bash
6
+ bun add sqlcx-orm
7
+ ```
8
+
9
+ ## What it does
10
+
11
+ You write SQL schemas and annotated queries. sqlcx generates type-safe TypeScript with [TypeBox](https://github.com/sinclairzx81/typebox) validation schemas and typed query functions.
12
+
13
+ ```
14
+ sql/schema.sql --> src/db/schema.ts (TypeBox schemas + types)
15
+ sql/queries/users.sql --> src/db/users.queries.ts (typed query functions)
16
+ src/db/client.ts (DatabaseClient interface)
17
+ ```
18
+
19
+ No runtime. No engine. Just codegen.
20
+
21
+ ## Quick Start
22
+
23
+ ```bash
24
+ # Initialize a project
25
+ bunx sqlcx-orm init
26
+
27
+ # Write your SQL, then generate
28
+ bunx sqlcx-orm generate
29
+ ```
30
+
31
+ ### 1. Define your schema
32
+
33
+ ```sql
34
+ -- sql/schema.sql
35
+ CREATE TABLE users (
36
+ id SERIAL PRIMARY KEY,
37
+ name TEXT NOT NULL,
38
+ email TEXT NOT NULL UNIQUE,
39
+ -- @json({ theme: string, notifications: boolean })
40
+ preferences JSONB,
41
+ -- @enum("admin", "editor", "viewer")
42
+ role TEXT NOT NULL DEFAULT 'viewer',
43
+ created_at TIMESTAMP NOT NULL DEFAULT NOW()
44
+ );
45
+ ```
46
+
47
+ ### 2. Write annotated queries
48
+
49
+ ```sql
50
+ -- sql/queries/users.sql
51
+
52
+ -- name: GetUser :one
53
+ SELECT * FROM users WHERE id = $1;
54
+
55
+ -- name: ListUsers :many
56
+ SELECT id, name, email, role FROM users ORDER BY created_at DESC;
57
+
58
+ -- name: CreateUser :one
59
+ INSERT INTO users (name, email, role) VALUES ($1, $2, $3) RETURNING *;
60
+
61
+ -- name: DeleteUser :execresult
62
+ DELETE FROM users WHERE id = $1;
63
+ ```
64
+
65
+ ### 3. Generate
66
+
67
+ ```bash
68
+ bunx sqlcx-orm generate --sql ./sql --out ./src/db
69
+ ```
70
+
71
+ ### 4. Use
72
+
73
+ ```ts
74
+ import { BunSqlClient } from "./src/db/client";
75
+ import { getUser, createUser } from "./src/db/users.queries";
76
+
77
+ const client = new BunSqlClient(Bun.sql);
78
+
79
+ const user = await getUser(client, { id: 1 });
80
+ // user: { id: number, name: string, email: string, ... } | null
81
+
82
+ await createUser(client, { name: "Alice", email: "alice@example.com", role: "admin" });
83
+ ```
84
+
85
+ ## Features
86
+
87
+ ### Inline `@enum` annotations
88
+
89
+ No separate enum objects. Define values right where the column is:
90
+
91
+ ```sql
92
+ -- @enum("draft", "published", "archived")
93
+ status TEXT NOT NULL DEFAULT 'draft'
94
+ ```
95
+
96
+ Generates `Type.Union([Type.Literal("draft"), Type.Literal("published"), Type.Literal("archived")])` — not a plain `string`.
97
+
98
+ ### Inline `@json` annotations
99
+
100
+ No more `unknown` for JSON columns:
101
+
102
+ ```sql
103
+ -- @json({ theme: string, notifications: boolean, font_size: number })
104
+ preferences JSONB
105
+ ```
106
+
107
+ Generates a fully typed TypeBox object schema. Supports nested objects, arrays (`string[]`), and nullable (`string?`).
108
+
109
+ ### Partial column selection
110
+
111
+ Only select the columns you need — the generated type matches exactly what you query:
112
+
113
+ ```sql
114
+ -- name: ListUsers :many
115
+ SELECT id, name, email FROM users ORDER BY created_at DESC;
116
+ ```
117
+
118
+ Generates a `ListUsersRow` with only `{ id: number; name: string; email: string }` — not the full table type. No over-fetching in your types.
119
+
120
+ ### `RETURNING` clause support
121
+
122
+ ```sql
123
+ -- name: CreateUser :one
124
+ INSERT INTO users (name, email) VALUES ($1, $2) RETURNING *;
125
+ ```
126
+
127
+ Return types are inferred from the table schema — works with `RETURNING *` and explicit column lists.
128
+
129
+ ### `@param` overrides
130
+
131
+ For ambiguous parameter names:
132
+
133
+ ```sql
134
+ -- name: ListByDateRange :many
135
+ -- @param $1 start_date
136
+ -- @param $2 end_date
137
+ SELECT * FROM posts WHERE published_at > $1 AND published_at < $2;
138
+ ```
139
+
140
+ ### Query commands
141
+
142
+ | Annotation | Returns | Use for |
143
+ |-----------|---------|---------|
144
+ | `:one` | `T \| null` | Single row lookups |
145
+ | `:many` | `T[]` | List queries |
146
+ | `:exec` | `void` | INSERT/UPDATE/DELETE |
147
+ | `:execresult` | `{ rowsAffected: number }` | DELETE/UPDATE with count |
148
+
149
+ ### Input/Output type separation
150
+
151
+ Generated schemas separate Select (all columns) from Insert (defaults are optional):
152
+
153
+ ```ts
154
+ // All columns present
155
+ export type SelectUsers = { id: number; name: string; created_at: Date; ... }
156
+
157
+ // Columns with defaults (id, created_at) are Optional
158
+ export type InsertUsers = { name: string; email: string; id?: number; created_at?: Date; ... }
159
+ ```
160
+
161
+ ## CLI
162
+
163
+ ```bash
164
+ sqlcx-orm generate [options] # Parse SQL and generate typed code
165
+ sqlcx-orm check [options] # Validate SQL without generating (CI-friendly)
166
+ sqlcx-orm init # Scaffold sql/ directory with examples
167
+
168
+ Options:
169
+ --sql <dir> SQL directory (default: ./sql)
170
+ --out <dir> Output directory (default: ./src/db)
171
+ --cache <dir> Cache directory (default: .sqlcx)
172
+ ```
173
+
174
+ ## How it works
175
+
176
+ ```
177
+ SQL files --> [PostgreSQL Parser] --> IR (Intermediate Representation)
178
+ |
179
+ +--> [TypeBox Schema Generator] --> schema.ts
180
+ +--> [Bun.sql Driver Generator] --> queries.ts + client.ts
181
+ ```
182
+
183
+ The IR is language-agnostic and cacheable. Adding new language targets (Python, Go) or schema generators (Zod, Valibot) means implementing a plugin against the IR — the SQL parsing is done once.
184
+
185
+ ## Plugin Architecture
186
+
187
+ sqlcx is built on four plugin axes:
188
+
189
+ - **Database Parser** — PostgreSQL (shipped), MySQL/SQLite (planned)
190
+ - **Schema Generator** — TypeBox v1.0 (shipped), Zod/Valibot (planned)
191
+ - **Driver Generator** — Bun.sql (shipped), pg/mysql2 (planned)
192
+ - **Language Plugin** — TypeScript (shipped), Python/Go (planned)
193
+
194
+ ## Why sqlcx?
195
+
196
+ | Pain point | Prisma | Drizzle | sqlcx |
197
+ |-----------|--------|---------|-------|
198
+ | JSON columns typed | No (`JsonValue`) | No (`unknown`) | Yes (`@json` annotations) |
199
+ | Inline enums | No (separate block) | No (separate object) | Yes (`@enum` annotations) |
200
+ | Bundle size | ~1.6MB | ~7.4KB | **0 KB** (no runtime) |
201
+ | Multi-language | Dropped Python | TypeScript only | Designed for any language |
202
+ | IDE lag on large schemas | Yes (huge .d.ts) | Yes (deep inference) | No (flat interfaces) |
203
+ | Generated type bloat | Thousands of lines | Complex generics | Simple flat types |
204
+
205
+ ## License
206
+
207
+ MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sqlcx-orm",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "SQL-first cross-language type-safe code generator",
5
5
  "type": "module",
6
6
  "bin": {