@parsrun/database 0.1.0
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 +103 -0
- package/dist/adapters/d1.d.ts +56 -0
- package/dist/adapters/d1.js +115 -0
- package/dist/adapters/d1.js.map +1 -0
- package/dist/adapters/neon.d.ts +49 -0
- package/dist/adapters/neon.js +145 -0
- package/dist/adapters/neon.js.map +1 -0
- package/dist/adapters/postgres.d.ts +59 -0
- package/dist/adapters/postgres.js +165 -0
- package/dist/adapters/postgres.js.map +1 -0
- package/dist/index.d.ts +177 -0
- package/dist/index.js +651 -0
- package/dist/index.js.map +1 -0
- package/dist/types-DgBIyTeZ.d.ts +198 -0
- package/package.json +70 -0
package/README.md
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# @parsrun/database
|
|
2
|
+
|
|
3
|
+
Database utilities for Pars with Drizzle ORM helpers and multi-runtime support.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Drizzle ORM**: Type-safe database operations
|
|
8
|
+
- **Multi-Adapter**: PostgreSQL, Neon, Cloudflare D1
|
|
9
|
+
- **Edge-Compatible**: Works on Cloudflare Workers, Deno
|
|
10
|
+
- **Migrations**: Schema migration utilities
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
pnpm add @parsrun/database drizzle-orm
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Quick Start
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
import { createDatabase } from '@parsrun/database';
|
|
22
|
+
|
|
23
|
+
const db = createDatabase({
|
|
24
|
+
adapter: 'postgres',
|
|
25
|
+
connectionString: process.env.DATABASE_URL,
|
|
26
|
+
});
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## API Overview
|
|
30
|
+
|
|
31
|
+
### Adapters
|
|
32
|
+
|
|
33
|
+
#### PostgreSQL
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
import { createPostgresAdapter } from '@parsrun/database/adapters/postgres';
|
|
37
|
+
|
|
38
|
+
const db = createPostgresAdapter({
|
|
39
|
+
connectionString: 'postgres://...',
|
|
40
|
+
});
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
#### Neon (Serverless PostgreSQL)
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
import { createNeonAdapter } from '@parsrun/database/adapters/neon';
|
|
47
|
+
|
|
48
|
+
const db = createNeonAdapter({
|
|
49
|
+
connectionString: process.env.DATABASE_URL,
|
|
50
|
+
});
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
#### Cloudflare D1
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
import { createD1Adapter } from '@parsrun/database/adapters/d1';
|
|
57
|
+
|
|
58
|
+
// In Cloudflare Worker
|
|
59
|
+
const db = createD1Adapter({
|
|
60
|
+
database: env.DB,
|
|
61
|
+
});
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Database Operations
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
import { users } from './schema';
|
|
68
|
+
|
|
69
|
+
// Insert
|
|
70
|
+
await db.insert(users).values({ name: 'John' });
|
|
71
|
+
|
|
72
|
+
// Select
|
|
73
|
+
const allUsers = await db.select().from(users);
|
|
74
|
+
|
|
75
|
+
// Update
|
|
76
|
+
await db.update(users).set({ name: 'Jane' }).where(eq(users.id, 1));
|
|
77
|
+
|
|
78
|
+
// Delete
|
|
79
|
+
await db.delete(users).where(eq(users.id, 1));
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### With Multi-Tenancy
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
import { withTenant } from '@parsrun/database';
|
|
86
|
+
|
|
87
|
+
// Automatically filter by tenant
|
|
88
|
+
const tenantDb = withTenant(db, tenantId);
|
|
89
|
+
const users = await tenantDb.select().from(users);
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Exports
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
import { ... } from '@parsrun/database'; // Main exports
|
|
96
|
+
import { ... } from '@parsrun/database/adapters/postgres'; // PostgreSQL
|
|
97
|
+
import { ... } from '@parsrun/database/adapters/neon'; // Neon
|
|
98
|
+
import { ... } from '@parsrun/database/adapters/d1'; // Cloudflare D1
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## License
|
|
102
|
+
|
|
103
|
+
MIT
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { drizzle } from 'drizzle-orm/d1';
|
|
2
|
+
import { a as DatabaseAdapter, c as D1Config, f as DatabaseHealth, d as D1Database } from '../types-DgBIyTeZ.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @parsrun/database - Cloudflare D1 Adapter
|
|
6
|
+
* Cloudflare D1 (SQLite) adapter - native edge database
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Cloudflare D1 Database Adapter
|
|
11
|
+
* Native SQLite database for Cloudflare Workers
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* // In Cloudflare Worker
|
|
16
|
+
* export default {
|
|
17
|
+
* async fetch(request, env) {
|
|
18
|
+
* const db = createD1Adapter({
|
|
19
|
+
* type: 'd1',
|
|
20
|
+
* binding: env.DB, // D1 binding from wrangler.toml
|
|
21
|
+
* });
|
|
22
|
+
*
|
|
23
|
+
* const users = await db.drizzle().select().from(usersTable);
|
|
24
|
+
* return new Response(JSON.stringify(users));
|
|
25
|
+
* }
|
|
26
|
+
* }
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
declare class D1Adapter implements DatabaseAdapter {
|
|
30
|
+
readonly type: "d1";
|
|
31
|
+
private binding;
|
|
32
|
+
private db;
|
|
33
|
+
constructor(config: D1Config);
|
|
34
|
+
execute<T = unknown>(sql: string): Promise<T[]>;
|
|
35
|
+
ping(): Promise<boolean>;
|
|
36
|
+
health(): Promise<DatabaseHealth>;
|
|
37
|
+
drizzle(): ReturnType<typeof drizzle>;
|
|
38
|
+
close(): Promise<void>;
|
|
39
|
+
/**
|
|
40
|
+
* Get the raw D1 binding
|
|
41
|
+
*/
|
|
42
|
+
getBinding(): D1Database;
|
|
43
|
+
/**
|
|
44
|
+
* Execute a batch of statements
|
|
45
|
+
*/
|
|
46
|
+
batch<T = unknown>(statements: Array<{
|
|
47
|
+
sql: string;
|
|
48
|
+
params?: unknown[];
|
|
49
|
+
}>): Promise<T[][]>;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Create a D1 adapter
|
|
53
|
+
*/
|
|
54
|
+
declare function createD1Adapter(config: D1Config): D1Adapter;
|
|
55
|
+
|
|
56
|
+
export { D1Adapter, createD1Adapter };
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
// src/adapters/d1.ts
|
|
2
|
+
import { drizzle } from "drizzle-orm/d1";
|
|
3
|
+
|
|
4
|
+
// src/types.ts
|
|
5
|
+
var DatabaseError = class extends Error {
|
|
6
|
+
constructor(message, code, cause) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.code = code;
|
|
9
|
+
this.cause = cause;
|
|
10
|
+
this.name = "DatabaseError";
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
var DatabaseErrorCodes = {
|
|
14
|
+
CONNECTION_FAILED: "CONNECTION_FAILED",
|
|
15
|
+
QUERY_FAILED: "QUERY_FAILED",
|
|
16
|
+
TRANSACTION_FAILED: "TRANSACTION_FAILED",
|
|
17
|
+
MIGRATION_FAILED: "MIGRATION_FAILED",
|
|
18
|
+
INVALID_CONFIG: "INVALID_CONFIG",
|
|
19
|
+
ADAPTER_NOT_AVAILABLE: "ADAPTER_NOT_AVAILABLE",
|
|
20
|
+
TIMEOUT: "TIMEOUT",
|
|
21
|
+
CONSTRAINT_VIOLATION: "CONSTRAINT_VIOLATION",
|
|
22
|
+
NOT_FOUND: "NOT_FOUND"
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
// src/adapters/d1.ts
|
|
26
|
+
var D1Adapter = class {
|
|
27
|
+
type = "d1";
|
|
28
|
+
binding;
|
|
29
|
+
db;
|
|
30
|
+
constructor(config) {
|
|
31
|
+
this.binding = config.binding;
|
|
32
|
+
const drizzleConfig = {};
|
|
33
|
+
if (config.logging !== void 0) {
|
|
34
|
+
drizzleConfig.logger = config.logging;
|
|
35
|
+
}
|
|
36
|
+
this.db = drizzle(this.binding, drizzleConfig);
|
|
37
|
+
}
|
|
38
|
+
async execute(sql) {
|
|
39
|
+
try {
|
|
40
|
+
const result = await this.binding.exec(sql);
|
|
41
|
+
return result.results ?? [];
|
|
42
|
+
} catch (err) {
|
|
43
|
+
throw new DatabaseError(
|
|
44
|
+
`Query failed: ${err instanceof Error ? err.message : "Unknown error"}`,
|
|
45
|
+
DatabaseErrorCodes.QUERY_FAILED,
|
|
46
|
+
err
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
async ping() {
|
|
51
|
+
try {
|
|
52
|
+
await this.binding.prepare("SELECT 1").first();
|
|
53
|
+
return true;
|
|
54
|
+
} catch {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
async health() {
|
|
59
|
+
const start = Date.now();
|
|
60
|
+
try {
|
|
61
|
+
await this.binding.prepare("SELECT 1").first();
|
|
62
|
+
const latencyMs = Date.now() - start;
|
|
63
|
+
const versionResult = await this.binding.prepare("SELECT sqlite_version() as version").first();
|
|
64
|
+
return {
|
|
65
|
+
healthy: true,
|
|
66
|
+
latencyMs,
|
|
67
|
+
version: versionResult ? `SQLite ${versionResult.version}` : void 0
|
|
68
|
+
};
|
|
69
|
+
} catch (err) {
|
|
70
|
+
return {
|
|
71
|
+
healthy: false,
|
|
72
|
+
latencyMs: Date.now() - start,
|
|
73
|
+
error: err instanceof Error ? err.message : "Unknown error"
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
drizzle() {
|
|
78
|
+
return this.db;
|
|
79
|
+
}
|
|
80
|
+
async close() {
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Get the raw D1 binding
|
|
84
|
+
*/
|
|
85
|
+
getBinding() {
|
|
86
|
+
return this.binding;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Execute a batch of statements
|
|
90
|
+
*/
|
|
91
|
+
async batch(statements) {
|
|
92
|
+
try {
|
|
93
|
+
const prepared = statements.map((stmt) => {
|
|
94
|
+
const p = this.binding.prepare(stmt.sql);
|
|
95
|
+
return stmt.params ? p.bind(...stmt.params) : p;
|
|
96
|
+
});
|
|
97
|
+
const results = await this.binding.batch(prepared);
|
|
98
|
+
return results.map((r) => r.results ?? []);
|
|
99
|
+
} catch (err) {
|
|
100
|
+
throw new DatabaseError(
|
|
101
|
+
`Batch execution failed: ${err instanceof Error ? err.message : "Unknown error"}`,
|
|
102
|
+
DatabaseErrorCodes.QUERY_FAILED,
|
|
103
|
+
err
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
function createD1Adapter(config) {
|
|
109
|
+
return new D1Adapter(config);
|
|
110
|
+
}
|
|
111
|
+
export {
|
|
112
|
+
D1Adapter,
|
|
113
|
+
createD1Adapter
|
|
114
|
+
};
|
|
115
|
+
//# sourceMappingURL=d1.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/adapters/d1.ts","../../src/types.ts"],"sourcesContent":["/**\n * @parsrun/database - Cloudflare D1 Adapter\n * Cloudflare D1 (SQLite) adapter - native edge database\n */\n\nimport { drizzle } from \"drizzle-orm/d1\";\nimport type {\n D1Config,\n D1Database,\n DatabaseAdapter,\n DatabaseHealth,\n} from \"../types.js\";\nimport { DatabaseError, DatabaseErrorCodes } from \"../types.js\";\n\n/**\n * Cloudflare D1 Database Adapter\n * Native SQLite database for Cloudflare Workers\n *\n * @example\n * ```typescript\n * // In Cloudflare Worker\n * export default {\n * async fetch(request, env) {\n * const db = createD1Adapter({\n * type: 'd1',\n * binding: env.DB, // D1 binding from wrangler.toml\n * });\n *\n * const users = await db.drizzle().select().from(usersTable);\n * return new Response(JSON.stringify(users));\n * }\n * }\n * ```\n */\nexport class D1Adapter implements DatabaseAdapter {\n readonly type = \"d1\" as const;\n\n private binding: D1Database;\n private db: ReturnType<typeof drizzle>;\n\n constructor(config: D1Config) {\n this.binding = config.binding;\n\n const drizzleConfig: Parameters<typeof drizzle>[1] = {};\n if (config.logging !== undefined) {\n drizzleConfig.logger = config.logging;\n }\n\n this.db = drizzle(this.binding as Parameters<typeof drizzle>[0], drizzleConfig);\n }\n\n async execute<T = unknown>(sql: string): Promise<T[]> {\n try {\n const result = await this.binding.exec<T>(sql);\n return result.results ?? [];\n } catch (err) {\n throw new DatabaseError(\n `Query failed: ${err instanceof Error ? err.message : \"Unknown error\"}`,\n DatabaseErrorCodes.QUERY_FAILED,\n err\n );\n }\n }\n\n async ping(): Promise<boolean> {\n try {\n await this.binding.prepare(\"SELECT 1\").first();\n return true;\n } catch {\n return false;\n }\n }\n\n async health(): Promise<DatabaseHealth> {\n const start = Date.now();\n\n try {\n await this.binding.prepare(\"SELECT 1\").first();\n const latencyMs = Date.now() - start;\n\n // Get SQLite version\n const versionResult = await this.binding\n .prepare(\"SELECT sqlite_version() as version\")\n .first<{ version: string }>();\n\n return {\n healthy: true,\n latencyMs,\n version: versionResult ? `SQLite ${versionResult.version}` : undefined,\n };\n } catch (err) {\n return {\n healthy: false,\n latencyMs: Date.now() - start,\n error: err instanceof Error ? err.message : \"Unknown error\",\n };\n }\n }\n\n drizzle(): ReturnType<typeof drizzle> {\n return this.db;\n }\n\n async close(): Promise<void> {\n // D1 bindings are managed by Cloudflare, nothing to close\n }\n\n /**\n * Get the raw D1 binding\n */\n getBinding(): D1Database {\n return this.binding;\n }\n\n /**\n * Execute a batch of statements\n */\n async batch<T = unknown>(\n statements: Array<{ sql: string; params?: unknown[] }>\n ): Promise<T[][]> {\n try {\n const prepared = statements.map((stmt) => {\n const p = this.binding.prepare(stmt.sql);\n return stmt.params ? p.bind(...stmt.params) : p;\n });\n\n const results = await this.binding.batch<T>(prepared);\n return results.map((r) => r.results ?? []);\n } catch (err) {\n throw new DatabaseError(\n `Batch execution failed: ${err instanceof Error ? err.message : \"Unknown error\"}`,\n DatabaseErrorCodes.QUERY_FAILED,\n err\n );\n }\n }\n}\n\n/**\n * Create a D1 adapter\n */\nexport function createD1Adapter(config: D1Config): D1Adapter {\n return new D1Adapter(config);\n}\n","/**\n * @parsrun/database - Type Definitions\n * Database types and interfaces\n */\n\n/**\n * Database adapter type\n */\nexport type DatabaseAdapterType = \"postgres\" | \"neon\" | \"d1\" | \"custom\";\n\n/**\n * Base database configuration\n */\nexport interface BaseDatabaseConfig {\n /** Adapter type */\n type: DatabaseAdapterType;\n /** Enable query logging */\n logging?: boolean | undefined;\n /** Connection pool size */\n poolSize?: number | undefined;\n}\n\n/**\n * PostgreSQL configuration\n */\nexport interface PostgresConfig extends BaseDatabaseConfig {\n type: \"postgres\";\n /** Database host */\n host: string;\n /** Database port */\n port: number;\n /** Database user */\n user: string;\n /** Database password */\n password: string;\n /** Database name */\n database: string;\n /** SSL configuration */\n ssl?: boolean | { rejectUnauthorized: boolean } | undefined;\n}\n\n/**\n * Neon serverless configuration\n */\nexport interface NeonConfig extends BaseDatabaseConfig {\n type: \"neon\";\n /** Connection string */\n connectionString: string;\n /** Use pooled connection */\n pooled?: boolean | undefined;\n}\n\n/**\n * Cloudflare D1 configuration\n */\nexport interface D1Config extends BaseDatabaseConfig {\n type: \"d1\";\n /** D1 binding */\n binding: D1Database;\n}\n\n/**\n * Cloudflare D1 Database binding type\n */\nexport interface D1Database {\n prepare(query: string): D1PreparedStatement;\n batch<T>(statements: D1PreparedStatement[]): Promise<D1Result<T>[]>;\n dump(): Promise<ArrayBuffer>;\n exec<T>(query: string): Promise<D1Result<T>>;\n}\n\ninterface D1PreparedStatement {\n bind(...values: unknown[]): D1PreparedStatement;\n first<T = unknown>(column?: string): Promise<T | null>;\n run<T = unknown>(): Promise<D1Result<T>>;\n all<T = unknown>(): Promise<D1Result<T>>;\n raw<T = unknown>(): Promise<T[]>;\n}\n\ninterface D1Result<T> {\n results?: T[];\n success: boolean;\n error?: string;\n meta?: D1Meta;\n}\n\ninterface D1Meta {\n duration: number;\n rows_read: number;\n rows_written: number;\n}\n\n/**\n * Combined database configuration\n */\nexport type DatabaseConfig = PostgresConfig | NeonConfig | D1Config;\n\n/**\n * Migration status\n */\nexport interface MigrationStatus {\n /** Whether migrations need to be run */\n needsMigration: boolean;\n /** Whether database is up to date */\n upToDate: boolean;\n /** Number of pending migrations */\n pendingCount: number;\n /** Number of applied migrations */\n appliedCount: number;\n /** Error message if check failed */\n error?: string | undefined;\n}\n\n/**\n * Migration result\n */\nexport interface MigrationResult {\n /** Whether migration succeeded */\n success: boolean;\n /** Number of migrations applied */\n appliedCount?: number | undefined;\n /** Error message if migration failed */\n error?: string | undefined;\n}\n\n/**\n * Transaction options\n */\nexport interface TransactionOptions {\n /** Isolation level */\n isolationLevel?: \"read uncommitted\" | \"read committed\" | \"repeatable read\" | \"serializable\" | undefined;\n /** Access mode */\n accessMode?: \"read only\" | \"read write\" | undefined;\n /** Deferrable (PostgreSQL) */\n deferrable?: boolean | undefined;\n}\n\n/**\n * Query options\n */\nexport interface QueryOptions {\n /** Query timeout in milliseconds */\n timeout?: number | undefined;\n /** Transform result rows */\n transform?: \"camelCase\" | \"snakeCase\" | undefined;\n}\n\n/**\n * Database health status\n */\nexport interface DatabaseHealth {\n /** Whether database is healthy */\n healthy: boolean;\n /** Connection latency in milliseconds */\n latencyMs: number;\n /** Database version */\n version?: string | undefined;\n /** Error message if unhealthy */\n error?: string | undefined;\n}\n\n/**\n * Database adapter interface\n */\nexport interface DatabaseAdapter {\n /** Adapter type */\n readonly type: DatabaseAdapterType;\n\n /**\n * Execute raw SQL query\n */\n execute<T = unknown>(sql: string): Promise<T[]>;\n\n /**\n * Check connection health\n */\n ping(): Promise<boolean>;\n\n /**\n * Get connection health with details\n */\n health(): Promise<DatabaseHealth>;\n\n /**\n * Get the underlying Drizzle instance\n */\n drizzle(): unknown;\n\n /**\n * Close database connection\n */\n close(): Promise<void>;\n}\n\n/**\n * Database error\n */\nexport class DatabaseError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly cause?: unknown\n ) {\n super(message);\n this.name = \"DatabaseError\";\n }\n}\n\n/**\n * Common database error codes\n */\nexport const DatabaseErrorCodes = {\n CONNECTION_FAILED: \"CONNECTION_FAILED\",\n QUERY_FAILED: \"QUERY_FAILED\",\n TRANSACTION_FAILED: \"TRANSACTION_FAILED\",\n MIGRATION_FAILED: \"MIGRATION_FAILED\",\n INVALID_CONFIG: \"INVALID_CONFIG\",\n ADAPTER_NOT_AVAILABLE: \"ADAPTER_NOT_AVAILABLE\",\n TIMEOUT: \"TIMEOUT\",\n CONSTRAINT_VIOLATION: \"CONSTRAINT_VIOLATION\",\n NOT_FOUND: \"NOT_FOUND\",\n} as const;\n"],"mappings":";AAKA,SAAS,eAAe;;;ACgMjB,IAAM,gBAAN,cAA4B,MAAM;AAAA,EACvC,YACE,SACgB,MACA,OAChB;AACA,UAAM,OAAO;AAHG;AACA;AAGhB,SAAK,OAAO;AAAA,EACd;AACF;AAKO,IAAM,qBAAqB;AAAA,EAChC,mBAAmB;AAAA,EACnB,cAAc;AAAA,EACd,oBAAoB;AAAA,EACpB,kBAAkB;AAAA,EAClB,gBAAgB;AAAA,EAChB,uBAAuB;AAAA,EACvB,SAAS;AAAA,EACT,sBAAsB;AAAA,EACtB,WAAW;AACb;;;AD3LO,IAAM,YAAN,MAA2C;AAAA,EACvC,OAAO;AAAA,EAER;AAAA,EACA;AAAA,EAER,YAAY,QAAkB;AAC5B,SAAK,UAAU,OAAO;AAEtB,UAAM,gBAA+C,CAAC;AACtD,QAAI,OAAO,YAAY,QAAW;AAChC,oBAAc,SAAS,OAAO;AAAA,IAChC;AAEA,SAAK,KAAK,QAAQ,KAAK,SAA0C,aAAa;AAAA,EAChF;AAAA,EAEA,MAAM,QAAqB,KAA2B;AACpD,QAAI;AACF,YAAM,SAAS,MAAM,KAAK,QAAQ,KAAQ,GAAG;AAC7C,aAAO,OAAO,WAAW,CAAC;AAAA,IAC5B,SAAS,KAAK;AACZ,YAAM,IAAI;AAAA,QACR,iBAAiB,eAAe,QAAQ,IAAI,UAAU,eAAe;AAAA,QACrE,mBAAmB;AAAA,QACnB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,OAAyB;AAC7B,QAAI;AACF,YAAM,KAAK,QAAQ,QAAQ,UAAU,EAAE,MAAM;AAC7C,aAAO;AAAA,IACT,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,SAAkC;AACtC,UAAM,QAAQ,KAAK,IAAI;AAEvB,QAAI;AACF,YAAM,KAAK,QAAQ,QAAQ,UAAU,EAAE,MAAM;AAC7C,YAAM,YAAY,KAAK,IAAI,IAAI;AAG/B,YAAM,gBAAgB,MAAM,KAAK,QAC9B,QAAQ,oCAAoC,EAC5C,MAA2B;AAE9B,aAAO;AAAA,QACL,SAAS;AAAA,QACT;AAAA,QACA,SAAS,gBAAgB,UAAU,cAAc,OAAO,KAAK;AAAA,MAC/D;AAAA,IACF,SAAS,KAAK;AACZ,aAAO;AAAA,QACL,SAAS;AAAA,QACT,WAAW,KAAK,IAAI,IAAI;AAAA,QACxB,OAAO,eAAe,QAAQ,IAAI,UAAU;AAAA,MAC9C;AAAA,IACF;AAAA,EACF;AAAA,EAEA,UAAsC;AACpC,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,QAAuB;AAAA,EAE7B;AAAA;AAAA;AAAA;AAAA,EAKA,aAAyB;AACvB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MACJ,YACgB;AAChB,QAAI;AACF,YAAM,WAAW,WAAW,IAAI,CAAC,SAAS;AACxC,cAAM,IAAI,KAAK,QAAQ,QAAQ,KAAK,GAAG;AACvC,eAAO,KAAK,SAAS,EAAE,KAAK,GAAG,KAAK,MAAM,IAAI;AAAA,MAChD,CAAC;AAED,YAAM,UAAU,MAAM,KAAK,QAAQ,MAAS,QAAQ;AACpD,aAAO,QAAQ,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AAAA,IAC3C,SAAS,KAAK;AACZ,YAAM,IAAI;AAAA,QACR,2BAA2B,eAAe,QAAQ,IAAI,UAAU,eAAe;AAAA,QAC/E,mBAAmB;AAAA,QACnB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAKO,SAAS,gBAAgB,QAA6B;AAC3D,SAAO,IAAI,UAAU,MAAM;AAC7B;","names":[]}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import * as _neondatabase_serverless from '@neondatabase/serverless';
|
|
2
|
+
import { a as DatabaseAdapter, N as NeonConfig, f as DatabaseHealth } from '../types-DgBIyTeZ.js';
|
|
3
|
+
|
|
4
|
+
type NeonClient = ReturnType<typeof _neondatabase_serverless.neon>;
|
|
5
|
+
/**
|
|
6
|
+
* Neon Serverless Database Adapter
|
|
7
|
+
* Optimized for edge environments (Cloudflare Workers, Vercel Edge, etc.)
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* const db = await createNeonAdapter({
|
|
12
|
+
* type: 'neon',
|
|
13
|
+
* connectionString: process.env.DATABASE_URL,
|
|
14
|
+
* });
|
|
15
|
+
*
|
|
16
|
+
* // Execute queries
|
|
17
|
+
* const users = await db.drizzle().select().from(usersTable);
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
declare class NeonAdapter implements DatabaseAdapter {
|
|
21
|
+
readonly type: "neon";
|
|
22
|
+
private client;
|
|
23
|
+
private db;
|
|
24
|
+
private config;
|
|
25
|
+
constructor(config: NeonConfig);
|
|
26
|
+
/**
|
|
27
|
+
* Initialize the connection
|
|
28
|
+
*/
|
|
29
|
+
connect(): Promise<void>;
|
|
30
|
+
execute<T = unknown>(sql: string): Promise<T[]>;
|
|
31
|
+
ping(): Promise<boolean>;
|
|
32
|
+
health(): Promise<DatabaseHealth>;
|
|
33
|
+
drizzle(): any;
|
|
34
|
+
close(): Promise<void>;
|
|
35
|
+
/**
|
|
36
|
+
* Get the raw Neon client
|
|
37
|
+
*/
|
|
38
|
+
getClient(): NeonClient | null;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Create a Neon adapter
|
|
42
|
+
*/
|
|
43
|
+
declare function createNeonAdapter(config: NeonConfig): Promise<NeonAdapter>;
|
|
44
|
+
/**
|
|
45
|
+
* Create a Neon adapter from connection string
|
|
46
|
+
*/
|
|
47
|
+
declare function createNeonFromUrl(connectionString: string, options?: Omit<NeonConfig, "type" | "connectionString">): Promise<NeonAdapter>;
|
|
48
|
+
|
|
49
|
+
export { NeonAdapter, createNeonAdapter, createNeonFromUrl };
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
// src/adapters/neon.ts
|
|
2
|
+
import { drizzle } from "drizzle-orm/neon-http";
|
|
3
|
+
|
|
4
|
+
// src/types.ts
|
|
5
|
+
var DatabaseError = class extends Error {
|
|
6
|
+
constructor(message, code, cause) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.code = code;
|
|
9
|
+
this.cause = cause;
|
|
10
|
+
this.name = "DatabaseError";
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
var DatabaseErrorCodes = {
|
|
14
|
+
CONNECTION_FAILED: "CONNECTION_FAILED",
|
|
15
|
+
QUERY_FAILED: "QUERY_FAILED",
|
|
16
|
+
TRANSACTION_FAILED: "TRANSACTION_FAILED",
|
|
17
|
+
MIGRATION_FAILED: "MIGRATION_FAILED",
|
|
18
|
+
INVALID_CONFIG: "INVALID_CONFIG",
|
|
19
|
+
ADAPTER_NOT_AVAILABLE: "ADAPTER_NOT_AVAILABLE",
|
|
20
|
+
TIMEOUT: "TIMEOUT",
|
|
21
|
+
CONSTRAINT_VIOLATION: "CONSTRAINT_VIOLATION",
|
|
22
|
+
NOT_FOUND: "NOT_FOUND"
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
// src/adapters/neon.ts
|
|
26
|
+
var NeonAdapter = class {
|
|
27
|
+
type = "neon";
|
|
28
|
+
client = null;
|
|
29
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
30
|
+
db = null;
|
|
31
|
+
config;
|
|
32
|
+
constructor(config) {
|
|
33
|
+
this.config = config;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Initialize the connection
|
|
37
|
+
*/
|
|
38
|
+
async connect() {
|
|
39
|
+
if (this.client) return;
|
|
40
|
+
try {
|
|
41
|
+
const { neon } = await import("@neondatabase/serverless");
|
|
42
|
+
this.client = neon(this.config.connectionString, {
|
|
43
|
+
fetchOptions: {
|
|
44
|
+
cache: "no-store"
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
const drizzleOpts = {};
|
|
48
|
+
if (this.config.logging !== void 0) {
|
|
49
|
+
drizzleOpts.logger = this.config.logging;
|
|
50
|
+
}
|
|
51
|
+
this.db = drizzle(this.client, drizzleOpts);
|
|
52
|
+
} catch (err) {
|
|
53
|
+
throw new DatabaseError(
|
|
54
|
+
`Failed to connect to Neon: ${err instanceof Error ? err.message : "Unknown error"}`,
|
|
55
|
+
DatabaseErrorCodes.CONNECTION_FAILED,
|
|
56
|
+
err
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
async execute(sql) {
|
|
61
|
+
if (!this.client) {
|
|
62
|
+
await this.connect();
|
|
63
|
+
}
|
|
64
|
+
try {
|
|
65
|
+
const result = await this.client(sql);
|
|
66
|
+
if (Array.isArray(result) && result.rows) {
|
|
67
|
+
return result.rows;
|
|
68
|
+
}
|
|
69
|
+
return result;
|
|
70
|
+
} catch (err) {
|
|
71
|
+
throw new DatabaseError(
|
|
72
|
+
`Query failed: ${err instanceof Error ? err.message : "Unknown error"}`,
|
|
73
|
+
DatabaseErrorCodes.QUERY_FAILED,
|
|
74
|
+
err
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
async ping() {
|
|
79
|
+
try {
|
|
80
|
+
await this.execute("SELECT 1");
|
|
81
|
+
return true;
|
|
82
|
+
} catch {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
async health() {
|
|
87
|
+
const start = Date.now();
|
|
88
|
+
try {
|
|
89
|
+
if (!this.client) {
|
|
90
|
+
await this.connect();
|
|
91
|
+
}
|
|
92
|
+
const result = await this.execute("SELECT version()");
|
|
93
|
+
const latencyMs = Date.now() - start;
|
|
94
|
+
return {
|
|
95
|
+
healthy: true,
|
|
96
|
+
latencyMs,
|
|
97
|
+
version: result[0]?.version
|
|
98
|
+
};
|
|
99
|
+
} catch (err) {
|
|
100
|
+
return {
|
|
101
|
+
healthy: false,
|
|
102
|
+
latencyMs: Date.now() - start,
|
|
103
|
+
error: err instanceof Error ? err.message : "Unknown error"
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
108
|
+
drizzle() {
|
|
109
|
+
if (!this.db) {
|
|
110
|
+
throw new DatabaseError(
|
|
111
|
+
"Database not connected. Call connect() first.",
|
|
112
|
+
DatabaseErrorCodes.CONNECTION_FAILED
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
return this.db;
|
|
116
|
+
}
|
|
117
|
+
async close() {
|
|
118
|
+
this.client = null;
|
|
119
|
+
this.db = null;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Get the raw Neon client
|
|
123
|
+
*/
|
|
124
|
+
getClient() {
|
|
125
|
+
return this.client;
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
async function createNeonAdapter(config) {
|
|
129
|
+
const adapter = new NeonAdapter(config);
|
|
130
|
+
await adapter.connect();
|
|
131
|
+
return adapter;
|
|
132
|
+
}
|
|
133
|
+
async function createNeonFromUrl(connectionString, options) {
|
|
134
|
+
return createNeonAdapter({
|
|
135
|
+
type: "neon",
|
|
136
|
+
connectionString,
|
|
137
|
+
...options
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
export {
|
|
141
|
+
NeonAdapter,
|
|
142
|
+
createNeonAdapter,
|
|
143
|
+
createNeonFromUrl
|
|
144
|
+
};
|
|
145
|
+
//# sourceMappingURL=neon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/adapters/neon.ts","../../src/types.ts"],"sourcesContent":["/**\n * @parsrun/database - Neon Serverless Adapter\n * Neon serverless PostgreSQL adapter - perfect for edge environments\n */\n\nimport { drizzle } from \"drizzle-orm/neon-http\";\nimport type {\n DatabaseAdapter,\n DatabaseHealth,\n NeonConfig,\n} from \"../types.js\";\nimport { DatabaseError, DatabaseErrorCodes } from \"../types.js\";\n\n// Type for Neon client\ntype NeonClient = ReturnType<typeof import(\"@neondatabase/serverless\").neon>;\n\n/**\n * Neon Serverless Database Adapter\n * Optimized for edge environments (Cloudflare Workers, Vercel Edge, etc.)\n *\n * @example\n * ```typescript\n * const db = await createNeonAdapter({\n * type: 'neon',\n * connectionString: process.env.DATABASE_URL,\n * });\n *\n * // Execute queries\n * const users = await db.drizzle().select().from(usersTable);\n * ```\n */\nexport class NeonAdapter implements DatabaseAdapter {\n readonly type = \"neon\" as const;\n\n private client: NeonClient | null = null;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private db: any = null;\n private config: NeonConfig;\n\n constructor(config: NeonConfig) {\n this.config = config;\n }\n\n /**\n * Initialize the connection\n */\n async connect(): Promise<void> {\n if (this.client) return;\n\n try {\n const { neon } = await import(\"@neondatabase/serverless\");\n\n this.client = neon(this.config.connectionString, {\n fetchOptions: {\n cache: \"no-store\",\n },\n });\n\n // Build drizzle config - use any to avoid complex type issues\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const drizzleOpts: any = {};\n if (this.config.logging !== undefined) {\n drizzleOpts.logger = this.config.logging;\n }\n\n this.db = drizzle(this.client, drizzleOpts);\n } catch (err) {\n throw new DatabaseError(\n `Failed to connect to Neon: ${err instanceof Error ? err.message : \"Unknown error\"}`,\n DatabaseErrorCodes.CONNECTION_FAILED,\n err\n );\n }\n }\n\n async execute<T = unknown>(sql: string): Promise<T[]> {\n if (!this.client) {\n await this.connect();\n }\n\n try {\n const result = await this.client!(sql);\n // Neon can return different formats depending on how it's called\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if (Array.isArray(result) && (result as any).rows) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (result as any).rows as T[];\n }\n return result as T[];\n } catch (err) {\n throw new DatabaseError(\n `Query failed: ${err instanceof Error ? err.message : \"Unknown error\"}`,\n DatabaseErrorCodes.QUERY_FAILED,\n err\n );\n }\n }\n\n async ping(): Promise<boolean> {\n try {\n await this.execute(\"SELECT 1\");\n return true;\n } catch {\n return false;\n }\n }\n\n async health(): Promise<DatabaseHealth> {\n const start = Date.now();\n\n try {\n if (!this.client) {\n await this.connect();\n }\n\n const result = await this.execute<{ version: string }>(\"SELECT version()\");\n const latencyMs = Date.now() - start;\n\n return {\n healthy: true,\n latencyMs,\n version: result[0]?.version,\n };\n } catch (err) {\n return {\n healthy: false,\n latencyMs: Date.now() - start,\n error: err instanceof Error ? err.message : \"Unknown error\",\n };\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n drizzle(): any {\n if (!this.db) {\n throw new DatabaseError(\n \"Database not connected. Call connect() first.\",\n DatabaseErrorCodes.CONNECTION_FAILED\n );\n }\n return this.db;\n }\n\n async close(): Promise<void> {\n // Neon serverless connections are stateless, nothing to close\n this.client = null;\n this.db = null;\n }\n\n /**\n * Get the raw Neon client\n */\n getClient(): NeonClient | null {\n return this.client;\n }\n}\n\n/**\n * Create a Neon adapter\n */\nexport async function createNeonAdapter(\n config: NeonConfig\n): Promise<NeonAdapter> {\n const adapter = new NeonAdapter(config);\n await adapter.connect();\n return adapter;\n}\n\n/**\n * Create a Neon adapter from connection string\n */\nexport async function createNeonFromUrl(\n connectionString: string,\n options?: Omit<NeonConfig, \"type\" | \"connectionString\">\n): Promise<NeonAdapter> {\n return createNeonAdapter({\n type: \"neon\",\n connectionString,\n ...options,\n });\n}\n","/**\n * @parsrun/database - Type Definitions\n * Database types and interfaces\n */\n\n/**\n * Database adapter type\n */\nexport type DatabaseAdapterType = \"postgres\" | \"neon\" | \"d1\" | \"custom\";\n\n/**\n * Base database configuration\n */\nexport interface BaseDatabaseConfig {\n /** Adapter type */\n type: DatabaseAdapterType;\n /** Enable query logging */\n logging?: boolean | undefined;\n /** Connection pool size */\n poolSize?: number | undefined;\n}\n\n/**\n * PostgreSQL configuration\n */\nexport interface PostgresConfig extends BaseDatabaseConfig {\n type: \"postgres\";\n /** Database host */\n host: string;\n /** Database port */\n port: number;\n /** Database user */\n user: string;\n /** Database password */\n password: string;\n /** Database name */\n database: string;\n /** SSL configuration */\n ssl?: boolean | { rejectUnauthorized: boolean } | undefined;\n}\n\n/**\n * Neon serverless configuration\n */\nexport interface NeonConfig extends BaseDatabaseConfig {\n type: \"neon\";\n /** Connection string */\n connectionString: string;\n /** Use pooled connection */\n pooled?: boolean | undefined;\n}\n\n/**\n * Cloudflare D1 configuration\n */\nexport interface D1Config extends BaseDatabaseConfig {\n type: \"d1\";\n /** D1 binding */\n binding: D1Database;\n}\n\n/**\n * Cloudflare D1 Database binding type\n */\nexport interface D1Database {\n prepare(query: string): D1PreparedStatement;\n batch<T>(statements: D1PreparedStatement[]): Promise<D1Result<T>[]>;\n dump(): Promise<ArrayBuffer>;\n exec<T>(query: string): Promise<D1Result<T>>;\n}\n\ninterface D1PreparedStatement {\n bind(...values: unknown[]): D1PreparedStatement;\n first<T = unknown>(column?: string): Promise<T | null>;\n run<T = unknown>(): Promise<D1Result<T>>;\n all<T = unknown>(): Promise<D1Result<T>>;\n raw<T = unknown>(): Promise<T[]>;\n}\n\ninterface D1Result<T> {\n results?: T[];\n success: boolean;\n error?: string;\n meta?: D1Meta;\n}\n\ninterface D1Meta {\n duration: number;\n rows_read: number;\n rows_written: number;\n}\n\n/**\n * Combined database configuration\n */\nexport type DatabaseConfig = PostgresConfig | NeonConfig | D1Config;\n\n/**\n * Migration status\n */\nexport interface MigrationStatus {\n /** Whether migrations need to be run */\n needsMigration: boolean;\n /** Whether database is up to date */\n upToDate: boolean;\n /** Number of pending migrations */\n pendingCount: number;\n /** Number of applied migrations */\n appliedCount: number;\n /** Error message if check failed */\n error?: string | undefined;\n}\n\n/**\n * Migration result\n */\nexport interface MigrationResult {\n /** Whether migration succeeded */\n success: boolean;\n /** Number of migrations applied */\n appliedCount?: number | undefined;\n /** Error message if migration failed */\n error?: string | undefined;\n}\n\n/**\n * Transaction options\n */\nexport interface TransactionOptions {\n /** Isolation level */\n isolationLevel?: \"read uncommitted\" | \"read committed\" | \"repeatable read\" | \"serializable\" | undefined;\n /** Access mode */\n accessMode?: \"read only\" | \"read write\" | undefined;\n /** Deferrable (PostgreSQL) */\n deferrable?: boolean | undefined;\n}\n\n/**\n * Query options\n */\nexport interface QueryOptions {\n /** Query timeout in milliseconds */\n timeout?: number | undefined;\n /** Transform result rows */\n transform?: \"camelCase\" | \"snakeCase\" | undefined;\n}\n\n/**\n * Database health status\n */\nexport interface DatabaseHealth {\n /** Whether database is healthy */\n healthy: boolean;\n /** Connection latency in milliseconds */\n latencyMs: number;\n /** Database version */\n version?: string | undefined;\n /** Error message if unhealthy */\n error?: string | undefined;\n}\n\n/**\n * Database adapter interface\n */\nexport interface DatabaseAdapter {\n /** Adapter type */\n readonly type: DatabaseAdapterType;\n\n /**\n * Execute raw SQL query\n */\n execute<T = unknown>(sql: string): Promise<T[]>;\n\n /**\n * Check connection health\n */\n ping(): Promise<boolean>;\n\n /**\n * Get connection health with details\n */\n health(): Promise<DatabaseHealth>;\n\n /**\n * Get the underlying Drizzle instance\n */\n drizzle(): unknown;\n\n /**\n * Close database connection\n */\n close(): Promise<void>;\n}\n\n/**\n * Database error\n */\nexport class DatabaseError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly cause?: unknown\n ) {\n super(message);\n this.name = \"DatabaseError\";\n }\n}\n\n/**\n * Common database error codes\n */\nexport const DatabaseErrorCodes = {\n CONNECTION_FAILED: \"CONNECTION_FAILED\",\n QUERY_FAILED: \"QUERY_FAILED\",\n TRANSACTION_FAILED: \"TRANSACTION_FAILED\",\n MIGRATION_FAILED: \"MIGRATION_FAILED\",\n INVALID_CONFIG: \"INVALID_CONFIG\",\n ADAPTER_NOT_AVAILABLE: \"ADAPTER_NOT_AVAILABLE\",\n TIMEOUT: \"TIMEOUT\",\n CONSTRAINT_VIOLATION: \"CONSTRAINT_VIOLATION\",\n NOT_FOUND: \"NOT_FOUND\",\n} as const;\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { PostgresJsDatabase } from 'drizzle-orm/postgres-js';
|
|
2
|
+
import { a as DatabaseAdapter, P as PostgresConfig, f as DatabaseHealth } from '../types-DgBIyTeZ.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @parsrun/database - PostgreSQL Adapter
|
|
6
|
+
* PostgreSQL adapter using postgres.js
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* PostgreSQL Database Adapter
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* const db = await createPostgresAdapter({
|
|
15
|
+
* type: 'postgres',
|
|
16
|
+
* host: 'localhost',
|
|
17
|
+
* port: 5432,
|
|
18
|
+
* user: 'postgres',
|
|
19
|
+
* password: 'password',
|
|
20
|
+
* database: 'mydb',
|
|
21
|
+
* });
|
|
22
|
+
*
|
|
23
|
+
* // Execute queries
|
|
24
|
+
* const users = await db.drizzle().select().from(usersTable);
|
|
25
|
+
*
|
|
26
|
+
* // Close when done
|
|
27
|
+
* await db.close();
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
declare class PostgresAdapter implements DatabaseAdapter {
|
|
31
|
+
readonly type: "postgres";
|
|
32
|
+
private client;
|
|
33
|
+
private db;
|
|
34
|
+
private config;
|
|
35
|
+
constructor(config: PostgresConfig);
|
|
36
|
+
/**
|
|
37
|
+
* Initialize the connection
|
|
38
|
+
*/
|
|
39
|
+
connect(): Promise<void>;
|
|
40
|
+
execute<T = unknown>(sql: string): Promise<T[]>;
|
|
41
|
+
ping(): Promise<boolean>;
|
|
42
|
+
health(): Promise<DatabaseHealth>;
|
|
43
|
+
drizzle(): PostgresJsDatabase<any>;
|
|
44
|
+
close(): Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* Get the raw postgres client
|
|
47
|
+
*/
|
|
48
|
+
getClient(): unknown;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Create a PostgreSQL adapter
|
|
52
|
+
*/
|
|
53
|
+
declare function createPostgresAdapter(config: PostgresConfig): Promise<PostgresAdapter>;
|
|
54
|
+
/**
|
|
55
|
+
* Create a PostgreSQL adapter from connection string
|
|
56
|
+
*/
|
|
57
|
+
declare function createPostgresFromUrl(connectionString: string, options?: Omit<PostgresConfig, "type" | "host" | "port" | "user" | "password" | "database">): Promise<PostgresAdapter>;
|
|
58
|
+
|
|
59
|
+
export { PostgresAdapter, createPostgresAdapter, createPostgresFromUrl };
|