@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.
@@ -0,0 +1,165 @@
1
+ // src/adapters/postgres.ts
2
+ import { drizzle } from "drizzle-orm/postgres-js";
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/postgres.ts
26
+ var PostgresAdapter = class {
27
+ type = "postgres";
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 postgresModule = await import("postgres");
42
+ const postgres = postgresModule.default;
43
+ let sslConfig = false;
44
+ if (this.config.ssl === true) {
45
+ sslConfig = "require";
46
+ } else if (typeof this.config.ssl === "object") {
47
+ sslConfig = this.config.ssl;
48
+ }
49
+ this.client = postgres({
50
+ host: this.config.host,
51
+ port: this.config.port,
52
+ user: this.config.user,
53
+ password: this.config.password,
54
+ database: this.config.database,
55
+ ssl: sslConfig,
56
+ max: this.config.poolSize ?? 10
57
+ });
58
+ const drizzleOpts = {};
59
+ if (this.config.logging !== void 0) {
60
+ drizzleOpts.logger = this.config.logging;
61
+ }
62
+ this.db = drizzle(this.client, drizzleOpts);
63
+ } catch (err) {
64
+ throw new DatabaseError(
65
+ `Failed to connect to PostgreSQL: ${err instanceof Error ? err.message : "Unknown error"}`,
66
+ DatabaseErrorCodes.CONNECTION_FAILED,
67
+ err
68
+ );
69
+ }
70
+ }
71
+ async execute(sql) {
72
+ if (!this.client) {
73
+ await this.connect();
74
+ }
75
+ try {
76
+ const client = this.client;
77
+ const result = await client.unsafe(sql);
78
+ return result;
79
+ } catch (err) {
80
+ throw new DatabaseError(
81
+ `Query failed: ${err instanceof Error ? err.message : "Unknown error"}`,
82
+ DatabaseErrorCodes.QUERY_FAILED,
83
+ err
84
+ );
85
+ }
86
+ }
87
+ async ping() {
88
+ try {
89
+ await this.execute("SELECT 1");
90
+ return true;
91
+ } catch {
92
+ return false;
93
+ }
94
+ }
95
+ async health() {
96
+ const start = Date.now();
97
+ try {
98
+ if (!this.client) {
99
+ await this.connect();
100
+ }
101
+ const result = await this.execute("SELECT version()");
102
+ const latencyMs = Date.now() - start;
103
+ return {
104
+ healthy: true,
105
+ latencyMs,
106
+ version: result[0]?.version
107
+ };
108
+ } catch (err) {
109
+ return {
110
+ healthy: false,
111
+ latencyMs: Date.now() - start,
112
+ error: err instanceof Error ? err.message : "Unknown error"
113
+ };
114
+ }
115
+ }
116
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
117
+ drizzle() {
118
+ if (!this.db) {
119
+ throw new DatabaseError(
120
+ "Database not connected. Call connect() first.",
121
+ DatabaseErrorCodes.CONNECTION_FAILED
122
+ );
123
+ }
124
+ return this.db;
125
+ }
126
+ async close() {
127
+ if (this.client) {
128
+ const client = this.client;
129
+ await client.end();
130
+ this.client = null;
131
+ this.db = null;
132
+ }
133
+ }
134
+ /**
135
+ * Get the raw postgres client
136
+ */
137
+ getClient() {
138
+ return this.client;
139
+ }
140
+ };
141
+ async function createPostgresAdapter(config) {
142
+ const adapter = new PostgresAdapter(config);
143
+ await adapter.connect();
144
+ return adapter;
145
+ }
146
+ async function createPostgresFromUrl(connectionString, options) {
147
+ const url = new URL(connectionString);
148
+ const config = {
149
+ type: "postgres",
150
+ host: url.hostname,
151
+ port: parseInt(url.port || "5432", 10),
152
+ user: url.username,
153
+ password: url.password,
154
+ database: url.pathname.slice(1),
155
+ ssl: url.searchParams.get("sslmode") === "require",
156
+ ...options
157
+ };
158
+ return createPostgresAdapter(config);
159
+ }
160
+ export {
161
+ PostgresAdapter,
162
+ createPostgresAdapter,
163
+ createPostgresFromUrl
164
+ };
165
+ //# sourceMappingURL=postgres.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/adapters/postgres.ts","../../src/types.ts"],"sourcesContent":["/**\n * @parsrun/database - PostgreSQL Adapter\n * PostgreSQL adapter using postgres.js\n */\n\nimport { drizzle, type PostgresJsDatabase } from \"drizzle-orm/postgres-js\";\nimport type {\n DatabaseAdapter,\n DatabaseHealth,\n PostgresConfig,\n} from \"../types.js\";\nimport { DatabaseError, DatabaseErrorCodes } from \"../types.js\";\n\n/**\n * PostgreSQL Database Adapter\n *\n * @example\n * ```typescript\n * const db = await createPostgresAdapter({\n * type: 'postgres',\n * host: 'localhost',\n * port: 5432,\n * user: 'postgres',\n * password: 'password',\n * database: 'mydb',\n * });\n *\n * // Execute queries\n * const users = await db.drizzle().select().from(usersTable);\n *\n * // Close when done\n * await db.close();\n * ```\n */\nexport class PostgresAdapter implements DatabaseAdapter {\n readonly type = \"postgres\" as const;\n\n private client: unknown = null;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private db: PostgresJsDatabase<any> | null = null;\n private config: PostgresConfig;\n\n constructor(config: PostgresConfig) {\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 postgresModule = await import(\"postgres\");\n const postgres = postgresModule.default;\n\n // Build SSL config\n type SSLMode = boolean | \"require\" | \"allow\" | \"prefer\" | \"verify-full\" | { rejectUnauthorized: boolean };\n let sslConfig: SSLMode = false;\n\n if (this.config.ssl === true) {\n sslConfig = \"require\";\n } else if (typeof this.config.ssl === \"object\") {\n sslConfig = this.config.ssl;\n }\n\n this.client = postgres({\n host: this.config.host,\n port: this.config.port,\n user: this.config.user,\n password: this.config.password,\n database: this.config.database,\n ssl: sslConfig,\n max: this.config.poolSize ?? 10,\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 // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this.db = drizzle(this.client as any, drizzleOpts);\n } catch (err) {\n throw new DatabaseError(\n `Failed to connect to PostgreSQL: ${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 client = this.client as { unsafe: (sql: string) => Promise<unknown[]> };\n const result = await client.unsafe(sql);\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(): PostgresJsDatabase<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 if (this.client) {\n const client = this.client as { end: () => Promise<void> };\n await client.end();\n this.client = null;\n this.db = null;\n }\n }\n\n /**\n * Get the raw postgres client\n */\n getClient(): unknown {\n return this.client;\n }\n}\n\n/**\n * Create a PostgreSQL adapter\n */\nexport async function createPostgresAdapter(\n config: PostgresConfig\n): Promise<PostgresAdapter> {\n const adapter = new PostgresAdapter(config);\n await adapter.connect();\n return adapter;\n}\n\n/**\n * Create a PostgreSQL adapter from connection string\n */\nexport async function createPostgresFromUrl(\n connectionString: string,\n options?: Omit<PostgresConfig, \"type\" | \"host\" | \"port\" | \"user\" | \"password\" | \"database\">\n): Promise<PostgresAdapter> {\n const url = new URL(connectionString);\n\n const config: PostgresConfig = {\n type: \"postgres\",\n host: url.hostname,\n port: parseInt(url.port || \"5432\", 10),\n user: url.username,\n password: url.password,\n database: url.pathname.slice(1),\n ssl: url.searchParams.get(\"sslmode\") === \"require\",\n ...options,\n };\n\n return createPostgresAdapter(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":"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","names":[]}
@@ -0,0 +1,177 @@
1
+ import { D as DatabaseConfig, a as DatabaseAdapter } from './types-DgBIyTeZ.js';
2
+ export { B as BaseDatabaseConfig, c as D1Config, d as D1Database, b as DatabaseAdapterType, g as DatabaseError, h as DatabaseErrorCodes, f as DatabaseHealth, e as MigrationResult, M as MigrationStatus, N as NeonConfig, P as PostgresConfig, Q as QueryOptions, T as TransactionOptions } from './types-DgBIyTeZ.js';
3
+ export { PostgresAdapter, createPostgresAdapter, createPostgresFromUrl } from './adapters/postgres.js';
4
+ export { NeonAdapter, createNeonAdapter, createNeonFromUrl } from './adapters/neon.js';
5
+ export { D1Adapter, createD1Adapter } from './adapters/d1.js';
6
+ export * from 'drizzle-orm';
7
+ import 'drizzle-orm/postgres-js';
8
+ import '@neondatabase/serverless';
9
+ import 'drizzle-orm/d1';
10
+
11
+ /**
12
+ * @parsrun/database - Utilities
13
+ * Database utility functions
14
+ */
15
+ /**
16
+ * Sleep for specified milliseconds
17
+ */
18
+ declare function sleep(ms: number): Promise<void>;
19
+ /**
20
+ * Retry a database operation with exponential backoff
21
+ */
22
+ declare function retry<T>(operation: () => Promise<T>, options?: {
23
+ maxAttempts?: number;
24
+ baseDelay?: number;
25
+ maxDelay?: number;
26
+ shouldRetry?: (error: unknown) => boolean;
27
+ }): Promise<T>;
28
+ /**
29
+ * Check if an error is retryable
30
+ */
31
+ declare function isRetryableError(error: unknown): boolean;
32
+ /**
33
+ * Parse a PostgreSQL connection string
34
+ */
35
+ declare function parseConnectionString(connectionString: string): {
36
+ host: string;
37
+ port: number;
38
+ user: string;
39
+ password: string;
40
+ database: string;
41
+ ssl: boolean;
42
+ params: Record<string, string>;
43
+ };
44
+ /**
45
+ * Build a PostgreSQL connection string
46
+ */
47
+ declare function buildConnectionString(config: {
48
+ host: string;
49
+ port?: number;
50
+ user: string;
51
+ password: string;
52
+ database: string;
53
+ ssl?: boolean;
54
+ params?: Record<string, string>;
55
+ }): string;
56
+ /**
57
+ * Convert snake_case to camelCase
58
+ */
59
+ declare function snakeToCamel(str: string): string;
60
+ /**
61
+ * Convert camelCase to snake_case
62
+ */
63
+ declare function camelToSnake(str: string): string;
64
+ /**
65
+ * Transform object keys from snake_case to camelCase
66
+ */
67
+ declare function transformToCamelCase<T extends Record<string, unknown>>(obj: T): Record<string, unknown>;
68
+ /**
69
+ * Transform object keys from camelCase to snake_case
70
+ */
71
+ declare function transformToSnakeCase<T extends Record<string, unknown>>(obj: T): Record<string, unknown>;
72
+ /**
73
+ * Generate a UUID v4
74
+ */
75
+ declare function generateUUID(): string;
76
+ /**
77
+ * Generate a short ID (8 characters)
78
+ */
79
+ declare function generateShortId(): string;
80
+ /**
81
+ * Paginate results
82
+ */
83
+ interface PaginationOptions {
84
+ page?: number;
85
+ limit?: number;
86
+ maxLimit?: number;
87
+ }
88
+ interface PaginatedResult<T> {
89
+ data: T[];
90
+ pagination: {
91
+ page: number;
92
+ limit: number;
93
+ total: number;
94
+ totalPages: number;
95
+ hasMore: boolean;
96
+ };
97
+ }
98
+ /**
99
+ * Calculate pagination offset
100
+ */
101
+ declare function getPaginationOffset(options: PaginationOptions): {
102
+ offset: number;
103
+ limit: number;
104
+ };
105
+ /**
106
+ * Create paginated result
107
+ */
108
+ declare function createPaginatedResult<T>(data: T[], total: number, options: PaginationOptions): PaginatedResult<T>;
109
+ /**
110
+ * Escape special characters for LIKE queries
111
+ */
112
+ declare function escapeLike(value: string): string;
113
+ /**
114
+ * Build a search pattern for LIKE queries
115
+ */
116
+ declare function buildSearchPattern(value: string, mode?: "contains" | "startsWith" | "endsWith"): string;
117
+
118
+ /**
119
+ * @parsrun/database
120
+ * Database utilities for Pars - Drizzle ORM helpers, multi-runtime support
121
+ *
122
+ * Supports:
123
+ * - PostgreSQL (via postgres.js)
124
+ * - Neon Serverless (edge-compatible)
125
+ * - Cloudflare D1 (SQLite)
126
+ *
127
+ * @example
128
+ * ```typescript
129
+ * import { createDatabase } from '@parsrun/database';
130
+ *
131
+ * // PostgreSQL
132
+ * const db = await createDatabase({
133
+ * type: 'postgres',
134
+ * host: 'localhost',
135
+ * port: 5432,
136
+ * user: 'postgres',
137
+ * password: 'password',
138
+ * database: 'mydb',
139
+ * });
140
+ *
141
+ * // Neon Serverless
142
+ * const db = await createDatabase({
143
+ * type: 'neon',
144
+ * connectionString: process.env.DATABASE_URL,
145
+ * });
146
+ *
147
+ * // Cloudflare D1
148
+ * const db = createDatabase({
149
+ * type: 'd1',
150
+ * binding: env.DB,
151
+ * });
152
+ *
153
+ * // Use with Drizzle ORM
154
+ * const users = await db.drizzle().select().from(usersTable);
155
+ * ```
156
+ */
157
+
158
+ /**
159
+ * Create a database adapter based on configuration
160
+ *
161
+ * @param config - Database configuration
162
+ * @returns Database adapter instance
163
+ */
164
+ declare function createDatabase(config: DatabaseConfig): Promise<DatabaseAdapter>;
165
+ /**
166
+ * Create a database adapter from connection string
167
+ *
168
+ * @param connectionString - Database connection URL
169
+ * @param options - Additional options
170
+ * @returns Database adapter instance
171
+ */
172
+ declare function createDatabaseFromUrl(connectionString: string, options?: {
173
+ logging?: boolean;
174
+ poolSize?: number;
175
+ }): Promise<DatabaseAdapter>;
176
+
177
+ export { DatabaseAdapter, DatabaseConfig, type PaginatedResult, type PaginationOptions, buildConnectionString, buildSearchPattern, camelToSnake, createDatabase, createDatabaseFromUrl, createPaginatedResult, escapeLike, generateShortId, generateUUID, getPaginationOffset, isRetryableError, parseConnectionString, retry, sleep, snakeToCamel, transformToCamelCase, transformToSnakeCase };