driftsql 1.0.8 → 1.0.10
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/dist/index.d.mts +20 -33
- package/dist/index.d.ts +20 -33
- package/dist/index.mjs +262 -192
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
interface PostgresConfig {
|
|
2
|
+
connectionString: string;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
interface LibSQLConfig {
|
|
6
|
+
url: string;
|
|
7
|
+
authToken?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
interface MySQLConfig {
|
|
11
|
+
connectionString: string;
|
|
12
|
+
}
|
|
4
13
|
|
|
5
14
|
type Drivers = ClientOptions['drivers'];
|
|
6
15
|
declare const inspectDB: (drivers: Drivers) => Promise<never>;
|
|
@@ -15,42 +24,20 @@ type UnifiedQueryResult<T extends Record<string, any>> = {
|
|
|
15
24
|
}>;
|
|
16
25
|
};
|
|
17
26
|
interface ClientOptions {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* @deprecated Since version 1.0.8 this option is deprecated and will be removed in future versions. Use `drivers.postgresHTTP.url` instead.
|
|
24
|
-
*/
|
|
25
|
-
password?: string;
|
|
26
|
-
drivers?: {
|
|
27
|
-
libsql?: Config;
|
|
28
|
-
postgres?: PoolConfig;
|
|
29
|
-
postgresHTTP?: {
|
|
30
|
-
url: string;
|
|
31
|
-
password: string;
|
|
32
|
-
};
|
|
33
|
-
mysql?: ConnectionOptions;
|
|
34
|
-
};
|
|
35
|
-
options?: {
|
|
36
|
-
defaultTimeout?: number;
|
|
27
|
+
drivers: {
|
|
28
|
+
libsql?: LibSQLConfig;
|
|
29
|
+
postgres?: PostgresConfig;
|
|
30
|
+
mysql?: MySQLConfig;
|
|
37
31
|
};
|
|
38
32
|
}
|
|
39
33
|
declare class DriftSQLClient<DT> {
|
|
40
|
-
private
|
|
41
|
-
private
|
|
42
|
-
private
|
|
43
|
-
private libsqlClient?;
|
|
44
|
-
private postgresClient?;
|
|
34
|
+
private postgres?;
|
|
35
|
+
private libsql?;
|
|
36
|
+
private mysql?;
|
|
45
37
|
private drivers;
|
|
46
38
|
constructor(options: ClientOptions);
|
|
47
|
-
private convertLibsqlResult;
|
|
48
39
|
readonly inspect: () => Promise<void>;
|
|
49
40
|
query<T extends Record<string, any>>(query: string, args?: (string | number | boolean | null)[]): Promise<UnifiedQueryResult<T>>;
|
|
50
|
-
status(): Promise<{
|
|
51
|
-
ok: boolean;
|
|
52
|
-
ping: number;
|
|
53
|
-
}>;
|
|
54
41
|
findFirst<K extends keyof DT>(table: K, where?: Partial<DT[K]>): Promise<DT[K] | null>;
|
|
55
42
|
findMany<K extends keyof DT>(table: K, options?: {
|
|
56
43
|
where?: Partial<DT[K]>;
|
|
@@ -64,4 +51,4 @@ declare class DriftSQLClient<DT> {
|
|
|
64
51
|
}
|
|
65
52
|
|
|
66
53
|
export { DriftSQLClient, inspectDB };
|
|
67
|
-
export type { ClientOptions };
|
|
54
|
+
export type { ClientOptions, UnifiedQueryResult };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
interface PostgresConfig {
|
|
2
|
+
connectionString: string;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
interface LibSQLConfig {
|
|
6
|
+
url: string;
|
|
7
|
+
authToken?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
interface MySQLConfig {
|
|
11
|
+
connectionString: string;
|
|
12
|
+
}
|
|
4
13
|
|
|
5
14
|
type Drivers = ClientOptions['drivers'];
|
|
6
15
|
declare const inspectDB: (drivers: Drivers) => Promise<never>;
|
|
@@ -15,42 +24,20 @@ type UnifiedQueryResult<T extends Record<string, any>> = {
|
|
|
15
24
|
}>;
|
|
16
25
|
};
|
|
17
26
|
interface ClientOptions {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* @deprecated Since version 1.0.8 this option is deprecated and will be removed in future versions. Use `drivers.postgresHTTP.url` instead.
|
|
24
|
-
*/
|
|
25
|
-
password?: string;
|
|
26
|
-
drivers?: {
|
|
27
|
-
libsql?: Config;
|
|
28
|
-
postgres?: PoolConfig;
|
|
29
|
-
postgresHTTP?: {
|
|
30
|
-
url: string;
|
|
31
|
-
password: string;
|
|
32
|
-
};
|
|
33
|
-
mysql?: ConnectionOptions;
|
|
34
|
-
};
|
|
35
|
-
options?: {
|
|
36
|
-
defaultTimeout?: number;
|
|
27
|
+
drivers: {
|
|
28
|
+
libsql?: LibSQLConfig;
|
|
29
|
+
postgres?: PostgresConfig;
|
|
30
|
+
mysql?: MySQLConfig;
|
|
37
31
|
};
|
|
38
32
|
}
|
|
39
33
|
declare class DriftSQLClient<DT> {
|
|
40
|
-
private
|
|
41
|
-
private
|
|
42
|
-
private
|
|
43
|
-
private libsqlClient?;
|
|
44
|
-
private postgresClient?;
|
|
34
|
+
private postgres?;
|
|
35
|
+
private libsql?;
|
|
36
|
+
private mysql?;
|
|
45
37
|
private drivers;
|
|
46
38
|
constructor(options: ClientOptions);
|
|
47
|
-
private convertLibsqlResult;
|
|
48
39
|
readonly inspect: () => Promise<void>;
|
|
49
40
|
query<T extends Record<string, any>>(query: string, args?: (string | number | boolean | null)[]): Promise<UnifiedQueryResult<T>>;
|
|
50
|
-
status(): Promise<{
|
|
51
|
-
ok: boolean;
|
|
52
|
-
ping: number;
|
|
53
|
-
}>;
|
|
54
41
|
findFirst<K extends keyof DT>(table: K, where?: Partial<DT[K]>): Promise<DT[K] | null>;
|
|
55
42
|
findMany<K extends keyof DT>(table: K, options?: {
|
|
56
43
|
where?: Partial<DT[K]>;
|
|
@@ -64,4 +51,4 @@ declare class DriftSQLClient<DT> {
|
|
|
64
51
|
}
|
|
65
52
|
|
|
66
53
|
export { DriftSQLClient, inspectDB };
|
|
67
|
-
export type { ClientOptions };
|
|
54
|
+
export type { ClientOptions, UnifiedQueryResult };
|
package/dist/index.mjs
CHANGED
|
@@ -1,11 +1,28 @@
|
|
|
1
1
|
import consola from 'consola';
|
|
2
|
-
import
|
|
3
|
-
import { Pool } from 'pg';
|
|
2
|
+
import postgres from 'postgres';
|
|
4
3
|
import { createClient } from '@libsql/client';
|
|
5
|
-
import mysql from 'mysql2/promise';
|
|
4
|
+
import * as mysql from 'mysql2/promise';
|
|
6
5
|
import fs from 'node:fs/promises';
|
|
7
6
|
|
|
8
7
|
const supportedDrivers = ["postgres", "postgresHTTP", "mysql", "libsql"];
|
|
8
|
+
const withTimeout = (promise, timeoutMs = 3e4) => {
|
|
9
|
+
return Promise.race([promise, new Promise((_, reject) => setTimeout(() => reject(new Error(`Query timeout after ${timeoutMs}ms`)), timeoutMs))]);
|
|
10
|
+
};
|
|
11
|
+
const retryQuery = async (queryFn, maxRetries = 3, baseDelay = 1e3) => {
|
|
12
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
13
|
+
try {
|
|
14
|
+
return await queryFn();
|
|
15
|
+
} catch (error) {
|
|
16
|
+
if (attempt === maxRetries) {
|
|
17
|
+
throw error;
|
|
18
|
+
}
|
|
19
|
+
const delay = baseDelay * Math.pow(2, attempt - 1);
|
|
20
|
+
console.warn(`Query attempt ${attempt} failed, retrying in ${delay}ms...`, error);
|
|
21
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
throw new Error("Max retries exceeded");
|
|
25
|
+
};
|
|
9
26
|
const mapDatabaseTypeToTypeScript = (dataType, isNullable = false, driverType = "postgres") => {
|
|
10
27
|
const nullable = isNullable ? " | null" : "";
|
|
11
28
|
const lowerType = dataType.toLowerCase();
|
|
@@ -103,144 +120,178 @@ const inspectDB = async (drivers) => {
|
|
|
103
120
|
const activeDriver = supportedConfiguredDrivers[0];
|
|
104
121
|
let generatedTypes = "";
|
|
105
122
|
const client = new DriftSQLClient({ drivers });
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
123
|
+
try {
|
|
124
|
+
let tablesQuery;
|
|
125
|
+
let tableSchemaFilter;
|
|
126
|
+
if (activeDriver === "mysql") {
|
|
127
|
+
const dbResult = await withTimeout(
|
|
128
|
+
retryQuery(() => client.query("SELECT DATABASE() as `database`", [])),
|
|
129
|
+
1e4
|
|
130
|
+
);
|
|
131
|
+
const currentDatabase = dbResult.rows[0]?.database;
|
|
132
|
+
if (!currentDatabase) {
|
|
133
|
+
throw new Error("Could not determine current MySQL database name");
|
|
134
|
+
}
|
|
135
|
+
console.log(`Using MySQL database: ${currentDatabase}`);
|
|
136
|
+
tablesQuery = `SELECT TABLE_NAME as table_name
|
|
116
137
|
FROM information_schema.tables
|
|
117
138
|
WHERE TABLE_SCHEMA = ?
|
|
118
139
|
AND TABLE_TYPE = 'BASE TABLE'
|
|
119
140
|
ORDER BY TABLE_NAME`;
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
141
|
+
tableSchemaFilter = currentDatabase;
|
|
142
|
+
} else if (activeDriver === "postgres" || activeDriver === "postgresHTTP") {
|
|
143
|
+
tablesQuery = `SELECT table_name
|
|
123
144
|
FROM information_schema.tables
|
|
124
145
|
WHERE table_schema = $1
|
|
125
146
|
AND table_type = 'BASE TABLE'
|
|
126
147
|
ORDER BY table_name`;
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
148
|
+
tableSchemaFilter = "public";
|
|
149
|
+
} else {
|
|
150
|
+
tablesQuery = `SELECT name as table_name
|
|
130
151
|
FROM sqlite_master
|
|
131
152
|
WHERE type = 'table'
|
|
132
153
|
ORDER BY name`;
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
console.log(
|
|
140
|
-
let
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
154
|
+
tableSchemaFilter = void 0;
|
|
155
|
+
}
|
|
156
|
+
const tables = await withTimeout(
|
|
157
|
+
retryQuery(() => client.query(tablesQuery, tableSchemaFilter ? [tableSchemaFilter] : [])),
|
|
158
|
+
3e4
|
|
159
|
+
);
|
|
160
|
+
console.log("Tables in the database:", tables.rows.map((t) => t.table_name).join(", "));
|
|
161
|
+
let processedTables = 0;
|
|
162
|
+
const totalTables = tables.rows.length;
|
|
163
|
+
for (const table of tables.rows) {
|
|
164
|
+
const tableName = table.table_name;
|
|
165
|
+
processedTables++;
|
|
166
|
+
console.log(`[${processedTables}/${totalTables}] Inspecting table: ${tableName}`);
|
|
167
|
+
try {
|
|
168
|
+
let columnsQuery;
|
|
169
|
+
let queryParams;
|
|
170
|
+
if (activeDriver === "mysql") {
|
|
171
|
+
columnsQuery = `
|
|
172
|
+
SELECT
|
|
173
|
+
COLUMN_NAME as column_name,
|
|
174
|
+
DATA_TYPE as data_type,
|
|
175
|
+
IS_NULLABLE as is_nullable,
|
|
176
|
+
COLUMN_DEFAULT as column_default
|
|
177
|
+
FROM information_schema.columns
|
|
178
|
+
WHERE TABLE_NAME = ?
|
|
179
|
+
AND TABLE_SCHEMA = ?
|
|
180
|
+
ORDER BY ORDINAL_POSITION
|
|
181
|
+
`;
|
|
182
|
+
queryParams = [tableName, tableSchemaFilter];
|
|
183
|
+
} else if (activeDriver === "postgres" || activeDriver === "postgresHTTP") {
|
|
184
|
+
columnsQuery = `
|
|
185
|
+
SELECT
|
|
186
|
+
column_name,
|
|
187
|
+
data_type,
|
|
188
|
+
is_nullable,
|
|
189
|
+
column_default
|
|
190
|
+
FROM information_schema.columns
|
|
191
|
+
WHERE table_name = $1
|
|
192
|
+
AND table_schema = $2
|
|
193
|
+
ORDER BY ordinal_position
|
|
194
|
+
`;
|
|
195
|
+
queryParams = [tableName, tableSchemaFilter];
|
|
196
|
+
} else {
|
|
197
|
+
columnsQuery = `
|
|
198
|
+
SELECT
|
|
199
|
+
name as column_name,
|
|
200
|
+
type as data_type,
|
|
201
|
+
CASE WHEN "notnull" = 0 THEN 'YES' ELSE 'NO' END as is_nullable,
|
|
202
|
+
dflt_value as column_default
|
|
203
|
+
FROM pragma_table_info(?)
|
|
204
|
+
ORDER BY cid
|
|
205
|
+
`;
|
|
206
|
+
queryParams = [tableName];
|
|
207
|
+
}
|
|
208
|
+
const columns = await withTimeout(
|
|
209
|
+
retryQuery(
|
|
210
|
+
() => client.query(columnsQuery, queryParams)
|
|
211
|
+
),
|
|
212
|
+
15e3
|
|
213
|
+
// Shorter timeout for individual table queries
|
|
214
|
+
);
|
|
215
|
+
if (columns.rows.length === 0) {
|
|
216
|
+
console.log(`No columns found for table: ${tableName}`);
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
console.log(`Columns in ${tableName}:`, columns.rows.map((c) => `${c.column_name} (${c.data_type}${c.is_nullable === "YES" ? ", nullable" : ""})`).join(", "));
|
|
220
|
+
const uniqueColumns = /* @__PURE__ */ new Map();
|
|
221
|
+
columns.rows.forEach((col) => {
|
|
222
|
+
if (!uniqueColumns.has(col.column_name)) {
|
|
223
|
+
uniqueColumns.set(col.column_name, col);
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
generatedTypes += `export interface ${tableName.charAt(0).toUpperCase() + tableName.slice(1)} {
|
|
193
227
|
`;
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
228
|
+
for (const col of uniqueColumns.values()) {
|
|
229
|
+
const tsType = mapDatabaseTypeToTypeScript(col.data_type, col.is_nullable === "YES", activeDriver);
|
|
230
|
+
generatedTypes += ` ${col.column_name}: ${tsType};
|
|
197
231
|
`;
|
|
232
|
+
}
|
|
233
|
+
generatedTypes += "}\n\n";
|
|
234
|
+
} catch (error) {
|
|
235
|
+
console.error(`Failed to process table ${tableName}:`, error);
|
|
236
|
+
console.log(`Skipping table ${tableName} and continuing...`);
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
198
239
|
}
|
|
199
|
-
generatedTypes += "
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
const tableName = table.table_name.charAt(0).toUpperCase() + table.table_name.slice(1);
|
|
204
|
-
generatedTypes += ` ${tableName}: ${tableName};
|
|
240
|
+
generatedTypes += "export interface Database {\n";
|
|
241
|
+
for (const table of tables.rows) {
|
|
242
|
+
const tableName = table.table_name.charAt(0).toUpperCase() + table.table_name.slice(1);
|
|
243
|
+
generatedTypes += ` ${tableName}: ${tableName};
|
|
205
244
|
`;
|
|
245
|
+
}
|
|
246
|
+
generatedTypes += "}\n\n";
|
|
247
|
+
await fs.writeFile("db-types.ts", generatedTypes, "utf8");
|
|
248
|
+
console.log("TypeScript types written to db-types.ts");
|
|
249
|
+
console.log(`Successfully processed ${processedTables} tables`);
|
|
250
|
+
} catch (error) {
|
|
251
|
+
console.error("Fatal error during database inspection:", error);
|
|
252
|
+
process.exit(1);
|
|
206
253
|
}
|
|
207
|
-
generatedTypes += "}\n\n";
|
|
208
|
-
await fs.writeFile("db-types.ts", generatedTypes, "utf8");
|
|
209
|
-
console.log("TypeScript types written to db-types.ts");
|
|
210
254
|
process.exit(0);
|
|
211
255
|
};
|
|
212
256
|
|
|
213
|
-
class
|
|
257
|
+
class PostgresDriver {
|
|
258
|
+
constructor(options) {
|
|
259
|
+
this.options = options;
|
|
260
|
+
this.client = postgres(this.options.connectionString);
|
|
261
|
+
}
|
|
214
262
|
client;
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
263
|
+
async query(query, params) {
|
|
264
|
+
try {
|
|
265
|
+
const result = await this.client.unsafe(query, params);
|
|
266
|
+
return {
|
|
267
|
+
rows: result,
|
|
268
|
+
rowCount: result.length,
|
|
269
|
+
command: void 0
|
|
270
|
+
};
|
|
271
|
+
} catch (error) {
|
|
272
|
+
console.error("Postgres query error:", error);
|
|
273
|
+
throw error;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
async close() {
|
|
277
|
+
try {
|
|
278
|
+
await this.client.end();
|
|
279
|
+
} catch (error) {
|
|
280
|
+
console.error("Error closing Postgres client:", error);
|
|
281
|
+
throw error;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
class LibSQLDriver {
|
|
220
287
|
constructor(options) {
|
|
221
|
-
this.
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
},
|
|
226
|
-
timeout: options.options?.defaultTimeout || 5e3,
|
|
227
|
-
hooks: {
|
|
228
|
-
afterResponse: [
|
|
229
|
-
async (request, options2, response) => {
|
|
230
|
-
if (!response.ok) {
|
|
231
|
-
const errorText = await response.text();
|
|
232
|
-
throw new Error(`HTTP Error: ${response.status} - ${errorText}`);
|
|
233
|
-
}
|
|
234
|
-
return response;
|
|
235
|
-
}
|
|
236
|
-
]
|
|
237
|
-
}
|
|
288
|
+
this.options = options;
|
|
289
|
+
this.client = createClient({
|
|
290
|
+
url: this.options.url,
|
|
291
|
+
...this.options.authToken ? { authToken: this.options.authToken } : {}
|
|
238
292
|
});
|
|
239
|
-
this.pool = options.drivers?.postgres ? new Pool(options.drivers.postgres) : void 0;
|
|
240
|
-
this.libsqlClient = options.drivers?.libsql ? createClient(options.drivers.libsql) : void 0;
|
|
241
|
-
this.mysqlClient = options.drivers?.mysql ? mysql.createConnection(options.drivers.mysql) : void 0;
|
|
242
|
-
this.drivers = options.drivers || {};
|
|
243
293
|
}
|
|
294
|
+
client;
|
|
244
295
|
convertLibsqlResult(result) {
|
|
245
296
|
const rows = result.rows.map((row) => {
|
|
246
297
|
const obj = {};
|
|
@@ -256,93 +307,115 @@ class DriftSQLClient {
|
|
|
256
307
|
fields: result.columns.map((col) => ({ name: col, dataTypeID: 0 }))
|
|
257
308
|
};
|
|
258
309
|
}
|
|
310
|
+
async query(query, params) {
|
|
311
|
+
try {
|
|
312
|
+
const result = await this.client.execute(query, params);
|
|
313
|
+
return this.convertLibsqlResult(result);
|
|
314
|
+
} catch (error) {
|
|
315
|
+
console.error("LibSQL query error:", error);
|
|
316
|
+
throw error;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
async close() {
|
|
320
|
+
try {
|
|
321
|
+
this.client.close();
|
|
322
|
+
} catch (error) {
|
|
323
|
+
console.error("Error closing LibSQL client:", error);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
class MySQLDriver {
|
|
329
|
+
constructor(options) {
|
|
330
|
+
this.options = options;
|
|
331
|
+
consola.warn("MySQL client is experimental and may not be compatible with the helper functions, since they originally designed for PostgreSQL and libsql. But .query() method should work.");
|
|
332
|
+
this.client = mysql.createConnection(this.options.connectionString);
|
|
333
|
+
}
|
|
334
|
+
client;
|
|
335
|
+
async query(query, params) {
|
|
336
|
+
try {
|
|
337
|
+
const [rows, fields] = await (await this.client).execute(query, params || []);
|
|
338
|
+
const rowCount = Array.isArray(rows) ? rows.length : 0;
|
|
339
|
+
return {
|
|
340
|
+
rows,
|
|
341
|
+
rowCount,
|
|
342
|
+
command: void 0,
|
|
343
|
+
fields: fields.map((field) => ({ name: field.name, dataTypeID: field.columnType }))
|
|
344
|
+
};
|
|
345
|
+
} catch (error) {
|
|
346
|
+
consola.error("MySQL query error:", error);
|
|
347
|
+
throw error;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
async close() {
|
|
351
|
+
try {
|
|
352
|
+
await (await this.client).end();
|
|
353
|
+
} catch (error) {
|
|
354
|
+
consola.error("Error closing MySQL client:", error);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
class DriftSQLClient {
|
|
360
|
+
postgres;
|
|
361
|
+
libsql;
|
|
362
|
+
mysql;
|
|
363
|
+
drivers;
|
|
364
|
+
constructor(options) {
|
|
365
|
+
this.postgres = options.drivers?.postgres ? new PostgresDriver({ connectionString: options.drivers.postgres.connectionString }) : void 0;
|
|
366
|
+
this.libsql = options.drivers?.libsql ? new LibSQLDriver(options.drivers.libsql) : void 0;
|
|
367
|
+
this.mysql = options.drivers?.mysql ? new MySQLDriver(options.drivers.mysql) : void 0;
|
|
368
|
+
this.drivers = options.drivers || {};
|
|
369
|
+
}
|
|
259
370
|
inspect = async () => {
|
|
260
371
|
return inspectDB(this.drivers);
|
|
261
372
|
};
|
|
262
373
|
async query(query, args) {
|
|
263
|
-
|
|
264
|
-
if (driversCount > 1) {
|
|
265
|
-
const error = new Error("Multiple drivers are configured. Please use only one driver at a time.");
|
|
266
|
-
consola.error(error);
|
|
267
|
-
throw error;
|
|
268
|
-
}
|
|
269
|
-
if (this.pool) {
|
|
374
|
+
if (this.postgres) {
|
|
270
375
|
try {
|
|
271
|
-
await this.
|
|
272
|
-
const result = await this.pool.query(query, args || []);
|
|
376
|
+
const result = await this.postgres.query(query, args || []);
|
|
273
377
|
return {
|
|
274
378
|
rows: result.rows,
|
|
275
379
|
rowCount: result.rowCount || 0,
|
|
276
380
|
command: result.command,
|
|
277
|
-
fields: result.fields
|
|
381
|
+
fields: result.fields?.map((field) => ({ name: field.name, dataTypeID: field.dataTypeID })) || []
|
|
278
382
|
};
|
|
279
|
-
} catch (
|
|
280
|
-
consola.error("Failed to
|
|
383
|
+
} catch (error2) {
|
|
384
|
+
consola.error("Failed to execute query with PostgreSQL:", error2);
|
|
385
|
+
throw error2;
|
|
281
386
|
}
|
|
282
387
|
}
|
|
283
|
-
if (this.
|
|
388
|
+
if (this.mysql) {
|
|
284
389
|
try {
|
|
285
|
-
|
|
286
|
-
const filteredArgs = (args || []).map((arg) => arg === void 0 ? null : arg);
|
|
287
|
-
const [rows, fields] = await (await this.mysqlClient).execute(query, filteredArgs);
|
|
390
|
+
const result = await this.mysql.query(query, args || []);
|
|
288
391
|
return {
|
|
289
|
-
rows,
|
|
290
|
-
rowCount:
|
|
291
|
-
command:
|
|
292
|
-
|
|
293
|
-
fields: fields.map((field) => ({ name: field.name, dataTypeID: field.columnType }))
|
|
392
|
+
rows: result.rows,
|
|
393
|
+
rowCount: result.rowCount || 0,
|
|
394
|
+
command: result.command,
|
|
395
|
+
fields: result.fields?.map((field) => ({ name: field.name, dataTypeID: field.dataTypeID })) || []
|
|
294
396
|
};
|
|
295
|
-
} catch (
|
|
296
|
-
consola.error("Failed to execute query with MySQL:",
|
|
297
|
-
throw
|
|
397
|
+
} catch (error2) {
|
|
398
|
+
consola.error("Failed to execute query with MySQL:", error2);
|
|
399
|
+
throw error2;
|
|
298
400
|
}
|
|
299
401
|
}
|
|
300
|
-
if (this.
|
|
402
|
+
if (this.libsql) {
|
|
301
403
|
try {
|
|
302
|
-
const result = await this.
|
|
404
|
+
const result = await this.libsql.query(query, args || []);
|
|
303
405
|
return {
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
fields: []
|
|
309
|
-
// postgres library does not provide field info
|
|
406
|
+
rows: result.rows,
|
|
407
|
+
rowCount: result.rowCount || 0,
|
|
408
|
+
command: result.command,
|
|
409
|
+
fields: void 0
|
|
310
410
|
};
|
|
311
|
-
} catch (
|
|
312
|
-
consola.error("Failed to execute query with
|
|
313
|
-
throw
|
|
411
|
+
} catch (error2) {
|
|
412
|
+
consola.error("Failed to execute query with LibSQL:", error2);
|
|
413
|
+
throw error2;
|
|
314
414
|
}
|
|
315
415
|
}
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
sql: query,
|
|
320
|
-
args: args || []
|
|
321
|
-
});
|
|
322
|
-
return this.convertLibsqlResult(result);
|
|
323
|
-
} catch (error) {
|
|
324
|
-
consola.error("Failed to execute query with libsql:", error);
|
|
325
|
-
throw error;
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
try {
|
|
329
|
-
const response = await this.client.post("query", {
|
|
330
|
-
json: { query, args: args || [] }
|
|
331
|
-
});
|
|
332
|
-
return response.json();
|
|
333
|
-
} catch (error) {
|
|
334
|
-
if (error instanceof Error) {
|
|
335
|
-
throw error;
|
|
336
|
-
}
|
|
337
|
-
throw new Error(`Query failed: ${JSON.stringify(error)}`);
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
async status() {
|
|
341
|
-
if (!this.client) {
|
|
342
|
-
throw new Error("HTTP client is not configured");
|
|
343
|
-
}
|
|
344
|
-
const response = await this.client.get("status");
|
|
345
|
-
return response.json();
|
|
416
|
+
const error = new Error("No database driver is configured or all drivers failed to execute the query");
|
|
417
|
+
consola.error(error);
|
|
418
|
+
throw error;
|
|
346
419
|
}
|
|
347
420
|
async findFirst(table, where) {
|
|
348
421
|
const tableName = String(table);
|
|
@@ -424,17 +497,14 @@ class DriftSQLClient {
|
|
|
424
497
|
return this.delete(table, where);
|
|
425
498
|
}
|
|
426
499
|
async close() {
|
|
427
|
-
if (this.
|
|
428
|
-
await this.
|
|
429
|
-
}
|
|
430
|
-
if (this.libsqlClient) {
|
|
431
|
-
this.libsqlClient.close();
|
|
500
|
+
if (this.postgres) {
|
|
501
|
+
await this.postgres.close();
|
|
432
502
|
}
|
|
433
|
-
if (this.
|
|
434
|
-
|
|
503
|
+
if (this.libsql) {
|
|
504
|
+
this.libsql.close();
|
|
435
505
|
}
|
|
436
|
-
if (this.
|
|
437
|
-
await this.
|
|
506
|
+
if (this.mysql) {
|
|
507
|
+
await this.mysql.close();
|
|
438
508
|
}
|
|
439
509
|
}
|
|
440
510
|
}
|
package/package.json
CHANGED