flint-orm 0.6.0 → 0.7.1

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.
@@ -0,0 +1,141 @@
1
+ # Driver Comparison Reference
2
+
3
+ Detailed comparison of all flint-orm drivers.
4
+
5
+ ## bun:sqlite
6
+
7
+ **Runtime:** Bun only
8
+ **Type:** Sync (Promise-wrapped for uniform API)
9
+ **Install:** Built into Bun — no separate install needed
10
+
11
+ ```ts
12
+ import { flint } from 'flint-orm/bun-sqlite';
13
+ const db = flint({ url: './app.db' });
14
+ ```
15
+
16
+ **Options:**
17
+ - `url: string` — Path to SQLite file or `:memory:`
18
+
19
+ **Limitations:**
20
+ - Only works in Bun runtime
21
+ - No remote database support
22
+ - No authentication support
23
+
24
+ ## better-sqlite3
25
+
26
+ **Runtime:** Node.js
27
+ **Type:** Sync (Promise-wrapped for uniform API)
28
+ **Install:** `npm install better-sqlite3`
29
+
30
+ ```ts
31
+ import { flint } from 'flint-orm/better-sqlite3';
32
+ const db = flint({ url: './app.db' });
33
+ ```
34
+
35
+ **Options:**
36
+ - `url: string` — Path to SQLite file or `:memory:`
37
+
38
+ **Limitations:**
39
+ - No remote database support
40
+ - No authentication support
41
+
42
+ ## @libsql/client
43
+
44
+ **Runtime:** Bun/Node.js
45
+ **Type:** Async
46
+ **Install:** `npm install @libsql/client`
47
+
48
+ ```ts
49
+ import { flint } from 'flint-orm/libsql';
50
+ const db = flint({
51
+ url: 'libsql://your-db.turso.io',
52
+ authToken: process.env.TURSO_AUTH_TOKEN,
53
+ });
54
+ ```
55
+
56
+ **Options:**
57
+ - `url: string` — Local file (`file:./app.db`), remote (`libsql://...`), or in-memory (`:memory:`)
58
+ - `authToken: string` — Required for remote databases
59
+
60
+ **Capabilities:**
61
+ - Local file access
62
+ - Remote database access
63
+ - Serverless compatible
64
+ - Authentication support
65
+
66
+ ## @libsql/client/web
67
+
68
+ **Runtime:** Any (browser, edge, serverless)
69
+ **Type:** Async
70
+ **Install:** `npm install @libsql/client`
71
+
72
+ ```ts
73
+ import { flint } from 'flint-orm/libsql-web';
74
+ const db = flint({
75
+ url: 'libsql://your-db.turso.io',
76
+ authToken: process.env.TURSO_AUTH_TOKEN,
77
+ });
78
+ ```
79
+
80
+ **Options:**
81
+ - `url: string` — Remote only (`ws://`, `wss://`, `http://`, `https://`)
82
+ - `authToken: string` — Required for remote databases
83
+
84
+ **Capabilities:**
85
+ - No native binary — works in any JavaScript runtime
86
+ - Serverless/edge optimized
87
+ - Authentication support
88
+
89
+ **Limitations:**
90
+ - No local file access (`file:` URLs not supported)
91
+ - No in-memory database support
92
+
93
+ ## @tursodatabase/database
94
+
95
+ **Runtime:** Bun/Node.js
96
+ **Type:** Async
97
+ **Install:** `npm install @tursodatabase/database`
98
+
99
+ ```ts
100
+ import { flint } from 'flint-orm/turso';
101
+ const db = flint({
102
+ url: 'libsql://your-db.turso.io',
103
+ authToken: process.env.TURSO_AUTH_TOKEN,
104
+ });
105
+ ```
106
+
107
+ **Options:**
108
+ - `url: string` — Local file or remote Turso database
109
+ - `authToken: string` — Required for remote databases
110
+
111
+ ## @tursodatabase/sync
112
+
113
+ **Runtime:** Bun/Node.js
114
+ **Type:** Async
115
+ **Install:** `npm install @tursodatabase/sync`
116
+
117
+ ```ts
118
+ import { flint } from 'flint-orm/turso-sync';
119
+ const db = flint({
120
+ url: 'libsql://your-db.turso.io',
121
+ authToken: process.env.TURSO_AUTH_TOKEN,
122
+ });
123
+ ```
124
+
125
+ **Options:**
126
+ - `url: string` — Local file or remote Turso database
127
+ - `authToken: string` — Required for remote databases
128
+
129
+ **Capabilities:**
130
+ - Includes sync support for offline-first applications
131
+
132
+ ## Decision Guide
133
+
134
+ | Use Case | Recommended Driver |
135
+ |----------|-------------------|
136
+ | Bun runtime, local file | bun:sqlite |
137
+ | Node.js, local file | better-sqlite3 |
138
+ | Remote Turso database | libsql |
139
+ | Serverless/edge | libsql-web |
140
+ | Turso with sync | turso-sync |
141
+ | Testing/prototyping | Any with `:memory:` |
@@ -0,0 +1,163 @@
1
+ ---
2
+ name: run-migrations
3
+ description: >
4
+ Generate and apply schema migrations safely using the CLI or programmatic
5
+ API. Covers flint generate, flint migrate, flint.config.ts, and the
6
+ migration pipeline (serialize → diff → generateSQL). Load when creating
7
+ or applying migrations, or when troubleshooting migration issues.
8
+ metadata:
9
+ type: core
10
+ library: flint-orm
11
+ library_version: 0.7.0
12
+ sources:
13
+ - 'kavenlabs/flint-orm:src/migration/generate.ts'
14
+ - 'kavenlabs/flint-orm:src/migration/migrate.ts'
15
+ - 'kavenlabs/flint-orm:src/migration/sql.ts'
16
+ - 'kavenlabs/flint-orm:src/cli.ts'
17
+ - 'kavenlabs/flint-orm:README.md'
18
+ - 'kavenlabs/flint-orm:API.md'
19
+ ---
20
+
21
+ # flint-orm — Migrations
22
+
23
+ ## Setup
24
+
25
+ ### flint.config.ts
26
+
27
+ ```ts
28
+ import { defineConfig } from 'flint-orm/config';
29
+
30
+ export default defineConfig({
31
+ driver: 'bun-sqlite', // Must match the driver you import in your app
32
+ database: {
33
+ url: './app.db',
34
+ },
35
+ schema: './src/schema',
36
+ migrations: './flint',
37
+ });
38
+ ```
39
+
40
+ ### CLI commands
41
+
42
+ ```bash
43
+ # Generate a migration from schema changes
44
+ flint generate
45
+ flint generate --name add_users_table
46
+ flint generate --preview # Show SQL without writing
47
+
48
+ # Apply pending migrations
49
+ flint migrate
50
+ flint migrate --dry-run # Show what would run
51
+ flint migrate --status # Show applied vs pending
52
+ ```
53
+
54
+ ## Core Patterns
55
+
56
+ ### Generate initial migration
57
+
58
+ After defining your schema, generate the first migration:
59
+
60
+ ```bash
61
+ flint generate --name init_schema
62
+ ```
63
+
64
+ This creates a folder in `./flint/` with:
65
+ - `migration.ts` — The operations to apply
66
+ - `state.json` — Snapshot of the schema
67
+
68
+ ### Apply migrations
69
+
70
+ ```bash
71
+ flint migrate
72
+ ```
73
+
74
+ This:
75
+ 1. Reads pending migrations from the migrations directory
76
+ 2. Applies them in order within transactions
77
+ 3. Records applied migrations in `__flint_migrations` table
78
+
79
+ ### Preview before applying
80
+
81
+ Always preview before applying in production:
82
+
83
+ ```bash
84
+ flint generate --preview # Review the SQL
85
+ flint migrate --dry-run # Verify what would run
86
+ flint migrate # Apply with confidence
87
+ ```
88
+
89
+ ### Programmatic API
90
+
91
+ ```ts
92
+ import { flint } from 'flint-orm/bun-sqlite';
93
+ import { generate, migrate, getMigrationStatus } from 'flint-orm/migration';
94
+
95
+ const db = flint({ url: './app.db' });
96
+
97
+ // Generate a migration
98
+ await generate([users, posts], './flint', {
99
+ name: 'add_posts',
100
+ interactive: true,
101
+ });
102
+
103
+ // Apply pending migrations
104
+ const result = await migrate(db.$executor, { migrationsDir: './flint' });
105
+ console.log(`Applied: ${result.applied.join(', ')}`);
106
+
107
+ // Check status
108
+ const status = await getMigrationStatus(db.$executor, './flint');
109
+ console.log(`Pending: ${status.pending.length}`);
110
+ ```
111
+
112
+ ## How It Works
113
+
114
+ 1. `flint generate` serializes your `table()` definitions to JSON
115
+ 2. Diffs against the last migration's `state.json`
116
+ 3. Detects adds, drops, renames, and safe modifications
117
+ 4. Prompts to confirm potential renames (interactive mode)
118
+ 5. Writes a migration folder with `migration.ts` + `state.json`
119
+ 6. `flint migrate` reads pending migrations and executes them in order
120
+
121
+ ## Common Mistakes
122
+
123
+ ### HIGH Running migrate without generate first
124
+
125
+ Wrong:
126
+
127
+ ```ts
128
+ // Modifying schema, then:
129
+ flint migrate // No migration files exist yet!
130
+ ```
131
+
132
+ Correct:
133
+
134
+ ```ts
135
+ // After schema changes:
136
+ flint generate --name add_users_table
137
+ flint migrate
138
+ ```
139
+
140
+ `migrate` applies existing migration files — you must generate them first from schema changes.
141
+
142
+ Source: README.md
143
+
144
+ ### HIGH Not using --preview or --dry-run before applying
145
+
146
+ Wrong:
147
+
148
+ ```ts
149
+ flint generate
150
+ flint migrate // Applies without preview
151
+ ```
152
+
153
+ Correct:
154
+
155
+ ```ts
156
+ flint generate --preview // Review the SQL
157
+ flint migrate --dry-run // Verify what would run
158
+ flint migrate // Apply with confidence
159
+ ```
160
+
161
+ Migrations can be destructive (dropping columns, rebuilding tables). Always preview first.
162
+
163
+ Source: README.md
@@ -0,0 +1,142 @@
1
+ ---
2
+ name: setup-client
3
+ description: >
4
+ Install flint-orm, choose a driver, and connect to a database. Covers
5
+ flint() factory, driver entry points (bun-sqlite, better-sqlite3, libsql,
6
+ libsql-web, turso, turso-sync), and flint.config.ts configuration. Load
7
+ when setting up a new project or switching drivers.
8
+ metadata:
9
+ type: core
10
+ library: flint-orm
11
+ library_version: 0.7.0
12
+ sources:
13
+ - 'kavenlabs/flint-orm:src/entries/bun-sqlite.ts'
14
+ - 'kavenlabs/flint-orm:src/entries/libsql.ts'
15
+ - 'kavenlabs/flint-orm:src/entries/libsql-web.ts'
16
+ - 'kavenlabs/flint-orm:src/entries/better-sqlite3.ts'
17
+ - 'kavenlabs/flint-orm:README.md'
18
+ ---
19
+
20
+ # flint-orm — Client Setup
21
+
22
+ flint-orm is a type-safe, driver-agnostic SQLite ORM for JavaScript. One schema, any driver.
23
+
24
+ ## Setup
25
+
26
+ ### Install with a driver
27
+
28
+ ```bash
29
+ # Choose ONE driver (bun:sqlite is built into Bun, no install needed):
30
+ bun add flint-orm # bun:sqlite (sync, Promise-wrapped) — Bun only
31
+ bun add flint-orm better-sqlite3 # better-sqlite3 (sync, Promise-wrapped)
32
+ bun add flint-orm @libsql/client # libsql (async, local or remote)
33
+ bun add flint-orm @libsql/client # libsql-web (async, serverless, no file: support)
34
+ bun add flint-orm @tursodatabase/database # turso (async)
35
+ bun add flint-orm @tursodatabase/sync # turso-sync (async, authToken)
36
+ ```
37
+
38
+ ### Initialize the client
39
+
40
+ ```ts
41
+ import { flint } from 'flint-orm/bun-sqlite';
42
+
43
+ const db = flint({ url: './app.db' });
44
+ ```
45
+
46
+ ### Create flint.config.ts
47
+
48
+ ```ts
49
+ import { defineConfig } from 'flint-orm/config';
50
+
51
+ export default defineConfig({
52
+ driver: 'bun-sqlite', // Must match the driver you import in your app
53
+ database: {
54
+ url: './app.db',
55
+ },
56
+ schema: './src/schema',
57
+ migrations: './flint',
58
+ });
59
+ ```
60
+
61
+ ## Core Patterns
62
+
63
+ ### Connect to a local file
64
+
65
+ ```ts
66
+ import { flint } from 'flint-orm/bun-sqlite';
67
+
68
+ const db = flint({ url: './app.db' });
69
+ ```
70
+
71
+ ### Connect to a remote database
72
+
73
+ ```ts
74
+ import { flint } from 'flint-orm/libsql';
75
+
76
+ const db = flint({
77
+ url: 'libsql://your-db.turso.io',
78
+ authToken: process.env.TURSO_AUTH_TOKEN,
79
+ });
80
+ ```
81
+
82
+ ### Connect in a serverless environment
83
+
84
+ ```ts
85
+ import { flint } from 'flint-orm/libsql-web';
86
+
87
+ // libsql-web only supports ws://, wss://, http://, https:// URLs
88
+ const db = flint({
89
+ url: 'libsql://your-db.turso.io',
90
+ authToken: process.env.TURSO_AUTH_TOKEN,
91
+ });
92
+ ```
93
+
94
+ ## Common Mistakes
95
+
96
+ ### CRITICAL Driver mismatch between config and app
97
+
98
+ Wrong:
99
+
100
+ ```ts
101
+ // flint.config.ts
102
+ export default defineConfig({ driver: 'bun-sqlite', ... });
103
+
104
+ // app.ts
105
+ import { flint } from 'flint-orm/libsql'; // MISMATCH
106
+ const db = flint({ url: '...' });
107
+ ```
108
+
109
+ Correct:
110
+
111
+ ```ts
112
+ // flint.config.ts
113
+ export default defineConfig({ driver: 'libsql', ... });
114
+
115
+ // app.ts
116
+ import { flint } from 'flint-orm/libsql'; // MATCHES
117
+ const db = flint({ url: '...' });
118
+ ```
119
+
120
+ The CLI uses flint.config.ts to determine which driver to use for migrations, but the app uses whichever driver you import — these must match.
121
+
122
+ Source: maintainer interview
123
+
124
+ ### HIGH Using libsql-web for local file databases
125
+
126
+ Wrong:
127
+
128
+ ```ts
129
+ import { flint } from 'flint-orm/libsql-web';
130
+ const db = flint({ url: './app.db' }); // ERROR: file: not supported
131
+ ```
132
+
133
+ Correct:
134
+
135
+ ```ts
136
+ import { flint } from 'flint-orm/libsql';
137
+ const db = flint({ url: './app.db' });
138
+ ```
139
+
140
+ libsql-web only supports ws:, wss:, http:, https: URLs — it has no native binary and cannot access local files. Use the regular libsql driver for local files.
141
+
142
+ Source: src/entries/libsql-web.ts
@@ -0,0 +1,186 @@
1
+ ---
2
+ name: update-schema
3
+ description: >
4
+ Add columns and tables without data loss. Covers safe vs unsafe migrations,
5
+ rebuildTable operation, additive migration patterns, and which changes
6
+ trigger table rebuilds. Load when modifying schema after initial migration
7
+ or when planning schema evolution.
8
+ metadata:
9
+ type: core
10
+ library: flint-orm
11
+ library_version: 0.7.0
12
+ sources:
13
+ - 'kavenlabs/flint-orm:src/migration/diff.ts'
14
+ - 'kavenlabs/flint-orm:src/migration/sql.ts'
15
+ - 'kavenlabs/flint-orm:src/migration/migrate.ts'
16
+ - 'kavenlabs/flint-orm:README.md'
17
+ ---
18
+
19
+ # flint-orm — Schema Updates
20
+
21
+ ## Setup
22
+
23
+ After defining your initial schema, you'll need to evolve it over time. flint-orm detects changes and generates appropriate migrations.
24
+
25
+ ## Core Patterns
26
+
27
+ ### Safe migration: Adding a column with default
28
+
29
+ ```ts
30
+ // Add a new column with a default value — safe, no data loss
31
+ const users = snakeCase.table('users', {
32
+ id: integer().autoIncrement().primaryKey(),
33
+ name: text().notNull(),
34
+ status: text().notNull().default('active'), // NEW: safe to add
35
+ });
36
+ ```
37
+
38
+ ### Safe migration: Adding a new table
39
+
40
+ ```ts
41
+ // Add a new table — always safe
42
+ const posts = snakeCase.table('posts', {
43
+ id: integer().autoIncrement().primaryKey(),
44
+ userId: integer().notNull().references(users.id),
45
+ title: text().notNull(),
46
+ });
47
+ ```
48
+
49
+ ### Unsafe migration: Changing column type
50
+
51
+ ```ts
52
+ // Changing a column type triggers a table rebuild
53
+ // The old column was: age: text('age')
54
+ // The new column is: age: integer('age')
55
+ const users = snakeCase.table('users', {
56
+ id: integer().autoIncrement().primaryKey(),
57
+ name: text().notNull(),
58
+ age: integer('age').notNull().default(0), // TYPE CHANGE: triggers rebuild
59
+ });
60
+ ```
61
+
62
+ ### Unsafe migration: Adding NOT NULL without default
63
+
64
+ ```ts
65
+ // Adding NOT NULL without a default triggers a table rebuild
66
+ const users = snakeCase.table('users', {
67
+ id: integer().autoIncrement().primaryKey(),
68
+ name: text().notNull(),
69
+ status: text().notNull(), // NO DEFAULT: triggers rebuild
70
+ });
71
+ ```
72
+
73
+ ## Migration Safety Reference
74
+
75
+ ### Safe changes (no rebuild)
76
+
77
+ | Change | Example |
78
+ |--------|---------|
79
+ | Add column with default | `status: text().default('active')` |
80
+ | Add new table | `snakeCase.table('new_table', {...})` |
81
+ | Add index | `index('idx_name').on(t.name)` |
82
+ | Drop index | Remove from index callback |
83
+ | Change default value | `status: text().default('inactive')` |
84
+
85
+ ### Unsafe changes (triggers rebuild)
86
+
87
+ | Change | Example |
88
+ |--------|---------|
89
+ | Change column type | `text()` → `integer()` |
90
+ | Add NOT NULL without default | `text().notNull()` (no `.default()`) |
91
+ | Remove NOT NULL | `text().notNull()` → `text()` |
92
+ | Add/remove UNIQUE | `text().unique()` → `text()` |
93
+ | Remove default | `text().default('x')` → `text()` |
94
+ | Add/change/remove foreign key | `.references(col)` changes |
95
+ | Change FK actions | `.onDelete('cascade')` changes |
96
+ | Change autoincrement | `.autoIncrement()` changes |
97
+
98
+ ### What is rebuildTable?
99
+
100
+ When an unsafe change is detected, flint-orm generates a `rebuildTable` operation that:
101
+
102
+ 1. Creates a temporary table with the new schema
103
+ 2. Copies data from the old table
104
+ 3. Drops the old table
105
+ 4. Renames the temporary table to the original name
106
+ 5. Recreates indexes
107
+
108
+ This happens within a transaction — if anything fails, the original table is preserved.
109
+
110
+ ## Common Mistakes
111
+
112
+ ### HIGH Adding NOT NULL column without a default
113
+
114
+ Wrong:
115
+
116
+ ```ts
117
+ // After initial migration, adding:
118
+ const users = snakeCase.table('users', {
119
+ id: integer().autoIncrement().primaryKey(),
120
+ name: text().notNull(),
121
+ status: text().notNull(), // No default — triggers rebuild
122
+ });
123
+ ```
124
+
125
+ Correct:
126
+
127
+ ```ts
128
+ const users = snakeCase.table('users', {
129
+ id: integer().autoIncrement().primaryKey(),
130
+ name: text().notNull(),
131
+ status: text().notNull().default('active'), // Safe: has default
132
+ });
133
+ ```
134
+
135
+ SQLite cannot add NOT NULL columns to existing tables without a default — this triggers a table rebuild.
136
+
137
+ Source: src/migration/diff.ts
138
+
139
+ ### HIGH Changing a column type
140
+
141
+ Wrong:
142
+
143
+ ```ts
144
+ // Changing after initial migration:
145
+ const users = snakeCase.table('users', {
146
+ id: integer().autoIncrement().primaryKey(),
147
+ name: text().notNull(),
148
+ age: integer('age'), // Was: age: text('age')
149
+ });
150
+ ```
151
+
152
+ Correct:
153
+
154
+ ```ts
155
+ // Plan for the type from the start, or accept the rebuild
156
+ const users = snakeCase.table('users', {
157
+ id: integer().autoIncrement().primaryKey(),
158
+ name: text().notNull(),
159
+ age: integer('age').notNull().default(0), // Correct type from start
160
+ });
161
+ ```
162
+
163
+ SQLite has no `ALTER COLUMN TYPE` — this always triggers a table rebuild.
164
+
165
+ Source: src/migration/diff.ts
166
+
167
+ ### HIGH Dropping a column referenced by foreign keys
168
+
169
+ Wrong:
170
+
171
+ ```ts
172
+ // Dropping users.id when orders.userId references it
173
+ // Migration fails with: Cannot rebuild "users" — referenced by: orders
174
+ ```
175
+
176
+ Correct:
177
+
178
+ ```bash
179
+ # Migrate dependent tables first, then rebuild the parent
180
+ flint migrate # Apply orders migration first
181
+ flint generate # Then rebuild users
182
+ ```
183
+
184
+ The migration runner checks for incoming foreign keys before rebuild — it will refuse if other tables reference the table being rebuilt.
185
+
186
+ Source: src/migration/migrate.ts