driftsql 1.0.32 → 2.0.0-beta.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.
package/README.md CHANGED
@@ -1,148 +1,328 @@
1
1
  # DriftSQL
2
2
 
3
- [![npm version](https://img.shields.io/npm/v/driftsql?color=yellow)](https://npmjs.com/package/driftsql)
4
- [![npm downloads](https://img.shields.io/npm/dm/driftsql?color=yellow)](https://npm.chart.dev/driftsql)
3
+ A modern, type-safe SQL client with built-in schema builder and migration system for TypeScript.
5
4
 
6
- A lightweight, type-safe SQL client for TypeScript with support for PostgreSQL, MySQL, LibSQL/SQLite, and Neon.
5
+ ## Features
6
+
7
+ - 🚀 **High-Performance SQL Client** with connection pooling and query caching
8
+ - 🎯 **Type-Safe Schema Builder** similar to Drizzle/Prisma
9
+ - 🔄 **Migration System** with automatic change detection
10
+ - 🛠️ **CLI Tools** for database management
11
+ - 📦 **Multiple Databases** - PostgreSQL, MySQL, SQLite support
12
+ - ⚡ **Helper Functions** for common CRUD operations
13
+ - 🔍 **Database Inspection** to generate TypeScript types
14
+
15
+ ## Quick Start
16
+
17
+ ```bash
18
+ # Install
19
+ bun add driftsql
7
20
 
8
- ## Installation
21
+ # Initialize with a basic notes schema
22
+ driftsql init
9
23
 
10
- ```sh
11
- npm install driftsql
24
+ # Update .env with your DATABASE_URL
25
+ cp .env.example .env
26
+
27
+ # Generate migration from schema
28
+ driftsql migrate:generate initial
29
+
30
+ # Run migrations
31
+ driftsql migrate:up
32
+
33
+ # Edit schema.ts, then generate new migrations automatically
34
+ driftsql migrate:generate add_posts
12
35
  ```
13
36
 
14
- ## Features
37
+ ## Automatic Workflow
15
38
 
16
- - 🔐 **Type-safe** - Full TypeScript support
17
- - 🚀 **Modular** - Import only what you need
18
- - 🛡️ **SQL injection protection** - Parameterized queries
19
- - 🔄 **Unified API** - Same interface across all drivers
20
- - ⚡ **Transactions** - When supported by the driver
39
+ DriftSQL automatically detects schema changes and generates migrations for you!
21
40
 
22
- ## Quick Start
41
+ 1. Define your schema in `schema.ts`:
23
42
 
24
43
  ```typescript
25
- import { PostgresDriver, SQLClient } from 'driftsql'
44
+ import { createTable, serial, varchar, text } from 'driftsql'
26
45
 
27
- // Choose your database
28
- const driver = new PostgresDriver({
29
- connectionString: 'postgresql://user:password@localhost:5432/mydb',
46
+ const usersTable = createTable('users', (table) => {
47
+ table.column(serial('id').primaryKey()).column(varchar('email', 255).unique().notNull()).column(varchar('name', 255).notNull())
30
48
  })
31
- const client = new SQLClient({ driver })
32
49
 
33
- // Raw queries
34
- const result = await client.query('SELECT * FROM users WHERE id = $1', [1])
50
+ const postsTable = createTable('posts', (table) => {
51
+ table.column(serial('id').primaryKey()).column(integer('user_id').references('users', 'id')).column(varchar('title', 255).notNull()).column(text('content'))
52
+ })
35
53
 
36
- // Helper methods
37
- const user = await client.findFirst('users', { email: 'user@example.com' })
38
- const newUser = await client.insert('users', { name: 'John', email: 'john@example.com' })
54
+ export default [usersTable.getDefinition(), postsTable.getDefinition()]
39
55
  ```
40
56
 
41
- ## Supported Databases
57
+ 2. Generate migration:
42
58
 
43
- ```typescript
44
- import { PostgresDriver, LibSQLDriver, MySQLDriver, NeonDriver, SQLClient } from 'driftsql'
59
+ ```bash
60
+ driftsql migrate:generate
61
+ ```
45
62
 
46
- // PostgreSQL
47
- const pg = new PostgresDriver({ connectionString: 'postgresql://...' })
63
+ 3. DriftSQL automatically:
48
64
 
49
- // Neon
50
- const neon = new NeonDriver({ connectionString: 'postgresql://...' })
65
+ - ✅ Compares with the last snapshot
66
+ - Detects all changes
67
+ - ✅ Generates migration file
68
+ - ✅ Generates TypeScript types (`db-types.ts`)
51
69
 
52
- // LibSQL/Turso/SQLite
53
- const libsql = new LibSQLDriver({ url: 'libsql://...', authToken: '...' })
54
- // or for local SQLite: new LibSQLDriver({ url: 'file:./database.db' })
70
+ 4. Apply migrations:
55
71
 
56
- // MySQL
57
- const mysql = new MySQLDriver({ connectionString: 'mysql://...' })
72
+ ```bash
73
+ driftsql migrate:up
74
+ ```
75
+
76
+ 5. Use type-safe queries:
58
77
 
59
- // Create client with any driver
60
- const client = new SQLClient({ driver: pg })
78
+ ```typescript
79
+ import { Database } from './db-types'
80
+ const client = new SQLClient<Database>({
81
+ /* ... */
82
+ })
61
83
  ```
62
84
 
63
- ## Custom Drivers
85
+ ## Usage
64
86
 
65
- You can easily create your own database drivers by implementing the `DatabaseDriver` interface:
87
+ ### SQL Client with Type Safety
66
88
 
67
- ```typescript
68
- import type { DatabaseDriver, QueryResult } from 'driftsql'
69
-
70
- class MyCustomDriver implements DatabaseDriver {
71
- async query<T = any>(sql: string, params?: any[]): Promise<QueryResult<T>> {
72
- // Your implementation here
73
- return {
74
- rows: [], // T[]
75
- rowCount: 0,
76
- command: 'SELECT',
77
- }
78
- }
79
-
80
- async close(): Promise<void> {
81
- // Cleanup logic
82
- }
83
- }
89
+ TypeScript types are **automatically generated** when you run `migrate:generate`:
84
90
 
85
- // Use your custom driver
86
- const client = new SQLClient({ driver: new MyCustomDriver() })
91
+ ```bash
92
+ driftsql migrate:generate # Creates migration AND db-types.ts automatically
87
93
  ```
88
94
 
89
- ## Database Inspection
95
+ Or generate them manually:
96
+
97
+ ```bash
98
+ driftsql generate:types --schema ./schema.ts --output ./db-types.ts
99
+ ```
90
100
 
91
- Generate TypeScript interfaces from your database schema:
101
+ Then use them for full type safety:
92
102
 
93
103
  ```typescript
94
- import { inspectDB, PostgresDriver } from 'driftsql'
104
+ import { SQLClient, PostgresDriver } from 'driftsql'
105
+ import type { Database } from './db-types'
95
106
 
96
- const driver = new PostgresDriver({
97
- connectionString: 'postgresql://user:password@localhost:5432/mydb',
107
+ // Generic parameter makes client type-safe
108
+ const client = new SQLClient<Database>({
109
+ driver: new PostgresDriver({
110
+ connectionString: process.env.DATABASE_URL!,
111
+ max: 10, // Connection pool size
112
+ idle_timeout: 30, // Seconds
113
+ connect_timeout: 10, // Seconds
114
+ }),
115
+ cacheTTL: 5000, // Cache TTL in ms (default: 5000)
98
116
  })
99
117
 
100
- // Generate types for all tables
101
- await inspectDB({
102
- driver,
103
- outputFile: 'db-types.ts', // optional, defaults to 'db-types.ts'
118
+ // Raw SQL queries (no type safety, but flexible)
119
+ const result = await client.query('SELECT * FROM users WHERE id = $1', [1])
120
+
121
+ // ✅ Type-safe helper methods (TypeScript validates everything!)
122
+ const user = await client.findFirst('users', { email: 'test@example.com' })
123
+ // ^^^^^ TypeScript ensures 'users' exists
124
+ // ^^^^^ TypeScript ensures 'email' is a valid column
125
+
126
+ const activeUsers = await client.findMany('users', {
127
+ where: { active: true }, // ✅ TypeScript validates field names and types
128
+ limit: 10,
129
+ offset: 0,
104
130
  })
105
- ```
106
131
 
107
- This will create a file with TypeScript interfaces for each table:
132
+ // Insert with type checking
133
+ const newUser = await client.insert('users', {
134
+ email: 'new@example.com', // ✅ Must be a string
135
+ name: 'New User', // ✅ Must be a string
136
+ active: true, // ✅ Must be a boolean
137
+ // invalid: 'field' // ❌ TypeScript error!
138
+ })
108
139
 
109
- ```typescript
110
- // Generated db-types.ts
111
- export interface Users {
112
- id: number
113
- name: string
114
- email: string
115
- created_at: Date
116
- active: boolean | null
117
- }
140
+ // ✅ Update with type checking
141
+ const updated = await client.update(
142
+ 'users',
143
+ { name: 'Updated Name' }, // ✅ Only valid columns
144
+ { id: 1 } // ✅ Only valid columns in where clause
145
+ )
146
+
147
+ // Delete with type checking
148
+ const deletedCount = await client.delete('users', { id: 1 })
149
+
150
+ // Transactions - all operations succeed or all fail
151
+ await client.transaction(async (tx) => {
152
+ const user = await tx.insert('users', { email: 'user@example.com', name: 'User' })
153
+ await tx.insert('posts', { user_id: user.id, title: 'First Post' })
154
+ await tx.query('UPDATE users SET post_count = post_count + 1 WHERE id = $1', [user.id])
155
+ })
156
+
157
+ // Cache management
158
+ const stats = client.getCacheStats() // { size: 5, ttl: 5000 }
159
+ client.clearCache() // Clear all cached queries
118
160
 
119
- export interface Posts {
120
- id: number
121
- title: string
122
- content: string
123
- user_id: number
124
- published: boolean
161
+ // Check driver capabilities
162
+ if (client.supportsTransactions()) {
163
+ await client.transaction(async (tx) => {
164
+ /* ... */
165
+ })
125
166
  }
126
167
 
127
- export interface Database {
128
- users: Users
129
- posts: Posts
168
+ if (client.supportsPreparedStatements()) {
169
+ const stmt = await client.prepare('SELECT * FROM users WHERE id = $1')
170
+ const result = await stmt.execute([1])
171
+ await stmt.finalize()
130
172
  }
173
+
174
+ await client.close()
131
175
  ```
132
176
 
133
- Then use the generated types with your client:
177
+ ### Schema Builder
134
178
 
135
179
  ```typescript
136
- import type { Database } from './db-types'
137
- import { PostgresDriver, SQLClient } from 'driftsql'
180
+ import { createTable, createMigration, serial, varchar, text, timestamp } from 'driftsql'
181
+
182
+ // Define table
183
+ const usersTable = createTable('users', (table) => {
184
+ table
185
+ .column(serial('id').primaryKey())
186
+ .column(varchar('email', 255).unique().notNull())
187
+ .column(varchar('name', 255).notNull())
188
+ .column(text('bio'))
189
+ .column(timestamp('created_at').default('CURRENT_TIMESTAMP').notNull())
190
+ .index('idx_users_email', ['email'])
191
+ })
192
+
193
+ // Create migration
194
+ const migration = createMigration('postgres').createTable(usersTable).build('001', 'create_users_table')
195
+
196
+ // View generated SQL
197
+ console.log(migration.up) // CREATE TABLE statements
198
+ console.log(migration.down) // DROP TABLE statements
199
+ ```
138
200
 
139
- const client = new SQLClient<Database>({ driver })
201
+ ### Change Detection
140
202
 
141
- // Now you get full type safety
142
- const user = await client.findFirst('users', { email: 'test@example.com' }) // Returns Users | null
143
- const posts = await client.findMany('posts', { where: { published: true } }) // Returns Posts[]
203
+ ```typescript
204
+ import { detectChanges, generateMigrationFromChanges } from 'driftsql'
205
+
206
+ const oldSchema = [
207
+ /* previous table definitions */
208
+ ]
209
+ const newSchema = [
210
+ /* updated table definitions */
211
+ ]
212
+
213
+ // Detect what changed
214
+ const changes = detectChanges(oldSchema, newSchema, 'postgres')
215
+
216
+ // Generate migration from changes
217
+ const migration = generateMigrationFromChanges(changes, '002', 'auto_migration')
218
+ ```
219
+
220
+ ### CLI Commands
221
+
222
+ ```bash
223
+ # Initialize project
224
+ driftsql init
225
+
226
+ # Create new migration
227
+ driftsql migrate:create add_users_table
228
+
229
+ # Run migrations
230
+ driftsql migrate:up
231
+
232
+ # Check migration status
233
+ driftsql migrate:status
234
+
235
+ # Rollback last migration
236
+ driftsql migrate:down
237
+
238
+ # Reset all migrations
239
+ driftsql migrate:reset
240
+
241
+ # Generate TypeScript types from database
242
+ driftsql db:inspect --output ./src/db-types.ts
243
+ ```
244
+
245
+ ## Performance Features
246
+
247
+ - **Connection Pooling**: Configurable pool size and timeouts
248
+ - **Query Caching**: Built-in LRU cache with TTL (default 5 seconds)
249
+ - **Smart Fallbacks**: Fast-path primary driver with automatic fallback support
250
+ - **Optimized Error Handling**: Reduced overhead in CRUD operations
251
+
252
+ ```typescript
253
+ const client = new SQLClient({
254
+ driver: new PostgresDriver({
255
+ connectionString: process.env.DATABASE_URL!,
256
+ max: 10, // Pool size
257
+ idle_timeout: 30, // Seconds
258
+ connect_timeout: 10, // Seconds
259
+ }),
260
+ cacheTTL: 5000, // Cache TTL in ms
261
+ })
262
+
263
+ // Cache management
264
+ client.clearCache()
265
+ const stats = client.getCacheStats()
144
266
  ```
145
267
 
268
+ ## Supported Databases
269
+
270
+ - ✅ **PostgreSQL** - Full feature support
271
+ - ✅ **MySQL** - Full feature support
272
+ - ✅ **SQLite** - Full feature support
273
+ - 🔄 More coming soon...
274
+
275
+ ## Column Types
276
+
277
+ **Numeric**: `serial`, `bigserial`, `integer`, `bigint`, `smallint`, `decimal`, `numeric`, `real`, `doublePrecision`
278
+
279
+ **String**: `text`, `varchar`, `char`
280
+
281
+ **Date/Time**: `timestamp`, `timestamptz`, `date`, `time`
282
+
283
+ **Other**: `boolean`, `json`, `jsonb`, `uuid`, `bytea`
284
+
285
+ ## Column Modifiers
286
+
287
+ ```typescript
288
+ column.primaryKey().notNull().unique().default(value).length(255).precision(10, 2).references('users', 'id').onDelete('CASCADE').check('age >= 18')
289
+ ```
290
+
291
+ ## Documentation
292
+
293
+ - [Schema Builder Guide](./SCHEMA.md) - Complete schema builder documentation
294
+ - [CLI Reference](./CLI.md) - All CLI commands and usage
295
+
296
+ ## Examples
297
+
298
+ Check the `examples/` directory for:
299
+
300
+ - Basic schema creation
301
+ - Migration generation
302
+ - Change detection
303
+ - Multiple database dialects
304
+
305
+ ## Contributing
306
+
307
+ Contributions are welcome! Please read our contributing guidelines.
308
+
146
309
  ## License
147
310
 
148
- Published under the [MIT](https://github.com/lassejlv/driftsql/blob/main/LICENSE) license.
311
+ MIT
312
+
313
+ ## Roadmap
314
+
315
+ - [x] PostgreSQL driver with helpers
316
+ - [x] Query caching
317
+ - [x] Schema builder
318
+ - [x] Migration system
319
+ - [x] Change detection
320
+ - [x] CLI tools
321
+ - [x] MySQL helpers
322
+ - [x] SQLite helpers
323
+ - [ ] MySQL driver implementation
324
+ - [ ] SQLite driver implementation
325
+ - [ ] More database drivers (SQL Server, Oracle, etc.)
326
+ - [ ] Schema diffing from live database
327
+ - [ ] Migration squashing
328
+ - [ ] Seeding system
@@ -0,0 +1 @@
1
+ export { };
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env node
2
+ import"../postgres-9C7eE0wB.js";import{a as e,o as t,r as n,s as r}from"../src-B1L6LdRV.js";import"../type-generator-CpqI7vBb.js";import i from"consola";import a from"node:fs/promises";import o from"node:path";import{Command as s}from"commander";const c=new s;c.name(`driftsql`).description(`DriftSQL CLI - Database migrations and schema management`).version(`0.0.1`),c.command(`migrate:up`).description(`Run all pending migrations`).option(`-d, --dir <directory>`,`Migrations directory`,`./migrations`).option(`-c, --config <path>`,`Config file path`,`./driftsql.config.ts`).action(async e=>{try{let{client:t,migrations:n}=await u(e.dir,e.config);await new r(t).upAll(n),await t.close(),i.success(`All migrations applied successfully`)}catch(e){i.error(`Migration failed:`,e),process.exit(1)}}),c.command(`migrate:down`).description(`Rollback the last migration`).option(`-d, --dir <directory>`,`Migrations directory`,`./migrations`).option(`-c, --config <path>`,`Config file path`,`./driftsql.config.ts`).action(async e=>{try{let{client:t,migrations:n}=await u(e.dir,e.config),a=new r(t),o=await a.getAppliedMigrations(),s=n.find(e=>e.version===o[o.length-1]);s?await a.down(s):i.info(`No migrations to rollback`),await t.close()}catch(e){i.error(`Rollback failed:`,e),process.exit(1)}}),c.command(`migrate:reset`).description(`Reset all migrations (down then up)`).option(`-d, --dir <directory>`,`Migrations directory`,`./migrations`).option(`-c, --config <path>`,`Config file path`,`./driftsql.config.ts`).action(async e=>{try{let{client:t,migrations:n}=await u(e.dir,e.config);await new r(t).reset(n),await t.close(),i.success(`All migrations reset successfully`)}catch(e){i.error(`Reset failed:`,e),process.exit(1)}}),c.command(`migrate:status`).description(`Show migration status`).option(`-d, --dir <directory>`,`Migrations directory`,`./migrations`).option(`-c, --config <path>`,`Config file path`,`./driftsql.config.ts`).action(async e=>{try{let{client:t,migrations:n}=await u(e.dir,e.config),a=await new r(t).getAppliedMigrations();i.info(`Migration Status:
3
+ `);for(let e of n){let t=a.includes(e.version)?`✓ Applied`:`✗ Pending`;i.log(`${t} - ${e.version} (${e.name})`)}await t.close()}catch(e){i.error(`Failed to get status:`,e),process.exit(1)}}),c.command(`migrate:create <name>`).description(`Create a new migration file`).option(`-d, --dir <directory>`,`Migrations directory`,`./migrations`).action(async(e,t)=>{try{let n=new Date().toISOString().replace(/[-:T.]/g,``).slice(0,14),r=`${n}_${e}.ts`,s=o.join(t.dir,r);await a.mkdir(t.dir,{recursive:!0});let c=`import { createMigration } from 'driftsql'
4
+
5
+ export const migration = createMigration('postgres')
6
+ .raw('-- Add your migration SQL here')
7
+ .build('${n}', '${e}')
8
+ `;await a.writeFile(s,c,`utf8`),i.success(`Created migration: ${r}`)}catch(e){i.error(`Failed to create migration:`,e),process.exit(1)}}),c.command(`migrate:generate [name]`).description(`Automatically generate migration from schema changes`).option(`-s, --schema <path>`,`Schema file path`,`./schema.ts`).option(`-d, --dir <directory>`,`Migrations directory`,`./migrations`).action(async(r,s)=>{try{let c=new n,l=o.resolve(process.cwd(),s.schema);i.start(`Loading schema...`);let u=await import(l),d=u.default||u.schema;(!d||!Array.isArray(d))&&(i.error(`Schema file must export default or named "schema" as an array of table definitions`),i.info(`Example: export default [usersTable.getDefinition(), postsTable.getDefinition()]`),process.exit(1));let f=d,p=await c.load();if(!p){i.info(`No previous schema snapshot found, creating initial migration...`);let e=new Date().toISOString().replace(/[-:T.]/g,``).slice(0,14),t=r||`initial`,n=`${e}_${t}.ts`,l=o.join(s.dir,n);await a.mkdir(s.dir,{recursive:!0});let{PostgresGenerator:u}=await import(`../postgres-DfhzvfQU.js`),d=new u,p=f.map(e=>d.generateCreateTable(e)).map(e=>` .raw(\`${e.replace(/`/g,"\\`")}\`)`).join(`
9
+ `),m=`import { createMigration } from 'driftsql'
10
+
11
+ // Initial migration - automatically generated
12
+ // Generated at: ${new Date().toISOString()}
13
+
14
+ export const migration = createMigration('postgres')
15
+ ${p}
16
+ .build('${e}', '${t}')
17
+ `;await a.writeFile(l,m,`utf8`),await c.save(f);let{generateTypesFromSchema:h}=await import(`../type-generator-DdCKALf8.js`);await h(f,o.join(process.cwd(),`db-types.ts`)),i.success(`\nCreated initial migration: ${n}`),i.success(`Generated TypeScript types: db-types.ts`),i.info(`Snapshot saved. Run "driftsql migrate:up" to apply changes.`);return}i.info(`Detecting changes...`);let m=e(p.tables,f,`postgres`);if(m.length===0){i.success(`No schema changes detected!`);return}i.info(`Found ${m.length} change(s):`),m.forEach((e,t)=>{i.log(` ${t+1}. ${e.type} - ${e.table}`)});let h=new Date().toISOString().replace(/[-:T.]/g,``).slice(0,14),g=r||`auto_migration`,_=`${h}_${g}.ts`,v=o.join(s.dir,_);await a.mkdir(s.dir,{recursive:!0});let y=t(m,h,g).build(h,g).up.map(e=>` .raw(\`${e.replace(/`/g,"\\`")}\``).join(`
18
+ `),b=`import { createMigration } from 'driftsql'
19
+
20
+ // This migration was automatically generated
21
+ // Generated at: ${new Date().toISOString()}
22
+ // Changes: ${m.length}
23
+
24
+ export const migration = createMigration('postgres')
25
+ ${y}
26
+ .build('${h}', '${g}')
27
+ `;await a.writeFile(v,b,`utf8`),await c.save(f);let{generateTypesFromSchema:x}=await import(`../type-generator-DdCKALf8.js`);await x(f,o.join(process.cwd(),`db-types.ts`)),i.success(`\nGenerated migration: ${_}`),i.success(`Updated TypeScript types: db-types.ts`),i.info(`Snapshot updated. Run "driftsql migrate:up" to apply changes.`)}catch(e){i.error(`Failed to generate migration:`,e),process.exit(1)}}),c.command(`db:inspect`).description(`Inspect database and generate TypeScript types`).option(`-c, --config <path>`,`Config file path`,`./driftsql.config.ts`).option(`-o, --output <path>`,`Output file path`,`./db-types.ts`).action(async e=>{try{let t=await l(e.config);await t.inspectDB({driver:t.getDriver(),outputFile:e.output}),await t.close()}catch(e){i.error(`Inspection failed:`,e),process.exit(1)}}),c.command(`generate:types`).description(`Generate TypeScript types from schema file`).option(`-s, --schema <path>`,`Schema file path`,`./schema.ts`).option(`-o, --output <path>`,`Output file path`,`./db-types.ts`).action(async e=>{try{let t=o.resolve(process.cwd(),e.schema),n=o.resolve(process.cwd(),e.output);i.start(`Loading schema...`);let r=await import(t),a=r.default||r.schema;(!a||!Array.isArray(a))&&(i.error(`Schema file must export default or named "schema" as an array of table definitions`),process.exit(1));let{generateTypesFromSchema:s}=await import(`../type-generator-DdCKALf8.js`);await s(a,n),i.success(`TypeScript types generated: ${e.output}`)}catch(e){i.error(`Type generation failed:`,e),process.exit(1)}}),c.command(`init`).description(`Initialize DriftSQL with a basic notes schema`).option(`-d, --dir <directory>`,`Migrations directory`,`./migrations`).action(async e=>{try{await a.mkdir(e.dir,{recursive:!0});let t=`.driftsql/
28
+ .env
29
+ `,n=o.join(process.cwd(),`driftsql.config.ts`),r=o.join(process.cwd(),`schema.ts`),s=o.join(process.cwd(),`.env.example`),c=o.join(process.cwd(),`.gitignore`),l=[{path:n,content:`import { SQLClient, PostgresDriver } from 'driftsql'
30
+
31
+ export default new SQLClient({
32
+ driver: new PostgresDriver({
33
+ connectionString: process.env.DATABASE_URL!,
34
+ }),
35
+ })
36
+ `,name:`driftsql.config.ts`},{path:r,content:`import { createTable, serial, varchar, text, timestamp, boolean } from 'driftsql'
37
+
38
+ const notesTable = createTable('notes', (table) => {
39
+ table
40
+ .column(serial('id').primaryKey())
41
+ .column(varchar('title', 255).notNull())
42
+ .column(text('content'))
43
+ .column(boolean('is_archived').default(false).notNull())
44
+ .column(timestamp('created_at').default('CURRENT_TIMESTAMP').notNull())
45
+ .column(timestamp('updated_at').default('CURRENT_TIMESTAMP').notNull())
46
+ .index('idx_notes_archived', ['is_archived'])
47
+ .index('idx_notes_created_at', ['created_at'])
48
+ })
49
+
50
+ // Export array of table definitions
51
+ export default [notesTable.getDefinition()]
52
+ `,name:`schema.ts`},{path:s,content:`DATABASE_URL=postgresql://user:password@localhost:5432/mydb
53
+ `,name:`.env.example`}];for(let e of l)try{await a.access(e.path),i.warn(`${e.name} already exists, skipping...`)}catch{await a.writeFile(e.path,e.content,`utf8`),i.success(`Created ${e.name}`)}try{(await a.readFile(c,`utf8`)).includes(`.driftsql/`)||(await a.appendFile(c,`
54
+ `+t),i.success(`Updated .gitignore`))}catch{await a.writeFile(c,t,`utf8`),i.success(`Created .gitignore`)}i.success(`
55
+ ✨ DriftSQL initialized successfully!
56
+ `),i.info(`Next steps:`),i.info(`1. Copy .env.example to .env and update DATABASE_URL`),i.info(`2. Run: driftsql migrate:generate initial (generates migration + types)`),i.info(`3. Run: driftsql migrate:up`),i.info(`4. Import Database type from db-types.ts for type safety`),i.info(`5. Edit schema.ts and run migrate:generate to auto-detect changes!
57
+ `)}catch(e){i.error(`Initialization failed:`,e),process.exit(1)}});async function l(e){try{let t=await import(o.resolve(process.cwd(),e));return t.default||t.client}catch(t){throw i.error(`Failed to load config from ${e}`),t}}async function u(e,t){let n=await l(t),r=[];try{let t=o.resolve(process.cwd(),e),i=(await a.readdir(t)).filter(e=>e.endsWith(`.ts`)||e.endsWith(`.js`)).sort();for(let e of i){let n=await import(o.join(t,e)),i=n.migration||n.default;i&&r.push(i)}return{client:n,migrations:r}}catch(t){throw i.error(`Failed to load migrations from ${e}`),t}}c.parse();export{};