@flightdev/db 0.0.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.
@@ -0,0 +1,26 @@
1
+
2
+ > @flightdev/db@0.0.2 build E:\testear framework\Flight\packages\db
3
+ > tsup
4
+
5
+ CLI Building entry: src/d1.ts, src/index.ts, src/neon.ts, src/postgres.ts, src/supabase.ts, src/turso.ts
6
+ CLI Using tsconfig: tsconfig.json
7
+ CLI tsup v8.5.1
8
+ CLI Using tsup config: E:\testear framework\Flight\packages\db\tsup.config.ts
9
+ CLI Target: node20
10
+ CLI Cleaning output folder
11
+ ESM Build start
12
+ ESM dist\index.js 402.00 B
13
+ ESM dist\postgres.js 2.39 KB
14
+ ESM dist\neon.js 2.96 KB
15
+ ESM dist\supabase.js 1.93 KB
16
+ ESM dist\d1.js 2.51 KB
17
+ ESM dist\turso.js 2.70 KB
18
+ ESM ⚡️ Build success in 23ms
19
+ DTS Build start
20
+ DTS ⚡️ Build success in 6371ms
21
+ DTS dist\d1.d.ts 1.53 KB
22
+ DTS dist\neon.d.ts 857.00 B
23
+ DTS dist\postgres.d.ts 907.00 B
24
+ DTS dist\supabase.d.ts 1.16 KB
25
+ DTS dist\turso.d.ts 916.00 B
26
+ DTS dist\index.d.ts 2.92 KB
@@ -0,0 +1,4 @@
1
+
2
+ > @flight-framework/db@0.0.2 typecheck E:\testear framework\Flight\packages\db
3
+ > tsc --noEmit
4
+
package/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ # @flight-framework/db
2
+
3
+ ## 0.0.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 379f5ee: Update
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024-2026 Flight Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,226 @@
1
+ # @flight-framework/db
2
+
3
+ Database abstraction layer for Flight Framework. Connect to any database with a unified, type-safe API.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @flight-framework/db
9
+ ```
10
+
11
+ Install the driver for your database:
12
+
13
+ ```bash
14
+ # PostgreSQL
15
+ npm install pg
16
+
17
+ # Turso / SQLite
18
+ npm install @libsql/client
19
+
20
+ # Neon Serverless
21
+ npm install @neondatabase/serverless
22
+
23
+ # Supabase
24
+ npm install @supabase/supabase-js
25
+ ```
26
+
27
+ ## Quick Start
28
+
29
+ ```typescript
30
+ import { createDb } from '@flight-framework/db';
31
+ import { postgres } from '@flight-framework/db/postgres';
32
+
33
+ const db = createDb(postgres({
34
+ connectionString: process.env.DATABASE_URL,
35
+ }));
36
+
37
+ // Query with type inference
38
+ const users = await db.query<{ id: string; email: string }>(
39
+ 'SELECT * FROM users WHERE active = $1',
40
+ [true]
41
+ );
42
+
43
+ console.log(users.rows);
44
+ ```
45
+
46
+ ## Drivers
47
+
48
+ ### PostgreSQL
49
+
50
+ Standard PostgreSQL driver using `pg` with connection pooling.
51
+
52
+ ```typescript
53
+ import { postgres } from '@flight-framework/db/postgres';
54
+
55
+ const driver = postgres({
56
+ connectionString: 'postgresql://user:pass@localhost:5432/mydb',
57
+ // Or use individual options:
58
+ host: 'localhost',
59
+ port: 5432,
60
+ database: 'mydb',
61
+ user: 'user',
62
+ password: 'pass',
63
+ ssl: true,
64
+ poolSize: 10,
65
+ timeout: 30000,
66
+ });
67
+ ```
68
+
69
+ ### Turso / SQLite
70
+
71
+ Cloud SQLite with Turso or local SQLite files.
72
+
73
+ ```typescript
74
+ import { turso } from '@flight-framework/db/turso';
75
+
76
+ // Turso Cloud
77
+ const cloud = turso({
78
+ url: 'libsql://your-db.turso.io',
79
+ authToken: process.env.TURSO_AUTH_TOKEN,
80
+ });
81
+
82
+ // Local SQLite
83
+ const local = turso({
84
+ url: 'file:local.db',
85
+ });
86
+ ```
87
+
88
+ ### Neon Serverless
89
+
90
+ Edge-compatible PostgreSQL for serverless environments.
91
+
92
+ ```typescript
93
+ import { neon } from '@flight-framework/db/neon';
94
+
95
+ // HTTP mode (recommended for serverless)
96
+ const http = neon({
97
+ connectionString: process.env.NEON_DATABASE_URL,
98
+ mode: 'http',
99
+ });
100
+
101
+ // WebSocket mode (for transactions)
102
+ const ws = neon({
103
+ connectionString: process.env.NEON_DATABASE_URL,
104
+ mode: 'websocket',
105
+ });
106
+ ```
107
+
108
+ ### Supabase
109
+
110
+ Direct database access with Supabase's query builder.
111
+
112
+ ```typescript
113
+ import { supabase } from '@flight-framework/db/supabase';
114
+
115
+ const driver = supabase({
116
+ url: process.env.SUPABASE_URL,
117
+ key: process.env.SUPABASE_ANON_KEY,
118
+ schema: 'public',
119
+ });
120
+ ```
121
+
122
+ ### Cloudflare D1
123
+
124
+ Native Cloudflare D1 support for edge SQLite.
125
+
126
+ ```typescript
127
+ import { d1 } from '@flight-framework/db/d1';
128
+
129
+ export default {
130
+ async fetch(request, env) {
131
+ const db = createDb(d1({ binding: env.DB }));
132
+ const users = await db.query('SELECT * FROM users');
133
+ return Response.json(users.rows);
134
+ }
135
+ };
136
+ ```
137
+
138
+ ## API Reference
139
+
140
+ ### Database Interface
141
+
142
+ ```typescript
143
+ interface Database {
144
+ // Run a query that returns rows
145
+ query<T>(sql: string, params?: unknown[]): Promise<QueryResult<T>>;
146
+
147
+ // Execute a statement (INSERT, UPDATE, DELETE)
148
+ execute(sql: string, params?: unknown[]): Promise<ExecuteResult>;
149
+
150
+ // Run operations in a transaction
151
+ transaction<T>(fn: (tx: Transaction) => Promise<T>): Promise<T>;
152
+
153
+ // Close the connection
154
+ close(): Promise<void>;
155
+
156
+ // Check connection health
157
+ ping(): Promise<boolean>;
158
+ }
159
+ ```
160
+
161
+ ### Query Result
162
+
163
+ ```typescript
164
+ interface QueryResult<T> {
165
+ rows: T[];
166
+ rowCount: number;
167
+ raw?: unknown;
168
+ }
169
+ ```
170
+
171
+ ### Execute Result
172
+
173
+ ```typescript
174
+ interface ExecuteResult {
175
+ rowsAffected: number;
176
+ insertId?: string | number;
177
+ raw?: unknown;
178
+ }
179
+ ```
180
+
181
+ ## Transactions
182
+
183
+ All drivers support transactions with automatic rollback on error.
184
+
185
+ ```typescript
186
+ const result = await db.transaction(async (tx) => {
187
+ const user = await tx.execute(
188
+ 'INSERT INTO users (email) VALUES ($1) RETURNING id',
189
+ ['user@example.com']
190
+ );
191
+
192
+ await tx.execute(
193
+ 'INSERT INTO profiles (user_id, name) VALUES ($1, $2)',
194
+ [user.insertId, 'John Doe']
195
+ );
196
+
197
+ return user.insertId;
198
+ });
199
+ ```
200
+
201
+ ## Type Safety
202
+
203
+ Define your row types for compile-time safety.
204
+
205
+ ```typescript
206
+ interface User {
207
+ id: string;
208
+ email: string;
209
+ name: string;
210
+ created_at: Date;
211
+ }
212
+
213
+ const users = await db.query<User>('SELECT * FROM users');
214
+ // users.rows is typed as User[]
215
+ ```
216
+
217
+ ## Best Practices
218
+
219
+ 1. **Use connection pooling** - All drivers support connection pools by default.
220
+ 2. **Parameterize queries** - Always use parameterized queries to prevent SQL injection.
221
+ 3. **Handle errors** - Wrap database operations in try-catch blocks.
222
+ 4. **Close connections** - Call `db.close()` when shutting down your application.
223
+
224
+ ## License
225
+
226
+ MIT
package/dist/d1.d.ts ADDED
@@ -0,0 +1,60 @@
1
+ import { Driver as DatabaseDriver } from './index.js';
2
+
3
+ /**
4
+ * @flightdev/db/d1 - Cloudflare D1 Driver
5
+ *
6
+ * Native Cloudflare D1 support for edge SQLite.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * // In your Cloudflare Worker
11
+ * import { d1 } from '@flightdev/db/d1';
12
+ * import { createDb } from '@flightdev/db';
13
+ *
14
+ * export default {
15
+ * async fetch(request, env) {
16
+ * const db = createDb(d1({ binding: env.DB }));
17
+ * const users = await db.query('SELECT * FROM users');
18
+ * return Response.json(users.rows);
19
+ * }
20
+ * };
21
+ * ```
22
+ */
23
+
24
+ /** D1 Database binding from Cloudflare Workers */
25
+ interface D1Database {
26
+ prepare(query: string): D1PreparedStatement;
27
+ batch<T = unknown>(statements: D1PreparedStatement[]): Promise<D1Result<T>[]>;
28
+ exec(query: string): Promise<D1ExecResult>;
29
+ }
30
+ interface D1PreparedStatement {
31
+ bind(...values: unknown[]): D1PreparedStatement;
32
+ first<T = unknown>(colName?: string): Promise<T>;
33
+ run(): Promise<D1Result>;
34
+ all<T = unknown>(): Promise<D1Result<T>>;
35
+ raw<T = unknown>(): Promise<T[]>;
36
+ }
37
+ interface D1Result<T = unknown> {
38
+ results?: T[];
39
+ success: boolean;
40
+ error?: string;
41
+ meta: {
42
+ changes: number;
43
+ last_row_id: number;
44
+ duration: number;
45
+ };
46
+ }
47
+ interface D1ExecResult {
48
+ count: number;
49
+ duration: number;
50
+ }
51
+ interface D1Config {
52
+ /** D1 database binding from env */
53
+ binding: D1Database;
54
+ }
55
+ /**
56
+ * Create a Cloudflare D1 driver
57
+ */
58
+ declare function d1(config: D1Config): DatabaseDriver;
59
+
60
+ export { type D1Config, type D1Database, d1, d1 as default };
package/dist/d1.js ADDED
@@ -0,0 +1,97 @@
1
+ // src/d1.ts
2
+ function d1(config) {
3
+ const db = config.binding;
4
+ return {
5
+ name: "d1",
6
+ async query(sql, params) {
7
+ let stmt = db.prepare(sql);
8
+ if (params?.length) {
9
+ stmt = stmt.bind(...params);
10
+ }
11
+ const result = await stmt.all();
12
+ return {
13
+ rows: result.results ?? [],
14
+ rowCount: result.results?.length ?? 0,
15
+ raw: result
16
+ };
17
+ },
18
+ async execute(sql, params) {
19
+ let stmt = db.prepare(sql);
20
+ if (params?.length) {
21
+ stmt = stmt.bind(...params);
22
+ }
23
+ const result = await stmt.run();
24
+ return {
25
+ rowsAffected: result.meta.changes,
26
+ insertId: result.meta.last_row_id,
27
+ raw: result
28
+ };
29
+ },
30
+ async transaction(fn) {
31
+ const statements = [];
32
+ const results = [];
33
+ const tx = {
34
+ async query(sql, params) {
35
+ let stmt = db.prepare(sql);
36
+ if (params?.length) {
37
+ stmt = stmt.bind(...params);
38
+ }
39
+ statements.push(stmt);
40
+ const placeholder = { rows: [], rowCount: 0 };
41
+ results.push(placeholder);
42
+ return placeholder;
43
+ },
44
+ async execute(sql, params) {
45
+ let stmt = db.prepare(sql);
46
+ if (params?.length) {
47
+ stmt = stmt.bind(...params);
48
+ }
49
+ statements.push(stmt);
50
+ const placeholder = { rowsAffected: 0 };
51
+ results.push(placeholder);
52
+ return placeholder;
53
+ },
54
+ async commit() {
55
+ const batchResults = await db.batch(statements);
56
+ batchResults.forEach((result, i) => {
57
+ const placeholder = results[i];
58
+ if (placeholder && "rows" in placeholder) {
59
+ placeholder.rows = result.results ?? [];
60
+ placeholder.rowCount = result.results?.length ?? 0;
61
+ } else if (placeholder) {
62
+ placeholder.rowsAffected = result.meta.changes;
63
+ placeholder.insertId = result.meta.last_row_id;
64
+ }
65
+ });
66
+ },
67
+ async rollback() {
68
+ statements.length = 0;
69
+ results.length = 0;
70
+ }
71
+ };
72
+ try {
73
+ const result = await fn(tx);
74
+ await tx.commit();
75
+ return result;
76
+ } catch (error) {
77
+ await tx.rollback();
78
+ throw error;
79
+ }
80
+ },
81
+ async close() {
82
+ },
83
+ async ping() {
84
+ try {
85
+ await db.prepare("SELECT 1").first();
86
+ return true;
87
+ } catch {
88
+ return false;
89
+ }
90
+ }
91
+ };
92
+ }
93
+ var d1_default = d1;
94
+ export {
95
+ d1,
96
+ d1_default as default
97
+ };
@@ -0,0 +1,87 @@
1
+ /**
2
+ * @flightdev/db - Agnostic Database Layer
3
+ *
4
+ * Universal database abstraction with pluggable drivers.
5
+ * Inspired by Drizzle ORM's driver pattern but framework-agnostic.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * import { createDb } from '@flightdev/db';
10
+ * import { postgres } from '@flightdev/db/postgres';
11
+ *
12
+ * const db = createDb(postgres({ connectionString: process.env.DATABASE_URL }));
13
+ *
14
+ * const users = await db.query('SELECT * FROM users');
15
+ * await db.execute('INSERT INTO users (name) VALUES (?)', ['John']);
16
+ * ```
17
+ */
18
+ /** Result of a database query */
19
+ interface QueryResult<T = Record<string, unknown>> {
20
+ rows: T[];
21
+ rowCount: number;
22
+ /** Raw result from underlying driver (for advanced use) */
23
+ raw?: unknown;
24
+ }
25
+ /** Result of a database execute (INSERT, UPDATE, DELETE) */
26
+ interface ExecuteResult {
27
+ rowsAffected: number;
28
+ insertId?: string | number;
29
+ raw?: unknown;
30
+ }
31
+ /** Transaction interface */
32
+ interface Transaction {
33
+ query<T = Record<string, unknown>>(sql: string, params?: unknown[]): Promise<QueryResult<T>>;
34
+ execute(sql: string, params?: unknown[]): Promise<ExecuteResult>;
35
+ commit(): Promise<void>;
36
+ rollback(): Promise<void>;
37
+ }
38
+ /** Database connection interface - what drivers must implement */
39
+ interface DatabaseDriver {
40
+ /** Driver name for identification */
41
+ readonly name: string;
42
+ /** Query that returns rows */
43
+ query<T = Record<string, unknown>>(sql: string, params?: unknown[]): Promise<QueryResult<T>>;
44
+ /** Execute that doesn't return rows (INSERT, UPDATE, DELETE) */
45
+ execute(sql: string, params?: unknown[]): Promise<ExecuteResult>;
46
+ /** Begin a transaction */
47
+ transaction<T>(fn: (tx: Transaction) => Promise<T>): Promise<T>;
48
+ /** Close the connection */
49
+ close(): Promise<void>;
50
+ /** Check if connection is alive */
51
+ ping(): Promise<boolean>;
52
+ }
53
+ /** Database instance with full API */
54
+ interface Database extends DatabaseDriver {
55
+ /** The underlying driver */
56
+ readonly driver: DatabaseDriver;
57
+ /** Infer types from database (Better Auth style) */
58
+ readonly $Infer: {
59
+ Query: QueryResult;
60
+ Execute: ExecuteResult;
61
+ };
62
+ }
63
+ /**
64
+ * Create a database instance from a driver
65
+ *
66
+ * @example
67
+ * ```typescript
68
+ * import { createDb } from '@flightdev/db';
69
+ * import { postgres } from '@flightdev/db/postgres';
70
+ *
71
+ * const db = createDb(postgres({ connectionString: process.env.DATABASE_URL }));
72
+ * ```
73
+ */
74
+ declare function createDb(driver: DatabaseDriver): Database;
75
+ /** Infer row type from a query */
76
+ type InferRow<T extends QueryResult> = T['rows'][number];
77
+ /** Database configuration base */
78
+ interface DatabaseConfig {
79
+ /** Connection string */
80
+ connectionString?: string;
81
+ /** Pool size */
82
+ poolSize?: number;
83
+ /** Connection timeout in ms */
84
+ timeout?: number;
85
+ }
86
+
87
+ export { type Database, type DatabaseConfig, type DatabaseDriver, type DatabaseDriver as Driver, type ExecuteResult, type InferRow, type QueryResult, type Transaction, createDb };
package/dist/index.js ADDED
@@ -0,0 +1,19 @@
1
+ // src/index.ts
2
+ function createDb(driver) {
3
+ return {
4
+ name: driver.name,
5
+ driver,
6
+ query: (sql, params) => driver.query(sql, params),
7
+ execute: (sql, params) => driver.execute(sql, params),
8
+ transaction: (fn) => driver.transaction(fn),
9
+ close: () => driver.close(),
10
+ ping: () => driver.ping(),
11
+ $Infer: {
12
+ Query: {},
13
+ Execute: {}
14
+ }
15
+ };
16
+ }
17
+ export {
18
+ createDb
19
+ };
package/dist/neon.d.ts ADDED
@@ -0,0 +1,32 @@
1
+ import { Driver as DatabaseDriver } from './index.js';
2
+
3
+ /**
4
+ * @flightdev/db/neon - Neon Serverless Driver
5
+ *
6
+ * Uses @neondatabase/serverless for edge-compatible PostgreSQL.
7
+ * Supports both HTTP (single queries) and WebSocket (transactions) modes.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * import { neon } from '@flightdev/db/neon';
12
+ * import { createDb } from '@flightdev/db';
13
+ *
14
+ * const db = createDb(neon({
15
+ * connectionString: process.env.NEON_DATABASE_URL,
16
+ * mode: 'http', // 'http' for serverless, 'websocket' for transactions
17
+ * }));
18
+ * ```
19
+ */
20
+
21
+ interface NeonConfig {
22
+ /** Neon connection string */
23
+ connectionString: string;
24
+ /** Connection mode */
25
+ mode?: 'http' | 'websocket';
26
+ }
27
+ /**
28
+ * Create a Neon Serverless driver
29
+ */
30
+ declare function neon(config: NeonConfig): DatabaseDriver;
31
+
32
+ export { type NeonConfig, neon as default, neon };
package/dist/neon.js ADDED
@@ -0,0 +1,117 @@
1
+ // src/neon.ts
2
+ function neon(config) {
3
+ const mode = config.mode ?? "http";
4
+ let sql = null;
5
+ let pool = null;
6
+ async function getSql() {
7
+ if (!sql) {
8
+ const neonModule = await import("@neondatabase/serverless");
9
+ if (mode === "http") {
10
+ sql = neonModule.neon(config.connectionString);
11
+ } else {
12
+ const { Pool } = neonModule;
13
+ pool = new Pool({ connectionString: config.connectionString });
14
+ sql = pool;
15
+ }
16
+ }
17
+ return { sql, pool };
18
+ }
19
+ return {
20
+ name: "neon",
21
+ async query(sqlQuery, params) {
22
+ const { sql: client } = await getSql();
23
+ if (mode === "http") {
24
+ const rows = await client(sqlQuery, params ?? []);
25
+ return {
26
+ rows,
27
+ rowCount: rows.length,
28
+ raw: rows
29
+ };
30
+ } else {
31
+ const result = await client.query(sqlQuery, params);
32
+ return {
33
+ rows: result.rows,
34
+ rowCount: result.rowCount ?? 0,
35
+ raw: result
36
+ };
37
+ }
38
+ },
39
+ async execute(sqlQuery, params) {
40
+ const { sql: client } = await getSql();
41
+ if (mode === "http") {
42
+ const result = await client(sqlQuery, params ?? []);
43
+ return {
44
+ rowsAffected: result.length ?? 0,
45
+ raw: result
46
+ };
47
+ } else {
48
+ const result = await client.query(sqlQuery, params);
49
+ return {
50
+ rowsAffected: result.rowCount ?? 0,
51
+ raw: result
52
+ };
53
+ }
54
+ },
55
+ async transaction(fn) {
56
+ if (mode === "http") {
57
+ throw new Error('Transactions require websocket mode. Use neon({ mode: "websocket" })');
58
+ }
59
+ const { pool: p } = await getSql();
60
+ const client = await p.connect();
61
+ try {
62
+ await client.query("BEGIN");
63
+ const tx = {
64
+ async query(sqlQuery, params) {
65
+ const result2 = await client.query(sqlQuery, params);
66
+ return {
67
+ rows: result2.rows,
68
+ rowCount: result2.rowCount ?? 0,
69
+ raw: result2
70
+ };
71
+ },
72
+ async execute(sqlQuery, params) {
73
+ const result2 = await client.query(sqlQuery, params);
74
+ return {
75
+ rowsAffected: result2.rowCount ?? 0,
76
+ raw: result2
77
+ };
78
+ },
79
+ async commit() {
80
+ await client.query("COMMIT");
81
+ },
82
+ async rollback() {
83
+ await client.query("ROLLBACK");
84
+ }
85
+ };
86
+ const result = await fn(tx);
87
+ await client.query("COMMIT");
88
+ return result;
89
+ } catch (error) {
90
+ await client.query("ROLLBACK");
91
+ throw error;
92
+ } finally {
93
+ client.release();
94
+ }
95
+ },
96
+ async close() {
97
+ if (pool) {
98
+ await pool.end();
99
+ pool = null;
100
+ }
101
+ sql = null;
102
+ },
103
+ async ping() {
104
+ try {
105
+ await this.query("SELECT 1");
106
+ return true;
107
+ } catch {
108
+ return false;
109
+ }
110
+ }
111
+ };
112
+ }
113
+ var neon_default = neon;
114
+ export {
115
+ neon_default as default,
116
+ neon
117
+ };