driftsql 1.0.3 → 1.0.5
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/LICENSE +1 -1
- package/dist/index.d.mts +4 -2
- package/dist/index.d.ts +4 -2
- package/dist/index.mjs +100 -48
- package/package.json +1 -1
package/LICENSE
CHANGED
package/dist/index.d.mts
CHANGED
|
@@ -31,7 +31,6 @@ declare class DriftSQLClient<DT> {
|
|
|
31
31
|
private pool?;
|
|
32
32
|
private mysqlClient?;
|
|
33
33
|
private libsqlClient?;
|
|
34
|
-
private neonClient?;
|
|
35
34
|
private postgresClient?;
|
|
36
35
|
private drivers;
|
|
37
36
|
constructor(options: ClientOptions);
|
|
@@ -43,7 +42,10 @@ declare class DriftSQLClient<DT> {
|
|
|
43
42
|
ping: number;
|
|
44
43
|
}>;
|
|
45
44
|
findFirst<K extends keyof DT>(table: K, where?: Partial<DT[K]>): Promise<DT[K] | null>;
|
|
46
|
-
findMany<K extends keyof DT>(table: K,
|
|
45
|
+
findMany<K extends keyof DT>(table: K, options?: {
|
|
46
|
+
where?: Partial<DT[K]>;
|
|
47
|
+
limit?: number;
|
|
48
|
+
}): Promise<DT[K][]>;
|
|
47
49
|
insert<K extends keyof DT>(table: K, data: Partial<DT[K]>): Promise<DT[K]>;
|
|
48
50
|
update<K extends keyof DT>(table: K, data: Partial<DT[K]>, where: Partial<DT[K]>): Promise<DT[K] | null>;
|
|
49
51
|
delete<K extends keyof DT>(table: K, where: Partial<DT[K]>): Promise<boolean>;
|
package/dist/index.d.ts
CHANGED
|
@@ -31,7 +31,6 @@ declare class DriftSQLClient<DT> {
|
|
|
31
31
|
private pool?;
|
|
32
32
|
private mysqlClient?;
|
|
33
33
|
private libsqlClient?;
|
|
34
|
-
private neonClient?;
|
|
35
34
|
private postgresClient?;
|
|
36
35
|
private drivers;
|
|
37
36
|
constructor(options: ClientOptions);
|
|
@@ -43,7 +42,10 @@ declare class DriftSQLClient<DT> {
|
|
|
43
42
|
ping: number;
|
|
44
43
|
}>;
|
|
45
44
|
findFirst<K extends keyof DT>(table: K, where?: Partial<DT[K]>): Promise<DT[K] | null>;
|
|
46
|
-
findMany<K extends keyof DT>(table: K,
|
|
45
|
+
findMany<K extends keyof DT>(table: K, options?: {
|
|
46
|
+
where?: Partial<DT[K]>;
|
|
47
|
+
limit?: number;
|
|
48
|
+
}): Promise<DT[K][]>;
|
|
47
49
|
insert<K extends keyof DT>(table: K, data: Partial<DT[K]>): Promise<DT[K]>;
|
|
48
50
|
update<K extends keyof DT>(table: K, data: Partial<DT[K]>, where: Partial<DT[K]>): Promise<DT[K] | null>;
|
|
49
51
|
delete<K extends keyof DT>(table: K, where: Partial<DT[K]>): Promise<boolean>;
|
package/dist/index.mjs
CHANGED
|
@@ -5,10 +5,11 @@ import { createClient } from '@libsql/client';
|
|
|
5
5
|
import mysql from 'mysql2/promise';
|
|
6
6
|
import fs from 'node:fs/promises';
|
|
7
7
|
|
|
8
|
-
const supportedDrivers = ["postgres"];
|
|
9
|
-
const
|
|
8
|
+
const supportedDrivers = ["postgres", "mysql"];
|
|
9
|
+
const mapDatabaseTypeToTypeScript = (dataType, isNullable = false, driverType = "postgres") => {
|
|
10
10
|
const nullable = isNullable ? " | null" : "";
|
|
11
|
-
|
|
11
|
+
const lowerType = dataType.toLowerCase();
|
|
12
|
+
switch (lowerType) {
|
|
12
13
|
case "uuid": {
|
|
13
14
|
return `string${nullable}`;
|
|
14
15
|
}
|
|
@@ -16,7 +17,10 @@ const mapPostgresToTypeScript = (postgresType, isNullable = false) => {
|
|
|
16
17
|
case "varchar":
|
|
17
18
|
case "text":
|
|
18
19
|
case "char":
|
|
19
|
-
case "character":
|
|
20
|
+
case "character":
|
|
21
|
+
case "longtext":
|
|
22
|
+
case "mediumtext":
|
|
23
|
+
case "tinytext": {
|
|
20
24
|
return `string${nullable}`;
|
|
21
25
|
}
|
|
22
26
|
case "integer":
|
|
@@ -33,11 +37,16 @@ const mapPostgresToTypeScript = (postgresType, isNullable = false) => {
|
|
|
33
37
|
case "real":
|
|
34
38
|
case "float4":
|
|
35
39
|
case "double precision":
|
|
36
|
-
case "float8":
|
|
40
|
+
case "float8":
|
|
41
|
+
case "tinyint":
|
|
42
|
+
case "mediumint":
|
|
43
|
+
case "float":
|
|
44
|
+
case "double": {
|
|
37
45
|
return `number${nullable}`;
|
|
38
46
|
}
|
|
39
47
|
case "boolean":
|
|
40
|
-
case "bool":
|
|
48
|
+
case "bool":
|
|
49
|
+
case "bit": {
|
|
41
50
|
return `boolean${nullable}`;
|
|
42
51
|
}
|
|
43
52
|
case "timestamp":
|
|
@@ -49,7 +58,9 @@ const mapPostgresToTypeScript = (postgresType, isNullable = false) => {
|
|
|
49
58
|
case "time with time zone":
|
|
50
59
|
case "time without time zone":
|
|
51
60
|
case "timetz":
|
|
52
|
-
case "interval":
|
|
61
|
+
case "interval":
|
|
62
|
+
case "datetime":
|
|
63
|
+
case "year": {
|
|
53
64
|
return `Date${nullable}`;
|
|
54
65
|
}
|
|
55
66
|
case "json":
|
|
@@ -59,11 +70,21 @@ const mapPostgresToTypeScript = (postgresType, isNullable = false) => {
|
|
|
59
70
|
case "array": {
|
|
60
71
|
return `any[]${nullable}`;
|
|
61
72
|
}
|
|
62
|
-
case "bytea":
|
|
73
|
+
case "bytea":
|
|
74
|
+
case "binary":
|
|
75
|
+
case "varbinary":
|
|
76
|
+
case "blob":
|
|
77
|
+
case "longblob":
|
|
78
|
+
case "mediumblob":
|
|
79
|
+
case "tinyblob": {
|
|
63
80
|
return `Buffer${nullable}`;
|
|
64
81
|
}
|
|
82
|
+
case "enum":
|
|
83
|
+
case "set": {
|
|
84
|
+
return `string${nullable}`;
|
|
85
|
+
}
|
|
65
86
|
default: {
|
|
66
|
-
console.warn(`Unknown
|
|
87
|
+
console.warn(`Unknown ${driverType} type: ${dataType}, defaulting to 'any'`);
|
|
67
88
|
return `any${nullable}`;
|
|
68
89
|
}
|
|
69
90
|
}
|
|
@@ -79,33 +100,67 @@ const inspectDB = async (drivers) => {
|
|
|
79
100
|
throw new Error(`No supported drivers found. Configured: ${configuredDrivers.join(", ")}. Supported: ${supportedDrivers.join(", ")}`);
|
|
80
101
|
}
|
|
81
102
|
console.log(`Found supported drivers: ${supportedConfiguredDrivers.join(", ")}`);
|
|
103
|
+
const activeDriver = supportedConfiguredDrivers[0];
|
|
82
104
|
let generatedTypes = "";
|
|
83
105
|
const client = new DriftSQLClient({ drivers });
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
106
|
+
let tablesQuery;
|
|
107
|
+
let tableSchemaFilter;
|
|
108
|
+
if (activeDriver === "mysql") {
|
|
109
|
+
const dbResult = await client.query("SELECT DATABASE() as `database`", []);
|
|
110
|
+
const currentDatabase = dbResult.rows[0]?.database;
|
|
111
|
+
if (!currentDatabase) {
|
|
112
|
+
throw new Error("Could not determine current MySQL database name");
|
|
113
|
+
}
|
|
114
|
+
console.log(`Using MySQL database: ${currentDatabase}`);
|
|
115
|
+
tablesQuery = `SELECT TABLE_NAME as table_name
|
|
116
|
+
FROM information_schema.tables
|
|
117
|
+
WHERE TABLE_SCHEMA = ?
|
|
118
|
+
AND TABLE_TYPE = 'BASE TABLE'
|
|
119
|
+
ORDER BY TABLE_NAME`;
|
|
120
|
+
tableSchemaFilter = currentDatabase;
|
|
121
|
+
} else {
|
|
122
|
+
tablesQuery = `SELECT table_name
|
|
123
|
+
FROM information_schema.tables
|
|
124
|
+
WHERE table_schema = $1
|
|
125
|
+
AND table_type = 'BASE TABLE'
|
|
126
|
+
ORDER BY table_name`;
|
|
127
|
+
tableSchemaFilter = "public";
|
|
128
|
+
}
|
|
129
|
+
const tables = await client.query(tablesQuery, tableSchemaFilter ? [tableSchemaFilter] : []);
|
|
91
130
|
console.log("Tables in the database:", tables.rows.map((t) => t.table_name).join(", "));
|
|
92
131
|
for (const table of tables.rows) {
|
|
93
132
|
const tableName = table.table_name;
|
|
94
133
|
console.log(`Inspecting table: ${tableName}`);
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
134
|
+
let columnsQuery;
|
|
135
|
+
let queryParams;
|
|
136
|
+
if (activeDriver === "mysql") {
|
|
137
|
+
columnsQuery = `
|
|
138
|
+
SELECT
|
|
139
|
+
COLUMN_NAME as column_name,
|
|
140
|
+
DATA_TYPE as data_type,
|
|
141
|
+
IS_NULLABLE as is_nullable,
|
|
142
|
+
COLUMN_DEFAULT as column_default
|
|
143
|
+
FROM information_schema.columns
|
|
144
|
+
WHERE TABLE_NAME = ?
|
|
145
|
+
AND TABLE_SCHEMA = ?
|
|
146
|
+
ORDER BY ORDINAL_POSITION
|
|
147
|
+
`;
|
|
148
|
+
queryParams = [tableName, tableSchemaFilter];
|
|
149
|
+
} else {
|
|
150
|
+
columnsQuery = `
|
|
151
|
+
SELECT
|
|
152
|
+
column_name,
|
|
153
|
+
data_type,
|
|
154
|
+
is_nullable,
|
|
155
|
+
column_default
|
|
156
|
+
FROM information_schema.columns
|
|
157
|
+
WHERE table_name = $1
|
|
158
|
+
AND table_schema = $2
|
|
159
|
+
ORDER BY ordinal_position
|
|
160
|
+
`;
|
|
161
|
+
queryParams = [tableName, tableSchemaFilter];
|
|
162
|
+
}
|
|
163
|
+
const columns = await client.query(columnsQuery, queryParams);
|
|
109
164
|
if (columns.rows.length === 0) {
|
|
110
165
|
console.log(`No columns found for table: ${tableName}`);
|
|
111
166
|
continue;
|
|
@@ -120,7 +175,7 @@ const inspectDB = async (drivers) => {
|
|
|
120
175
|
generatedTypes += `export interface ${tableName.charAt(0).toUpperCase() + tableName.slice(1)} {
|
|
121
176
|
`;
|
|
122
177
|
for (const col of uniqueColumns.values()) {
|
|
123
|
-
const tsType =
|
|
178
|
+
const tsType = mapDatabaseTypeToTypeScript(col.data_type, col.is_nullable === "YES", activeDriver);
|
|
124
179
|
generatedTypes += ` ${col.column_name}: ${tsType};
|
|
125
180
|
`;
|
|
126
181
|
}
|
|
@@ -143,7 +198,6 @@ class DriftSQLClient {
|
|
|
143
198
|
pool;
|
|
144
199
|
mysqlClient;
|
|
145
200
|
libsqlClient;
|
|
146
|
-
neonClient;
|
|
147
201
|
postgresClient;
|
|
148
202
|
drivers;
|
|
149
203
|
constructor(options) {
|
|
@@ -189,6 +243,12 @@ class DriftSQLClient {
|
|
|
189
243
|
return inspectDB(this.drivers);
|
|
190
244
|
};
|
|
191
245
|
async query(query, args) {
|
|
246
|
+
const driversCount = Object.keys(this.drivers).filter((key) => this.drivers[key] !== void 0).length;
|
|
247
|
+
if (driversCount > 1) {
|
|
248
|
+
const error = new Error("Multiple drivers are configured. Please use only one driver at a time.");
|
|
249
|
+
consola.error(error);
|
|
250
|
+
throw error;
|
|
251
|
+
}
|
|
192
252
|
if (this.pool) {
|
|
193
253
|
try {
|
|
194
254
|
await this.pool.connect();
|
|
@@ -206,7 +266,8 @@ class DriftSQLClient {
|
|
|
206
266
|
if (this.mysqlClient) {
|
|
207
267
|
try {
|
|
208
268
|
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.");
|
|
209
|
-
const
|
|
269
|
+
const filteredArgs = (args || []).map((arg) => arg === void 0 ? null : arg);
|
|
270
|
+
const [rows, fields] = await (await this.mysqlClient).execute(query, filteredArgs);
|
|
210
271
|
return {
|
|
211
272
|
rows,
|
|
212
273
|
rowCount: Array.isArray(rows) ? rows.length : 0,
|
|
@@ -247,20 +308,6 @@ class DriftSQLClient {
|
|
|
247
308
|
throw error;
|
|
248
309
|
}
|
|
249
310
|
}
|
|
250
|
-
if (this.neonClient) {
|
|
251
|
-
try {
|
|
252
|
-
const sql = this.neonClient;
|
|
253
|
-
console.log(sql);
|
|
254
|
-
throw new Error("Neon client is not implemented yet");
|
|
255
|
-
return {
|
|
256
|
-
rows: [],
|
|
257
|
-
rowCount: 0
|
|
258
|
-
};
|
|
259
|
-
} catch (error) {
|
|
260
|
-
consola.error("Failed to execute query with Neon:", error);
|
|
261
|
-
throw error;
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
311
|
try {
|
|
265
312
|
const response = await this.client.post("query", {
|
|
266
313
|
json: { query, args: args || [] }
|
|
@@ -294,8 +341,9 @@ class DriftSQLClient {
|
|
|
294
341
|
const result = await this.query(query, args);
|
|
295
342
|
return result.rows[0] || null;
|
|
296
343
|
}
|
|
297
|
-
async findMany(table,
|
|
344
|
+
async findMany(table, options) {
|
|
298
345
|
const tableName = String(table);
|
|
346
|
+
const { where, limit } = options || {};
|
|
299
347
|
const whereEntries = Object.entries(where || {});
|
|
300
348
|
let query = `SELECT * FROM ${tableName}`;
|
|
301
349
|
let args = [];
|
|
@@ -304,6 +352,10 @@ class DriftSQLClient {
|
|
|
304
352
|
query += ` WHERE ${whereClause}`;
|
|
305
353
|
args = whereEntries.map(([, value]) => value);
|
|
306
354
|
}
|
|
355
|
+
if (typeof limit === "number" && limit > 0) {
|
|
356
|
+
query += ` LIMIT $${args.length + 1}`;
|
|
357
|
+
args.push(limit);
|
|
358
|
+
}
|
|
307
359
|
const result = await this.query(query, args);
|
|
308
360
|
return result.rows;
|
|
309
361
|
}
|
package/package.json
CHANGED