@kysera/dialects 0.7.3 → 0.8.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 +115 -93
- package/dist/index.d.ts +85 -26
- package/dist/index.js +10 -2
- package/dist/index.js.map +1 -1
- package/package.json +4 -1
- package/src/adapters/mssql.ts +207 -0
- package/src/adapters/mysql.ts +73 -51
- package/src/adapters/postgres.ts +67 -42
- package/src/adapters/sqlite.ts +53 -34
- package/src/connection.ts +26 -16
- package/src/factory.ts +20 -16
- package/src/helpers.ts +78 -25
- package/src/index.ts +13 -10
- package/src/types.ts +31 -28
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { Kysely } from 'kysely';
|
|
2
|
+
import { Dialect, KyseraLogger } from '@kysera/core';
|
|
3
|
+
export { Dialect } from '@kysera/core';
|
|
2
4
|
|
|
3
5
|
/**
|
|
4
6
|
* @kysera/dialects - Type Definitions
|
|
@@ -6,10 +8,6 @@ import { Kysely } from 'kysely';
|
|
|
6
8
|
* Dialect-specific types and interfaces for database operations
|
|
7
9
|
*/
|
|
8
10
|
|
|
9
|
-
/**
|
|
10
|
-
* Supported database dialects
|
|
11
|
-
*/
|
|
12
|
-
type DatabaseDialect = 'postgres' | 'mysql' | 'sqlite';
|
|
13
11
|
/**
|
|
14
12
|
* Database connection configuration
|
|
15
13
|
*/
|
|
@@ -26,7 +24,7 @@ interface ConnectionConfig {
|
|
|
26
24
|
*/
|
|
27
25
|
interface DialectAdapter {
|
|
28
26
|
/** The dialect this adapter handles */
|
|
29
|
-
readonly dialect:
|
|
27
|
+
readonly dialect: Dialect;
|
|
30
28
|
/** Get default port for this dialect */
|
|
31
29
|
getDefaultPort(): number | null;
|
|
32
30
|
/** Get SQL expression for current timestamp */
|
|
@@ -49,8 +47,12 @@ interface DialectAdapter {
|
|
|
49
47
|
getTables(db: Kysely<any>): Promise<string[]>;
|
|
50
48
|
/** Get database size in bytes */
|
|
51
49
|
getDatabaseSize(db: Kysely<any>, databaseName?: string): Promise<number>;
|
|
52
|
-
/**
|
|
53
|
-
|
|
50
|
+
/**
|
|
51
|
+
* Truncate a single table
|
|
52
|
+
* @returns true if table was truncated, false if table does not exist
|
|
53
|
+
* @throws Error for other database errors
|
|
54
|
+
*/
|
|
55
|
+
truncateTable(db: Kysely<any>, tableName: string): Promise<boolean>;
|
|
54
56
|
/** Truncate all tables (for testing) */
|
|
55
57
|
truncateAllTables(db: Kysely<any>, exclude?: string[]): Promise<void>;
|
|
56
58
|
}
|
|
@@ -73,14 +75,14 @@ interface DatabaseErrorLike {
|
|
|
73
75
|
* const adapter = getAdapter('postgres');
|
|
74
76
|
* console.log(adapter.getDefaultPort()); // 5432
|
|
75
77
|
*/
|
|
76
|
-
declare function getAdapter(dialect:
|
|
78
|
+
declare function getAdapter(dialect: Dialect): DialectAdapter;
|
|
77
79
|
/**
|
|
78
80
|
* Create a new dialect adapter instance
|
|
79
81
|
*
|
|
80
82
|
* @example
|
|
81
83
|
* const adapter = createDialectAdapter('mysql');
|
|
82
84
|
*/
|
|
83
|
-
declare function createDialectAdapter(dialect:
|
|
85
|
+
declare function createDialectAdapter(dialect: Dialect): DialectAdapter;
|
|
84
86
|
/**
|
|
85
87
|
* Register a custom dialect adapter
|
|
86
88
|
*
|
|
@@ -95,6 +97,8 @@ declare function registerAdapter(adapter: DialectAdapter): void;
|
|
|
95
97
|
|
|
96
98
|
declare class PostgresAdapter implements DialectAdapter {
|
|
97
99
|
readonly dialect: "postgres";
|
|
100
|
+
private logger;
|
|
101
|
+
constructor(logger?: KyseraLogger);
|
|
98
102
|
getDefaultPort(): number;
|
|
99
103
|
getCurrentTimestamp(): string;
|
|
100
104
|
escapeIdentifier(identifier: string): string;
|
|
@@ -106,7 +110,7 @@ declare class PostgresAdapter implements DialectAdapter {
|
|
|
106
110
|
getTableColumns(db: Kysely<any>, tableName: string): Promise<string[]>;
|
|
107
111
|
getTables(db: Kysely<any>): Promise<string[]>;
|
|
108
112
|
getDatabaseSize(db: Kysely<any>, databaseName?: string): Promise<number>;
|
|
109
|
-
truncateTable(db: Kysely<any>, tableName: string): Promise<
|
|
113
|
+
truncateTable(db: Kysely<any>, tableName: string): Promise<boolean>;
|
|
110
114
|
truncateAllTables(db: Kysely<any>, exclude?: string[]): Promise<void>;
|
|
111
115
|
}
|
|
112
116
|
declare const postgresAdapter: PostgresAdapter;
|
|
@@ -117,6 +121,8 @@ declare const postgresAdapter: PostgresAdapter;
|
|
|
117
121
|
|
|
118
122
|
declare class MySQLAdapter implements DialectAdapter {
|
|
119
123
|
readonly dialect: "mysql";
|
|
124
|
+
private logger;
|
|
125
|
+
constructor(logger?: KyseraLogger);
|
|
120
126
|
getDefaultPort(): number;
|
|
121
127
|
getCurrentTimestamp(): string;
|
|
122
128
|
escapeIdentifier(identifier: string): string;
|
|
@@ -128,7 +134,7 @@ declare class MySQLAdapter implements DialectAdapter {
|
|
|
128
134
|
getTableColumns(db: Kysely<any>, tableName: string): Promise<string[]>;
|
|
129
135
|
getTables(db: Kysely<any>): Promise<string[]>;
|
|
130
136
|
getDatabaseSize(db: Kysely<any>, databaseName?: string): Promise<number>;
|
|
131
|
-
truncateTable(db: Kysely<any>, tableName: string): Promise<
|
|
137
|
+
truncateTable(db: Kysely<any>, tableName: string): Promise<boolean>;
|
|
132
138
|
truncateAllTables(db: Kysely<any>, exclude?: string[]): Promise<void>;
|
|
133
139
|
}
|
|
134
140
|
declare const mysqlAdapter: MySQLAdapter;
|
|
@@ -139,6 +145,8 @@ declare const mysqlAdapter: MySQLAdapter;
|
|
|
139
145
|
|
|
140
146
|
declare class SQLiteAdapter implements DialectAdapter {
|
|
141
147
|
readonly dialect: "sqlite";
|
|
148
|
+
private logger;
|
|
149
|
+
constructor(logger?: KyseraLogger);
|
|
142
150
|
getDefaultPort(): null;
|
|
143
151
|
getCurrentTimestamp(): string;
|
|
144
152
|
escapeIdentifier(identifier: string): string;
|
|
@@ -150,11 +158,35 @@ declare class SQLiteAdapter implements DialectAdapter {
|
|
|
150
158
|
getTableColumns(db: Kysely<any>, tableName: string): Promise<string[]>;
|
|
151
159
|
getTables(db: Kysely<any>): Promise<string[]>;
|
|
152
160
|
getDatabaseSize(_db: Kysely<any>, _databaseName?: string): Promise<number>;
|
|
153
|
-
truncateTable(db: Kysely<any>, tableName: string): Promise<
|
|
161
|
+
truncateTable(db: Kysely<any>, tableName: string): Promise<boolean>;
|
|
154
162
|
truncateAllTables(db: Kysely<any>, exclude?: string[]): Promise<void>;
|
|
155
163
|
}
|
|
156
164
|
declare const sqliteAdapter: SQLiteAdapter;
|
|
157
165
|
|
|
166
|
+
/**
|
|
167
|
+
* Microsoft SQL Server Dialect Adapter
|
|
168
|
+
*
|
|
169
|
+
* Supports SQL Server 2017+, Azure SQL Database, and Azure SQL Edge
|
|
170
|
+
*/
|
|
171
|
+
|
|
172
|
+
declare class MSSQLAdapter implements DialectAdapter {
|
|
173
|
+
readonly dialect: "mssql";
|
|
174
|
+
getDefaultPort(): number;
|
|
175
|
+
getCurrentTimestamp(): string;
|
|
176
|
+
escapeIdentifier(identifier: string): string;
|
|
177
|
+
formatDate(date: Date): string;
|
|
178
|
+
isUniqueConstraintError(error: unknown): boolean;
|
|
179
|
+
isForeignKeyError(error: unknown): boolean;
|
|
180
|
+
isNotNullError(error: unknown): boolean;
|
|
181
|
+
tableExists(db: Kysely<any>, tableName: string): Promise<boolean>;
|
|
182
|
+
getTableColumns(db: Kysely<any>, tableName: string): Promise<string[]>;
|
|
183
|
+
getTables(db: Kysely<any>): Promise<string[]>;
|
|
184
|
+
getDatabaseSize(db: Kysely<any>, _databaseName?: string): Promise<number>;
|
|
185
|
+
truncateTable(db: Kysely<any>, tableName: string): Promise<boolean>;
|
|
186
|
+
truncateAllTables(db: Kysely<any>, exclude?: string[]): Promise<void>;
|
|
187
|
+
}
|
|
188
|
+
declare const mssqlAdapter: MSSQLAdapter;
|
|
189
|
+
|
|
158
190
|
/**
|
|
159
191
|
* Connection URL utilities
|
|
160
192
|
*/
|
|
@@ -174,7 +206,7 @@ declare function parseConnectionUrl(url: string): ConnectionConfig;
|
|
|
174
206
|
* const url = buildConnectionUrl('postgres', { host: 'localhost', database: 'mydb' });
|
|
175
207
|
* // 'postgresql://localhost:5432/mydb'
|
|
176
208
|
*/
|
|
177
|
-
declare function buildConnectionUrl(dialect:
|
|
209
|
+
declare function buildConnectionUrl(dialect: Dialect, config: ConnectionConfig): string;
|
|
178
210
|
/**
|
|
179
211
|
* Get default port for a dialect
|
|
180
212
|
*
|
|
@@ -183,7 +215,7 @@ declare function buildConnectionUrl(dialect: DatabaseDialect, config: Connection
|
|
|
183
215
|
* getDefaultPort('mysql') // 3306
|
|
184
216
|
* getDefaultPort('sqlite') // null
|
|
185
217
|
*/
|
|
186
|
-
declare function getDefaultPort(dialect:
|
|
218
|
+
declare function getDefaultPort(dialect: Dialect): number | null;
|
|
187
219
|
|
|
188
220
|
/**
|
|
189
221
|
* Dialect Helper Functions
|
|
@@ -192,13 +224,40 @@ declare function getDefaultPort(dialect: DatabaseDialect): number | null;
|
|
|
192
224
|
* for backward compatibility with existing code.
|
|
193
225
|
*/
|
|
194
226
|
|
|
227
|
+
/**
|
|
228
|
+
* Validate a SQL identifier (table name, column name, etc.)
|
|
229
|
+
*
|
|
230
|
+
* @param name - The identifier to validate
|
|
231
|
+
* @returns true if the identifier is valid, false otherwise
|
|
232
|
+
*
|
|
233
|
+
* @example
|
|
234
|
+
* validateIdentifier('users') // true
|
|
235
|
+
* validateIdentifier('public.users') // true
|
|
236
|
+
* validateIdentifier('_private_table') // true
|
|
237
|
+
* validateIdentifier('123invalid') // false (starts with number)
|
|
238
|
+
* validateIdentifier('table-name') // false (contains hyphen)
|
|
239
|
+
* validateIdentifier('') // false (empty)
|
|
240
|
+
*/
|
|
241
|
+
declare function validateIdentifier(name: string): boolean;
|
|
242
|
+
/**
|
|
243
|
+
* Assert that an identifier is valid, throwing an error if not
|
|
244
|
+
*
|
|
245
|
+
* @param name - The identifier to validate
|
|
246
|
+
* @param context - Optional context for the error message (e.g., 'table name', 'column name')
|
|
247
|
+
* @throws Error if the identifier is invalid
|
|
248
|
+
*
|
|
249
|
+
* @example
|
|
250
|
+
* assertValidIdentifier('users', 'table name'); // passes
|
|
251
|
+
* assertValidIdentifier('123bad', 'table name'); // throws Error: Invalid table name: 123bad
|
|
252
|
+
*/
|
|
253
|
+
declare function assertValidIdentifier(name: string, context?: string): void;
|
|
195
254
|
/**
|
|
196
255
|
* Check if table exists in the database
|
|
197
256
|
*
|
|
198
257
|
* @example
|
|
199
258
|
* const exists = await tableExists(db, 'users', 'postgres');
|
|
200
259
|
*/
|
|
201
|
-
declare function tableExists(db: Kysely<any>, tableName: string, dialect:
|
|
260
|
+
declare function tableExists(db: Kysely<any>, tableName: string, dialect: Dialect): Promise<boolean>;
|
|
202
261
|
/**
|
|
203
262
|
* Get column names for a table
|
|
204
263
|
*
|
|
@@ -206,7 +265,7 @@ declare function tableExists(db: Kysely<any>, tableName: string, dialect: Databa
|
|
|
206
265
|
* const columns = await getTableColumns(db, 'users', 'postgres');
|
|
207
266
|
* // ['id', 'name', 'email', 'created_at']
|
|
208
267
|
*/
|
|
209
|
-
declare function getTableColumns(db: Kysely<any>, tableName: string, dialect:
|
|
268
|
+
declare function getTableColumns(db: Kysely<any>, tableName: string, dialect: Dialect): Promise<string[]>;
|
|
210
269
|
/**
|
|
211
270
|
* Get all tables in the database
|
|
212
271
|
*
|
|
@@ -214,7 +273,7 @@ declare function getTableColumns(db: Kysely<any>, tableName: string, dialect: Da
|
|
|
214
273
|
* const tables = await getTables(db, 'postgres');
|
|
215
274
|
* // ['users', 'posts', 'comments']
|
|
216
275
|
*/
|
|
217
|
-
declare function getTables(db: Kysely<any>, dialect:
|
|
276
|
+
declare function getTables(db: Kysely<any>, dialect: Dialect): Promise<string[]>;
|
|
218
277
|
/**
|
|
219
278
|
* Escape identifier for SQL (table names, column names, etc.)
|
|
220
279
|
*
|
|
@@ -222,7 +281,7 @@ declare function getTables(db: Kysely<any>, dialect: DatabaseDialect): Promise<s
|
|
|
222
281
|
* escapeIdentifier('my-table', 'postgres') // '"my-table"'
|
|
223
282
|
* escapeIdentifier('my-table', 'mysql') // '`my-table`'
|
|
224
283
|
*/
|
|
225
|
-
declare function escapeIdentifier(identifier: string, dialect:
|
|
284
|
+
declare function escapeIdentifier(identifier: string, dialect: Dialect): string;
|
|
226
285
|
/**
|
|
227
286
|
* Get SQL expression for current timestamp
|
|
228
287
|
*
|
|
@@ -230,7 +289,7 @@ declare function escapeIdentifier(identifier: string, dialect: DatabaseDialect):
|
|
|
230
289
|
* getCurrentTimestamp('postgres') // 'CURRENT_TIMESTAMP'
|
|
231
290
|
* getCurrentTimestamp('sqlite') // "datetime('now')"
|
|
232
291
|
*/
|
|
233
|
-
declare function getCurrentTimestamp(dialect:
|
|
292
|
+
declare function getCurrentTimestamp(dialect: Dialect): string;
|
|
234
293
|
/**
|
|
235
294
|
* Format date for database insertion
|
|
236
295
|
*
|
|
@@ -238,7 +297,7 @@ declare function getCurrentTimestamp(dialect: DatabaseDialect): string;
|
|
|
238
297
|
* formatDate(new Date(), 'postgres') // '2024-01-15T10:30:00.000Z'
|
|
239
298
|
* formatDate(new Date(), 'mysql') // '2024-01-15 10:30:00'
|
|
240
299
|
*/
|
|
241
|
-
declare function formatDate(date: Date, dialect:
|
|
300
|
+
declare function formatDate(date: Date, dialect: Dialect): string;
|
|
242
301
|
/**
|
|
243
302
|
* Check if error is a unique constraint violation
|
|
244
303
|
*
|
|
@@ -251,7 +310,7 @@ declare function formatDate(date: Date, dialect: DatabaseDialect): string;
|
|
|
251
310
|
* }
|
|
252
311
|
* }
|
|
253
312
|
*/
|
|
254
|
-
declare function isUniqueConstraintError(error: unknown, dialect:
|
|
313
|
+
declare function isUniqueConstraintError(error: unknown, dialect: Dialect): boolean;
|
|
255
314
|
/**
|
|
256
315
|
* Check if error is a foreign key constraint violation
|
|
257
316
|
*
|
|
@@ -260,7 +319,7 @@ declare function isUniqueConstraintError(error: unknown, dialect: DatabaseDialec
|
|
|
260
319
|
* console.log('Referenced row does not exist');
|
|
261
320
|
* }
|
|
262
321
|
*/
|
|
263
|
-
declare function isForeignKeyError(error: unknown, dialect:
|
|
322
|
+
declare function isForeignKeyError(error: unknown, dialect: Dialect): boolean;
|
|
264
323
|
/**
|
|
265
324
|
* Check if error is a not-null constraint violation
|
|
266
325
|
*
|
|
@@ -269,7 +328,7 @@ declare function isForeignKeyError(error: unknown, dialect: DatabaseDialect): bo
|
|
|
269
328
|
* console.log('Required field is missing');
|
|
270
329
|
* }
|
|
271
330
|
*/
|
|
272
|
-
declare function isNotNullError(error: unknown, dialect:
|
|
331
|
+
declare function isNotNullError(error: unknown, dialect: Dialect): boolean;
|
|
273
332
|
/**
|
|
274
333
|
* Get database size in bytes
|
|
275
334
|
*
|
|
@@ -277,7 +336,7 @@ declare function isNotNullError(error: unknown, dialect: DatabaseDialect): boole
|
|
|
277
336
|
* const size = await getDatabaseSize(db, 'postgres');
|
|
278
337
|
* console.log(`Database size: ${size} bytes`);
|
|
279
338
|
*/
|
|
280
|
-
declare function getDatabaseSize(db: Kysely<any>, dialect:
|
|
339
|
+
declare function getDatabaseSize(db: Kysely<any>, dialect: Dialect, databaseName?: string): Promise<number>;
|
|
281
340
|
/**
|
|
282
341
|
* Truncate all tables in the database (useful for testing)
|
|
283
342
|
*
|
|
@@ -285,6 +344,6 @@ declare function getDatabaseSize(db: Kysely<any>, dialect: DatabaseDialect, data
|
|
|
285
344
|
* // Truncate all tables except migrations
|
|
286
345
|
* await truncateAllTables(db, 'postgres', ['kysely_migrations']);
|
|
287
346
|
*/
|
|
288
|
-
declare function truncateAllTables(db: Kysely<any>, dialect:
|
|
347
|
+
declare function truncateAllTables(db: Kysely<any>, dialect: Dialect, exclude?: string[]): Promise<void>;
|
|
289
348
|
|
|
290
|
-
export { type ConnectionConfig, type
|
|
349
|
+
export { type ConnectionConfig, type DatabaseErrorLike, type DialectAdapter, MSSQLAdapter, MySQLAdapter, PostgresAdapter, SQLiteAdapter, assertValidIdentifier, buildConnectionUrl, createDialectAdapter, escapeIdentifier, formatDate, getAdapter, getCurrentTimestamp, getDatabaseSize, getDefaultPort, getTableColumns, getTables, isForeignKeyError, isNotNullError, isUniqueConstraintError, mssqlAdapter, mysqlAdapter, parseConnectionUrl, postgresAdapter, registerAdapter, sqliteAdapter, tableExists, truncateAllTables, validateIdentifier };
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
-
import {sql}from'kysely';var
|
|
2
|
-
|
|
1
|
+
import {sql}from'kysely';import {silentLogger}from'@kysera/core';var _=128,C=/^[a-zA-Z_][a-zA-Z0-9_.]*$/;function h(a){return !a||a.length>_?false:C.test(a)}function n(a,e="identifier"){if(!h(a))throw new Error(`Invalid ${e}: ${a}`)}async function x(a,e,t){return await o(t).tableExists(a,e)}async function S(a,e,t){return await o(t).getTableColumns(a,e)}async function K(a,e){return await o(e).getTables(a)}function k(a,e){return o(e).escapeIdentifier(a)}function I(a){return o(a).getCurrentTimestamp()}function q(a,e){return o(e).formatDate(a)}function P(a,e){return o(e).isUniqueConstraintError(a)}function R(a,e){return o(e).isForeignKeyError(a)}function M(a,e){return o(e).isNotNullError(a)}async function N(a,e,t){return await o(e).getDatabaseSize(a,t)}async function F(a,e,t=[]){await o(e).truncateAllTables(a,t);}var c=class{dialect="postgres";logger;constructor(e=silentLogger){this.logger=e;}getDefaultPort(){return 5432}getCurrentTimestamp(){return "CURRENT_TIMESTAMP"}escapeIdentifier(e){return '"'+e.replace(/"/g,'""')+'"'}formatDate(e){return e.toISOString()}isUniqueConstraintError(e){let t=e,r=t.message?.toLowerCase()||"";return (t.code||"")==="23505"||r.includes("unique constraint")}isForeignKeyError(e){let t=e,r=t.message?.toLowerCase()||"";return (t.code||"")==="23503"||r.includes("foreign key constraint")}isNotNullError(e){let t=e,r=t.message?.toLowerCase()||"";return (t.code||"")==="23502"||r.includes("not-null constraint")}async tableExists(e,t){n(t,"table name");try{return !!await e.selectFrom("information_schema.tables").select("table_name").where("table_name","=",t).where("table_schema","=","public").executeTakeFirst()}catch{return false}}async getTableColumns(e,t){n(t,"table name");try{return (await e.selectFrom("information_schema.columns").select("column_name").where("table_name","=",t).where("table_schema","=","public").execute()).map(s=>s.column_name)}catch{return []}}async getTables(e){try{return (await e.selectFrom("information_schema.tables").select("table_name").where("table_schema","=","public").where("table_type","=","BASE TABLE").execute()).map(r=>r.table_name)}catch{return []}}async getDatabaseSize(e,t){try{return (t?await sql`SELECT pg_database_size(${t}) as size`.execute(e):await sql`SELECT pg_database_size(current_database()) as size`.execute(e)).rows?.[0]?.size||0}catch{return 0}}async truncateTable(e,t){n(t,"table name");try{return await sql.raw(`TRUNCATE TABLE ${this.escapeIdentifier(t)} RESTART IDENTITY CASCADE`).execute(e),!0}catch(r){let s=String(r);if(s.includes("does not exist")||s.includes("relation")&&s.includes("not exist"))return false;throw this.logger.error(`Failed to truncate table "${t}":`,r),r}}async truncateAllTables(e,t=[]){let r=await this.getTables(e);for(let s of r)t.includes(s)||await this.truncateTable(e,s);}},d=new c;var u=class{dialect="mysql";logger;constructor(e=silentLogger){this.logger=e;}getDefaultPort(){return 3306}getCurrentTimestamp(){return "CURRENT_TIMESTAMP"}escapeIdentifier(e){return "`"+e.replace(/`/g,"``")+"`"}formatDate(e){return e.toISOString().slice(0,19).replace("T"," ")}isUniqueConstraintError(e){let t=e,r=t.message?.toLowerCase()||"",s=t.code||"";return s==="ER_DUP_ENTRY"||s==="1062"||r.includes("duplicate entry")}isForeignKeyError(e){let r=e.code||"";return r==="ER_ROW_IS_REFERENCED"||r==="1451"||r==="ER_NO_REFERENCED_ROW"||r==="1452"}isNotNullError(e){let r=e.code||"";return r==="ER_BAD_NULL_ERROR"||r==="1048"}async tableExists(e,t){n(t,"table name");try{return !!await e.selectFrom("information_schema.tables").select("table_name").where("table_name","=",t).where("table_schema","=",sql`DATABASE()`).executeTakeFirst()}catch{return false}}async getTableColumns(e,t){n(t,"table name");try{return (await e.selectFrom("information_schema.columns").select("column_name").where("table_name","=",t).where("table_schema","=",sql`DATABASE()`).execute()).map(s=>s.column_name)}catch{return []}}async getTables(e){try{return (await e.selectFrom("information_schema.tables").select("table_name").where("table_schema","=",sql`DATABASE()`).where("table_type","=","BASE TABLE").execute()).map(r=>r.table_name)}catch{return []}}async getDatabaseSize(e,t){try{let r=t||await sql`SELECT DATABASE() as name`.execute(e).then(l=>l.rows?.[0]?.name);return r&&(await sql`
|
|
2
|
+
SELECT SUM(data_length + index_length) as size
|
|
3
|
+
FROM information_schema.tables
|
|
4
|
+
WHERE table_schema = ${r}
|
|
5
|
+
`.execute(e)).rows?.[0]?.size||0}catch{return 0}}async truncateTable(e,t){n(t,"table name");try{await sql.raw("SET FOREIGN_KEY_CHECKS = 0").execute(e);try{return await sql.raw(`TRUNCATE TABLE ${this.escapeIdentifier(t)}`).execute(e),!0}finally{try{await sql.raw("SET FOREIGN_KEY_CHECKS = 1").execute(e);}catch(r){this.logger.error("Failed to re-enable foreign key checks:",r);}}}catch(r){let s=String(r);if(s.includes("doesn't exist")||s.includes("Unknown table"))return false;throw this.logger.error(`Failed to truncate table "${t}":`,r),r}}async truncateAllTables(e,t=[]){let r=await this.getTables(e);for(let s of r)t.includes(s)||await this.truncateTable(e,s);}},E=new u;var m=class{dialect="sqlite";logger;constructor(e=silentLogger){this.logger=e;}getDefaultPort(){return null}getCurrentTimestamp(){return "datetime('now')"}escapeIdentifier(e){return '"'+e.replace(/"/g,'""')+'"'}formatDate(e){return e.toISOString()}isUniqueConstraintError(e){return (e.message?.toLowerCase()||"").includes("unique constraint failed")}isForeignKeyError(e){return (e.message?.toLowerCase()||"").includes("foreign key constraint failed")}isNotNullError(e){return (e.message?.toLowerCase()||"").includes("not null constraint failed")}async tableExists(e,t){n(t,"table name");try{return !!await e.selectFrom("sqlite_master").select("name").where("type","=","table").where("name","=",t).executeTakeFirst()}catch{return false}}async getTableColumns(e,t){n(t,"table name");try{return (await sql.raw(`PRAGMA table_info(${this.escapeIdentifier(t)})`).execute(e)).rows.map(s=>s.name)}catch{return []}}async getTables(e){try{return (await e.selectFrom("sqlite_master").select("name").where("type","=","table").where("name","not like","sqlite_%").execute()).map(r=>r.name)}catch{return []}}async getDatabaseSize(e,t){return 0}async truncateTable(e,t){n(t,"table name");try{return await sql.raw(`DELETE FROM ${this.escapeIdentifier(t)}`).execute(e),!0}catch(r){if(String(r).includes("no such table"))return false;throw this.logger.error(`Failed to truncate table "${t}":`,r),r}}async truncateAllTables(e,t=[]){let r=await this.getTables(e);for(let s of r)t.includes(s)||await this.truncateTable(e,s);}},f=new m;var g=class{dialect="mssql";getDefaultPort(){return 1433}getCurrentTimestamp(){return "GETDATE()"}escapeIdentifier(e){return "["+e.replace(/\]/g,"]]")+"]"}formatDate(e){return e.toISOString().replace("T"," ").replace("Z","")}isUniqueConstraintError(e){let t=e,r=t.message?.toLowerCase()||"",s=t.code||"";return s==="2627"||s==="2601"||r.includes("violation of unique key constraint")||r.includes("cannot insert duplicate key")||r.includes("unique constraint")}isForeignKeyError(e){let t=e,r=t.message?.toLowerCase()||"";return (t.code||"")==="547"||r.includes("foreign key constraint")||r.includes("conflicted with the foreign key")}isNotNullError(e){let t=e,r=t.message?.toLowerCase()||"";return (t.code||"")==="515"||r.includes("cannot insert the value null")||r.includes("does not allow nulls")}async tableExists(e,t){n(t,"table name");try{return !!await e.selectFrom("INFORMATION_SCHEMA.TABLES").select("TABLE_NAME").where("TABLE_NAME","=",t).where("TABLE_TYPE","=","BASE TABLE").executeTakeFirst()}catch{return false}}async getTableColumns(e,t){n(t,"table name");try{return (await e.selectFrom("INFORMATION_SCHEMA.COLUMNS").select("COLUMN_NAME").where("TABLE_NAME","=",t).execute()).map(s=>s.COLUMN_NAME)}catch{return []}}async getTables(e){try{return (await e.selectFrom("INFORMATION_SCHEMA.TABLES").select("TABLE_NAME").where("TABLE_TYPE","=","BASE TABLE").where("TABLE_SCHEMA","=","dbo").execute()).map(r=>r.TABLE_NAME)}catch{return []}}async getDatabaseSize(e,t){try{return (await sql`
|
|
6
|
+
SELECT SUM(size * 8 * 1024) as size
|
|
7
|
+
FROM sys.database_files
|
|
8
|
+
WHERE type = 0
|
|
9
|
+
`.execute(e)).rows?.[0]?.size||0}catch{return 0}}async truncateTable(e,t){n(t,"table name");try{try{await sql.raw(`TRUNCATE TABLE ${this.escapeIdentifier(t)}`).execute(e);}catch(r){let s=String(r);if(s.includes("FOREIGN KEY")||s.includes("Cannot truncate")){await sql.raw(`DELETE FROM ${this.escapeIdentifier(t)}`).execute(e);try{let l=this.escapeIdentifier(t);await sql.raw(`DBCC CHECKIDENT (${l}, RESEED, 0)`).execute(e);}catch{}}else throw r}return !0}catch(r){let s=String(r);if(s.includes("Invalid object name")||s.includes("does not exist"))return false;throw new Error(`Failed to truncate MSSQL table "${t}": ${String(r)}`)}}async truncateAllTables(e,t=[]){let r=await this.getTables(e);for(let s of r)if(!t.includes(s))try{await sql.raw(`ALTER TABLE ${this.escapeIdentifier(s)} NOCHECK CONSTRAINT ALL`).execute(e);}catch{}for(let s of r)t.includes(s)||await this.truncateTable(e,s);for(let s of r)if(!t.includes(s))try{await sql.raw(`ALTER TABLE ${this.escapeIdentifier(s)} CHECK CONSTRAINT ALL`).execute(e);}catch{}}},b=new g;var L={postgres:d,mysql:E,sqlite:f,mssql:b};function o(a){let e=L[a];if(!e)throw new Error(`Unknown dialect: ${a}. Supported: postgres, mysql, sqlite, mssql`);return e}function U(a){switch(a){case "postgres":return new c;case "mysql":return new u;case "sqlite":return new m;case "mssql":return new g;default:throw new Error(`Unknown dialect: ${a}. Supported: postgres, mysql, sqlite, mssql`)}}function z(a){L[a.dialect]=a;}function v(a){let e=new URL(a);return {host:e.hostname,port:e.port?parseInt(e.port):void 0,database:e.pathname.slice(1),user:e.username||void 0,password:e.password||void 0,ssl:e.searchParams.get("ssl")==="true"||e.searchParams.get("sslmode")==="require"}}function H(a,e){let r={postgres:"postgresql",mysql:"mysql",sqlite:"sqlite",mssql:"mssql"}[a],s=e.user?e.password?`${e.user}:${e.password}@`:`${e.user}@`:"",l=e.host||"localhost",w=e.port||o(a).getDefaultPort(),A=e.database,T=w?`${r}://${s}${l}:${w}/${A}`:`${r}://${s}${l}/${A}`;return e.ssl&&(T+="?ssl=true"),T}function j(a){return o(a).getDefaultPort()}
|
|
10
|
+
export{g as MSSQLAdapter,u as MySQLAdapter,c as PostgresAdapter,m as SQLiteAdapter,n as assertValidIdentifier,H as buildConnectionUrl,U as createDialectAdapter,k as escapeIdentifier,q as formatDate,o as getAdapter,I as getCurrentTimestamp,N as getDatabaseSize,j as getDefaultPort,S as getTableColumns,K as getTables,R as isForeignKeyError,M as isNotNullError,P as isUniqueConstraintError,b as mssqlAdapter,E as mysqlAdapter,v as parseConnectionUrl,d as postgresAdapter,z as registerAdapter,f as sqliteAdapter,x as tableExists,F as truncateAllTables,h as validateIdentifier};//# sourceMappingURL=index.js.map
|
|
3
11
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/adapters/postgres.ts","../src/adapters/mysql.ts","../src/adapters/sqlite.ts","../src/factory.ts","../src/connection.ts","../src/helpers.ts"],"names":["PostgresAdapter","identifier","date","error","e","message","db","tableName","r","databaseName","sql","exclude","tables","table","postgresAdapter","MySQLAdapter","code","dbName","mysqlAdapter","SQLiteAdapter","_db","_databaseName","sqliteAdapter","adapters","getAdapter","dialect","adapter","createDialectAdapter","registerAdapter","parseConnectionUrl","url","parsed","buildConnectionUrl","config","protocol","auth","host","port","database","getDefaultPort","tableExists","getTableColumns","getTables","escapeIdentifier","getCurrentTimestamp","formatDate","isUniqueConstraintError","isForeignKeyError","isNotNullError","getDatabaseSize","truncateAllTables"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * PostgreSQL Dialect Adapter\n */\n\nimport type { Kysely } from 'kysely';\nimport { sql } from 'kysely';\nimport type { DialectAdapter, DatabaseErrorLike } from '../types.js';\n\nexport class PostgresAdapter implements DialectAdapter {\n readonly dialect = 'postgres' as const;\n\n getDefaultPort(): number {\n return 5432;\n }\n\n getCurrentTimestamp(): string {\n return 'CURRENT_TIMESTAMP';\n }\n\n escapeIdentifier(identifier: string): string {\n return `\"${identifier.replace(/\"/g, '\"\"')}\"`;\n }\n\n formatDate(date: Date): string {\n return date.toISOString();\n }\n\n isUniqueConstraintError(error: unknown): boolean {\n const e = error as DatabaseErrorLike;\n const message = e.message?.toLowerCase() || '';\n const code = e.code || '';\n return code === '23505' || message.includes('unique constraint');\n }\n\n isForeignKeyError(error: unknown): boolean {\n const e = error as DatabaseErrorLike;\n const message = e.message?.toLowerCase() || '';\n const code = e.code || '';\n return code === '23503' || message.includes('foreign key constraint');\n }\n\n isNotNullError(error: unknown): boolean {\n const e = error as DatabaseErrorLike;\n const message = e.message?.toLowerCase() || '';\n const code = e.code || '';\n return code === '23502' || message.includes('not-null constraint');\n }\n\n async tableExists(db: Kysely<any>, tableName: string): Promise<boolean> {\n try {\n const result = await db\n .selectFrom('information_schema.tables')\n .select('table_name')\n .where('table_name', '=', tableName)\n .where('table_schema', '=', 'public')\n .executeTakeFirst();\n return !!result;\n } catch {\n return false;\n }\n }\n\n async getTableColumns(db: Kysely<any>, tableName: string): Promise<string[]> {\n try {\n const results = await db\n .selectFrom('information_schema.columns')\n .select('column_name')\n .where('table_name', '=', tableName)\n .where('table_schema', '=', 'public')\n .execute();\n return results.map((r) => r.column_name as string);\n } catch {\n return [];\n }\n }\n\n async getTables(db: Kysely<any>): Promise<string[]> {\n try {\n const results = await db\n .selectFrom('information_schema.tables')\n .select('table_name')\n .where('table_schema', '=', 'public')\n .where('table_type', '=', 'BASE TABLE')\n .execute();\n return results.map((r) => r.table_name as string);\n } catch {\n return [];\n }\n }\n\n async getDatabaseSize(db: Kysely<any>, databaseName?: string): Promise<number> {\n try {\n const result = await sql\n .raw(`SELECT pg_database_size(${databaseName ? `'${databaseName}'` : 'current_database()'}) as size`)\n .execute(db)\n .then((r) => r.rows?.[0]);\n return (result as { size?: number })?.size || 0;\n } catch {\n return 0;\n }\n }\n\n async truncateTable(db: Kysely<any>, tableName: string): Promise<void> {\n try {\n await sql.raw(`TRUNCATE TABLE ${this.escapeIdentifier(tableName)} RESTART IDENTITY CASCADE`).execute(db);\n } catch {\n // Ignore errors for tables that might not exist or have constraints\n }\n }\n\n async truncateAllTables(db: Kysely<any>, exclude: string[] = []): Promise<void> {\n const tables = await this.getTables(db);\n for (const table of tables) {\n if (!exclude.includes(table)) {\n await this.truncateTable(db, table);\n }\n }\n }\n}\n\nexport const postgresAdapter = new PostgresAdapter();\n","/**\n * MySQL Dialect Adapter\n */\n\nimport type { Kysely } from 'kysely';\nimport { sql } from 'kysely';\nimport type { DialectAdapter, DatabaseErrorLike } from '../types.js';\n\nexport class MySQLAdapter implements DialectAdapter {\n readonly dialect = 'mysql' as const;\n\n getDefaultPort(): number {\n return 3306;\n }\n\n getCurrentTimestamp(): string {\n return 'CURRENT_TIMESTAMP';\n }\n\n escapeIdentifier(identifier: string): string {\n return `\\`${identifier.replace(/`/g, '``')}\\``;\n }\n\n formatDate(date: Date): string {\n // MySQL datetime format: YYYY-MM-DD HH:MM:SS\n return date.toISOString().slice(0, 19).replace('T', ' ');\n }\n\n isUniqueConstraintError(error: unknown): boolean {\n const e = error as DatabaseErrorLike;\n const message = e.message?.toLowerCase() || '';\n const code = e.code || '';\n return code === 'ER_DUP_ENTRY' || code === '1062' || message.includes('duplicate entry');\n }\n\n isForeignKeyError(error: unknown): boolean {\n const e = error as DatabaseErrorLike;\n const code = e.code || '';\n return (\n code === 'ER_ROW_IS_REFERENCED' ||\n code === '1451' ||\n code === 'ER_NO_REFERENCED_ROW' ||\n code === '1452'\n );\n }\n\n isNotNullError(error: unknown): boolean {\n const e = error as DatabaseErrorLike;\n const code = e.code || '';\n return code === 'ER_BAD_NULL_ERROR' || code === '1048';\n }\n\n async tableExists(db: Kysely<any>, tableName: string): Promise<boolean> {\n try {\n const result = await db\n .selectFrom('information_schema.tables')\n .select('table_name')\n .where('table_name', '=', tableName)\n .where('table_schema', '=', sql`DATABASE()`)\n .executeTakeFirst();\n return !!result;\n } catch {\n return false;\n }\n }\n\n async getTableColumns(db: Kysely<any>, tableName: string): Promise<string[]> {\n try {\n const results = await db\n .selectFrom('information_schema.columns')\n .select('column_name')\n .where('table_name', '=', tableName)\n .where('table_schema', '=', sql`DATABASE()`)\n .execute();\n return results.map((r) => r.column_name as string);\n } catch {\n return [];\n }\n }\n\n async getTables(db: Kysely<any>): Promise<string[]> {\n try {\n const results = await db\n .selectFrom('information_schema.tables')\n .select('table_name')\n .where('table_schema', '=', sql`DATABASE()`)\n .where('table_type', '=', 'BASE TABLE')\n .execute();\n return results.map((r) => r.table_name as string);\n } catch {\n return [];\n }\n }\n\n async getDatabaseSize(db: Kysely<any>, databaseName?: string): Promise<number> {\n try {\n const dbName =\n databaseName ||\n (await sql\n .raw('SELECT DATABASE() as name')\n .execute(db)\n .then((r) => (r.rows?.[0] as { name?: string })?.name));\n\n const result = await sql\n .raw(\n `SELECT SUM(data_length + index_length) as size FROM information_schema.tables WHERE table_schema = '${dbName}'`\n )\n .execute(db)\n .then((r) => r.rows?.[0]);\n\n return (result as { size?: number })?.size || 0;\n } catch {\n return 0;\n }\n }\n\n async truncateTable(db: Kysely<any>, tableName: string): Promise<void> {\n try {\n // Temporarily disable foreign key checks\n await sql.raw('SET FOREIGN_KEY_CHECKS = 0').execute(db);\n await sql.raw(`TRUNCATE TABLE ${this.escapeIdentifier(tableName)}`).execute(db);\n await sql.raw('SET FOREIGN_KEY_CHECKS = 1').execute(db);\n } catch {\n // Re-enable foreign key checks even on error\n try {\n await sql.raw('SET FOREIGN_KEY_CHECKS = 1').execute(db);\n } catch {\n // Ignore\n }\n }\n }\n\n async truncateAllTables(db: Kysely<any>, exclude: string[] = []): Promise<void> {\n const tables = await this.getTables(db);\n for (const table of tables) {\n if (!exclude.includes(table)) {\n await this.truncateTable(db, table);\n }\n }\n }\n}\n\nexport const mysqlAdapter = new MySQLAdapter();\n","/**\n * SQLite Dialect Adapter\n */\n\nimport type { Kysely } from 'kysely';\nimport { sql } from 'kysely';\nimport type { DialectAdapter, DatabaseErrorLike } from '../types.js';\n\nexport class SQLiteAdapter implements DialectAdapter {\n readonly dialect = 'sqlite' as const;\n\n getDefaultPort(): null {\n // SQLite is file-based, no port\n return null;\n }\n\n getCurrentTimestamp(): string {\n return \"datetime('now')\";\n }\n\n escapeIdentifier(identifier: string): string {\n return `\"${identifier.replace(/\"/g, '\"\"')}\"`;\n }\n\n formatDate(date: Date): string {\n return date.toISOString();\n }\n\n isUniqueConstraintError(error: unknown): boolean {\n const e = error as DatabaseErrorLike;\n const message = e.message?.toLowerCase() || '';\n return message.includes('unique constraint failed');\n }\n\n isForeignKeyError(error: unknown): boolean {\n const e = error as DatabaseErrorLike;\n const message = e.message?.toLowerCase() || '';\n return message.includes('foreign key constraint failed');\n }\n\n isNotNullError(error: unknown): boolean {\n const e = error as DatabaseErrorLike;\n const message = e.message?.toLowerCase() || '';\n return message.includes('not null constraint failed');\n }\n\n async tableExists(db: Kysely<any>, tableName: string): Promise<boolean> {\n try {\n const result = await db\n .selectFrom('sqlite_master')\n .select('name')\n .where('type', '=', 'table')\n .where('name', '=', tableName)\n .executeTakeFirst();\n return !!result;\n } catch {\n return false;\n }\n }\n\n async getTableColumns(db: Kysely<any>, tableName: string): Promise<string[]> {\n try {\n const results = await sql.raw(`PRAGMA table_info(${tableName})`).execute(db);\n return (results.rows as Array<{ name: string }>).map((r) => r.name);\n } catch {\n return [];\n }\n }\n\n async getTables(db: Kysely<any>): Promise<string[]> {\n try {\n const results = await db\n .selectFrom('sqlite_master')\n .select('name')\n .where('type', '=', 'table')\n .where('name', 'not like', 'sqlite_%')\n .execute();\n return results.map((r) => r.name as string);\n } catch {\n return [];\n }\n }\n\n async getDatabaseSize(_db: Kysely<any>, _databaseName?: string): Promise<number> {\n // SQLite database size requires file system access\n // which is not available in a cross-runtime way\n return 0;\n }\n\n async truncateTable(db: Kysely<any>, tableName: string): Promise<void> {\n try {\n // SQLite doesn't support TRUNCATE, use DELETE instead\n await db.deleteFrom(tableName as any).execute();\n } catch {\n // Ignore errors for tables that might not exist\n }\n }\n\n async truncateAllTables(db: Kysely<any>, exclude: string[] = []): Promise<void> {\n const tables = await this.getTables(db);\n for (const table of tables) {\n if (!exclude.includes(table)) {\n await this.truncateTable(db, table);\n }\n }\n }\n}\n\nexport const sqliteAdapter = new SQLiteAdapter();\n","/**\n * Dialect Adapter Factory\n */\n\nimport type { DatabaseDialect, DialectAdapter } from './types.js';\nimport { PostgresAdapter, postgresAdapter } from './adapters/postgres.js';\nimport { MySQLAdapter, mysqlAdapter } from './adapters/mysql.js';\nimport { SQLiteAdapter, sqliteAdapter } from './adapters/sqlite.js';\n\nconst adapters: Record<DatabaseDialect, DialectAdapter> = {\n postgres: postgresAdapter,\n mysql: mysqlAdapter,\n sqlite: sqliteAdapter,\n};\n\n/**\n * Get a dialect adapter for the specified dialect\n *\n * @example\n * const adapter = getAdapter('postgres');\n * console.log(adapter.getDefaultPort()); // 5432\n */\nexport function getAdapter(dialect: DatabaseDialect): DialectAdapter {\n const adapter = adapters[dialect];\n if (!adapter) {\n throw new Error(`Unknown dialect: ${dialect}. Supported: postgres, mysql, sqlite`);\n }\n return adapter;\n}\n\n/**\n * Create a new dialect adapter instance\n *\n * @example\n * const adapter = createDialectAdapter('mysql');\n */\nexport function createDialectAdapter(dialect: DatabaseDialect): DialectAdapter {\n switch (dialect) {\n case 'postgres':\n return new PostgresAdapter();\n case 'mysql':\n return new MySQLAdapter();\n case 'sqlite':\n return new SQLiteAdapter();\n default:\n throw new Error(`Unknown dialect: ${dialect}. Supported: postgres, mysql, sqlite`);\n }\n}\n\n/**\n * Register a custom dialect adapter\n *\n * @example\n * registerAdapter(customAdapter);\n */\nexport function registerAdapter(adapter: DialectAdapter): void {\n adapters[adapter.dialect] = adapter;\n}\n","/**\n * Connection URL utilities\n */\n\nimport type { DatabaseDialect, ConnectionConfig } from './types.js';\nimport { getAdapter } from './factory.js';\n\n/**\n * Parse database connection URL into ConnectionConfig\n *\n * @example\n * const config = parseConnectionUrl('postgresql://user:pass@localhost:5432/mydb?ssl=true');\n * // { host: 'localhost', port: 5432, database: 'mydb', user: 'user', password: 'pass', ssl: true }\n */\nexport function parseConnectionUrl(url: string): ConnectionConfig {\n const parsed = new URL(url);\n\n return {\n host: parsed.hostname,\n port: parsed.port ? parseInt(parsed.port) : undefined,\n database: parsed.pathname.slice(1),\n user: parsed.username || undefined,\n password: parsed.password || undefined,\n ssl: parsed.searchParams.get('ssl') === 'true' || parsed.searchParams.get('sslmode') === 'require',\n };\n}\n\n/**\n * Build connection URL from config\n *\n * @example\n * const url = buildConnectionUrl('postgres', { host: 'localhost', database: 'mydb' });\n * // 'postgresql://localhost:5432/mydb'\n */\nexport function buildConnectionUrl(dialect: DatabaseDialect, config: ConnectionConfig): string {\n const protocol = dialect === 'postgres' ? 'postgresql' : dialect;\n const auth = config.user\n ? config.password\n ? `${config.user}:${config.password}@`\n : `${config.user}@`\n : '';\n\n const host = config.host || 'localhost';\n const port = config.port || getAdapter(dialect).getDefaultPort();\n const database = config.database;\n\n let url = port ? `${protocol}://${auth}${host}:${port}/${database}` : `${protocol}://${auth}${host}/${database}`;\n\n if (config.ssl) {\n url += '?ssl=true';\n }\n\n return url;\n}\n\n/**\n * Get default port for a dialect\n *\n * @example\n * getDefaultPort('postgres') // 5432\n * getDefaultPort('mysql') // 3306\n * getDefaultPort('sqlite') // null\n */\nexport function getDefaultPort(dialect: DatabaseDialect): number | null {\n return getAdapter(dialect).getDefaultPort();\n}\n","/**\n * Dialect Helper Functions\n *\n * Standalone helper functions that accept dialect as parameter\n * for backward compatibility with existing code.\n */\n\nimport type { Kysely } from 'kysely';\nimport type { DatabaseDialect } from './types.js';\nimport { getAdapter } from './factory.js';\n\n/**\n * Check if table exists in the database\n *\n * @example\n * const exists = await tableExists(db, 'users', 'postgres');\n */\nexport async function tableExists(db: Kysely<any>, tableName: string, dialect: DatabaseDialect): Promise<boolean> {\n return getAdapter(dialect).tableExists(db, tableName);\n}\n\n/**\n * Get column names for a table\n *\n * @example\n * const columns = await getTableColumns(db, 'users', 'postgres');\n * // ['id', 'name', 'email', 'created_at']\n */\nexport async function getTableColumns(\n db: Kysely<any>,\n tableName: string,\n dialect: DatabaseDialect\n): Promise<string[]> {\n return getAdapter(dialect).getTableColumns(db, tableName);\n}\n\n/**\n * Get all tables in the database\n *\n * @example\n * const tables = await getTables(db, 'postgres');\n * // ['users', 'posts', 'comments']\n */\nexport async function getTables(db: Kysely<any>, dialect: DatabaseDialect): Promise<string[]> {\n return getAdapter(dialect).getTables(db);\n}\n\n/**\n * Escape identifier for SQL (table names, column names, etc.)\n *\n * @example\n * escapeIdentifier('my-table', 'postgres') // '\"my-table\"'\n * escapeIdentifier('my-table', 'mysql') // '`my-table`'\n */\nexport function escapeIdentifier(identifier: string, dialect: DatabaseDialect): string {\n return getAdapter(dialect).escapeIdentifier(identifier);\n}\n\n/**\n * Get SQL expression for current timestamp\n *\n * @example\n * getCurrentTimestamp('postgres') // 'CURRENT_TIMESTAMP'\n * getCurrentTimestamp('sqlite') // \"datetime('now')\"\n */\nexport function getCurrentTimestamp(dialect: DatabaseDialect): string {\n return getAdapter(dialect).getCurrentTimestamp();\n}\n\n/**\n * Format date for database insertion\n *\n * @example\n * formatDate(new Date(), 'postgres') // '2024-01-15T10:30:00.000Z'\n * formatDate(new Date(), 'mysql') // '2024-01-15 10:30:00'\n */\nexport function formatDate(date: Date, dialect: DatabaseDialect): string {\n return getAdapter(dialect).formatDate(date);\n}\n\n/**\n * Check if error is a unique constraint violation\n *\n * @example\n * try {\n * await db.insertInto('users').values({ email: 'duplicate@example.com' }).execute();\n * } catch (error) {\n * if (isUniqueConstraintError(error, 'postgres')) {\n * console.log('Email already exists');\n * }\n * }\n */\nexport function isUniqueConstraintError(error: unknown, dialect: DatabaseDialect): boolean {\n return getAdapter(dialect).isUniqueConstraintError(error);\n}\n\n/**\n * Check if error is a foreign key constraint violation\n *\n * @example\n * if (isForeignKeyError(error, 'mysql')) {\n * console.log('Referenced row does not exist');\n * }\n */\nexport function isForeignKeyError(error: unknown, dialect: DatabaseDialect): boolean {\n return getAdapter(dialect).isForeignKeyError(error);\n}\n\n/**\n * Check if error is a not-null constraint violation\n *\n * @example\n * if (isNotNullError(error, 'sqlite')) {\n * console.log('Required field is missing');\n * }\n */\nexport function isNotNullError(error: unknown, dialect: DatabaseDialect): boolean {\n return getAdapter(dialect).isNotNullError(error);\n}\n\n/**\n * Get database size in bytes\n *\n * @example\n * const size = await getDatabaseSize(db, 'postgres');\n * console.log(`Database size: ${size} bytes`);\n */\nexport async function getDatabaseSize(\n db: Kysely<any>,\n dialect: DatabaseDialect,\n databaseName?: string\n): Promise<number> {\n return getAdapter(dialect).getDatabaseSize(db, databaseName);\n}\n\n/**\n * Truncate all tables in the database (useful for testing)\n *\n * @example\n * // Truncate all tables except migrations\n * await truncateAllTables(db, 'postgres', ['kysely_migrations']);\n */\nexport async function truncateAllTables(\n db: Kysely<any>,\n dialect: DatabaseDialect,\n exclude: string[] = []\n): Promise<void> {\n return getAdapter(dialect).truncateAllTables(db, exclude);\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/helpers.ts","../src/adapters/postgres.ts","../src/adapters/mysql.ts","../src/adapters/sqlite.ts","../src/adapters/mssql.ts","../src/factory.ts","../src/connection.ts"],"names":["MAX_IDENTIFIER_LENGTH","IDENTIFIER_PATTERN","validateIdentifier","name","assertValidIdentifier","context","tableExists","db","tableName","dialect","getAdapter","getTableColumns","getTables","escapeIdentifier","identifier","getCurrentTimestamp","formatDate","date","isUniqueConstraintError","error","isForeignKeyError","isNotNullError","getDatabaseSize","databaseName","truncateAllTables","exclude","PostgresAdapter","logger","silentLogger","e","message","r","sql","errorMessage","tables","table","postgresAdapter","MySQLAdapter","code","dbName","fkError","mysqlAdapter","SQLiteAdapter","_db","_databaseName","sqliteAdapter","MSSQLAdapter","truncateError","errorMsg","escapedTableName","mssqlAdapter","adapters","adapter","createDialectAdapter","registerAdapter","parseConnectionUrl","url","parsed","buildConnectionUrl","config","protocol","auth","host","port","database","getDefaultPort"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Dialect Helper Functions\n *\n * Standalone helper functions that accept dialect as parameter\n * for backward compatibility with existing code.\n */\n\nimport type { Kysely } from 'kysely'\nimport type { Dialect } from './types.js'\nimport { getAdapter } from './factory.js'\n\n/**\n * Maximum allowed length for SQL identifiers\n */\nconst MAX_IDENTIFIER_LENGTH = 128\n\n/**\n * Pattern for valid SQL identifiers\n * Allows alphanumeric, underscore, and dot for schema.table notation\n */\nconst IDENTIFIER_PATTERN = /^[a-zA-Z_][a-zA-Z0-9_.]*$/\n\n/**\n * Validate a SQL identifier (table name, column name, etc.)\n *\n * @param name - The identifier to validate\n * @returns true if the identifier is valid, false otherwise\n *\n * @example\n * validateIdentifier('users') // true\n * validateIdentifier('public.users') // true\n * validateIdentifier('_private_table') // true\n * validateIdentifier('123invalid') // false (starts with number)\n * validateIdentifier('table-name') // false (contains hyphen)\n * validateIdentifier('') // false (empty)\n */\nexport function validateIdentifier(name: string): boolean {\n if (!name || name.length > MAX_IDENTIFIER_LENGTH) {\n return false\n }\n return IDENTIFIER_PATTERN.test(name)\n}\n\n/**\n * Assert that an identifier is valid, throwing an error if not\n *\n * @param name - The identifier to validate\n * @param context - Optional context for the error message (e.g., 'table name', 'column name')\n * @throws Error if the identifier is invalid\n *\n * @example\n * assertValidIdentifier('users', 'table name'); // passes\n * assertValidIdentifier('123bad', 'table name'); // throws Error: Invalid table name: 123bad\n */\nexport function assertValidIdentifier(name: string, context = 'identifier'): void {\n if (!validateIdentifier(name)) {\n throw new Error(`Invalid ${context}: ${name}`)\n }\n}\n\n/**\n * Check if table exists in the database\n *\n * @example\n * const exists = await tableExists(db, 'users', 'postgres');\n */\nexport async function tableExists(\n db: Kysely<any>,\n tableName: string,\n dialect: Dialect\n): Promise<boolean> {\n return await getAdapter(dialect).tableExists(db, tableName)\n}\n\n/**\n * Get column names for a table\n *\n * @example\n * const columns = await getTableColumns(db, 'users', 'postgres');\n * // ['id', 'name', 'email', 'created_at']\n */\nexport async function getTableColumns(\n db: Kysely<any>,\n tableName: string,\n dialect: Dialect\n): Promise<string[]> {\n return await getAdapter(dialect).getTableColumns(db, tableName)\n}\n\n/**\n * Get all tables in the database\n *\n * @example\n * const tables = await getTables(db, 'postgres');\n * // ['users', 'posts', 'comments']\n */\nexport async function getTables(db: Kysely<any>, dialect: Dialect): Promise<string[]> {\n return await getAdapter(dialect).getTables(db)\n}\n\n/**\n * Escape identifier for SQL (table names, column names, etc.)\n *\n * @example\n * escapeIdentifier('my-table', 'postgres') // '\"my-table\"'\n * escapeIdentifier('my-table', 'mysql') // '`my-table`'\n */\nexport function escapeIdentifier(identifier: string, dialect: Dialect): string {\n return getAdapter(dialect).escapeIdentifier(identifier)\n}\n\n/**\n * Get SQL expression for current timestamp\n *\n * @example\n * getCurrentTimestamp('postgres') // 'CURRENT_TIMESTAMP'\n * getCurrentTimestamp('sqlite') // \"datetime('now')\"\n */\nexport function getCurrentTimestamp(dialect: Dialect): string {\n return getAdapter(dialect).getCurrentTimestamp()\n}\n\n/**\n * Format date for database insertion\n *\n * @example\n * formatDate(new Date(), 'postgres') // '2024-01-15T10:30:00.000Z'\n * formatDate(new Date(), 'mysql') // '2024-01-15 10:30:00'\n */\nexport function formatDate(date: Date, dialect: Dialect): string {\n return getAdapter(dialect).formatDate(date)\n}\n\n/**\n * Check if error is a unique constraint violation\n *\n * @example\n * try {\n * await db.insertInto('users').values({ email: 'duplicate@example.com' }).execute();\n * } catch (error) {\n * if (isUniqueConstraintError(error, 'postgres')) {\n * console.log('Email already exists');\n * }\n * }\n */\nexport function isUniqueConstraintError(error: unknown, dialect: Dialect): boolean {\n return getAdapter(dialect).isUniqueConstraintError(error)\n}\n\n/**\n * Check if error is a foreign key constraint violation\n *\n * @example\n * if (isForeignKeyError(error, 'mysql')) {\n * console.log('Referenced row does not exist');\n * }\n */\nexport function isForeignKeyError(error: unknown, dialect: Dialect): boolean {\n return getAdapter(dialect).isForeignKeyError(error)\n}\n\n/**\n * Check if error is a not-null constraint violation\n *\n * @example\n * if (isNotNullError(error, 'sqlite')) {\n * console.log('Required field is missing');\n * }\n */\nexport function isNotNullError(error: unknown, dialect: Dialect): boolean {\n return getAdapter(dialect).isNotNullError(error)\n}\n\n/**\n * Get database size in bytes\n *\n * @example\n * const size = await getDatabaseSize(db, 'postgres');\n * console.log(`Database size: ${size} bytes`);\n */\nexport async function getDatabaseSize(\n db: Kysely<any>,\n dialect: Dialect,\n databaseName?: string\n): Promise<number> {\n return await getAdapter(dialect).getDatabaseSize(db, databaseName)\n}\n\n/**\n * Truncate all tables in the database (useful for testing)\n *\n * @example\n * // Truncate all tables except migrations\n * await truncateAllTables(db, 'postgres', ['kysely_migrations']);\n */\nexport async function truncateAllTables(\n db: Kysely<any>,\n dialect: Dialect,\n exclude: string[] = []\n): Promise<void> {\n await getAdapter(dialect).truncateAllTables(db, exclude)\n}\n","/**\n * PostgreSQL Dialect Adapter\n */\n\nimport type { Kysely } from 'kysely'\nimport { sql } from 'kysely'\nimport { silentLogger, type KyseraLogger } from '@kysera/core'\nimport type { DialectAdapter, DatabaseErrorLike } from '../types.js'\nimport { assertValidIdentifier } from '../helpers.js'\n\nexport class PostgresAdapter implements DialectAdapter {\n readonly dialect = 'postgres' as const\n private logger: KyseraLogger\n\n constructor(logger: KyseraLogger = silentLogger) {\n this.logger = logger\n }\n\n getDefaultPort(): number {\n return 5432\n }\n\n getCurrentTimestamp(): string {\n return 'CURRENT_TIMESTAMP'\n }\n\n escapeIdentifier(identifier: string): string {\n return '\"' + identifier.replace(/\"/g, '\"\"') + '\"'\n }\n\n formatDate(date: Date): string {\n return date.toISOString()\n }\n\n isUniqueConstraintError(error: unknown): boolean {\n const e = error as DatabaseErrorLike\n const message = e.message?.toLowerCase() || ''\n const code = e.code || ''\n return code === '23505' || message.includes('unique constraint')\n }\n\n isForeignKeyError(error: unknown): boolean {\n const e = error as DatabaseErrorLike\n const message = e.message?.toLowerCase() || ''\n const code = e.code || ''\n return code === '23503' || message.includes('foreign key constraint')\n }\n\n isNotNullError(error: unknown): boolean {\n const e = error as DatabaseErrorLike\n const message = e.message?.toLowerCase() || ''\n const code = e.code || ''\n return code === '23502' || message.includes('not-null constraint')\n }\n\n async tableExists(db: Kysely<any>, tableName: string): Promise<boolean> {\n assertValidIdentifier(tableName, 'table name')\n try {\n const result = await db\n .selectFrom('information_schema.tables')\n .select('table_name')\n .where('table_name', '=', tableName)\n .where('table_schema', '=', 'public')\n .executeTakeFirst()\n return !!result\n } catch {\n return false\n }\n }\n\n async getTableColumns(db: Kysely<any>, tableName: string): Promise<string[]> {\n assertValidIdentifier(tableName, 'table name')\n try {\n const results = await db\n .selectFrom('information_schema.columns')\n .select('column_name')\n .where('table_name', '=', tableName)\n .where('table_schema', '=', 'public')\n .execute()\n return results.map(r => r.column_name as string)\n } catch {\n return []\n }\n }\n\n async getTables(db: Kysely<any>): Promise<string[]> {\n try {\n const results = await db\n .selectFrom('information_schema.tables')\n .select('table_name')\n .where('table_schema', '=', 'public')\n .where('table_type', '=', 'BASE TABLE')\n .execute()\n return results.map(r => r.table_name as string)\n } catch {\n return []\n }\n }\n\n async getDatabaseSize(db: Kysely<any>, databaseName?: string): Promise<number> {\n try {\n // Use parameterized query to prevent SQL injection\n const result = databaseName\n ? await sql<{ size: number }>`SELECT pg_database_size(${databaseName}) as size`.execute(db)\n : await sql<{ size: number }>`SELECT pg_database_size(current_database()) as size`.execute(\n db\n )\n return (result.rows?.[0] as { size?: number })?.size || 0\n } catch {\n return 0\n }\n }\n\n async truncateTable(db: Kysely<any>, tableName: string): Promise<boolean> {\n assertValidIdentifier(tableName, 'table name')\n try {\n await sql\n .raw(`TRUNCATE TABLE ${this.escapeIdentifier(tableName)} RESTART IDENTITY CASCADE`)\n .execute(db)\n return true\n } catch (error) {\n // Only ignore \"table does not exist\" errors\n const errorMessage = String(error)\n if (\n errorMessage.includes('does not exist') ||\n (errorMessage.includes('relation') && errorMessage.includes('not exist'))\n ) {\n return false\n }\n // Log and rethrow unexpected errors\n this.logger.error(`Failed to truncate table \"${tableName}\":`, error)\n throw error\n }\n }\n\n async truncateAllTables(db: Kysely<any>, exclude: string[] = []): Promise<void> {\n const tables = await this.getTables(db)\n for (const table of tables) {\n if (!exclude.includes(table)) {\n await this.truncateTable(db, table)\n }\n }\n }\n}\n\nexport const postgresAdapter = new PostgresAdapter()\n","/**\n * MySQL Dialect Adapter\n */\n\nimport type { Kysely } from 'kysely'\nimport { sql } from 'kysely'\nimport { silentLogger, type KyseraLogger } from '@kysera/core'\nimport type { DialectAdapter, DatabaseErrorLike } from '../types.js'\nimport { assertValidIdentifier } from '../helpers.js'\n\nexport class MySQLAdapter implements DialectAdapter {\n readonly dialect = 'mysql' as const\n private logger: KyseraLogger\n\n constructor(logger: KyseraLogger = silentLogger) {\n this.logger = logger\n }\n\n getDefaultPort(): number {\n return 3306\n }\n\n getCurrentTimestamp(): string {\n return 'CURRENT_TIMESTAMP'\n }\n\n escapeIdentifier(identifier: string): string {\n return '`' + identifier.replace(/`/g, '``') + '`'\n }\n\n formatDate(date: Date): string {\n // MySQL datetime format: YYYY-MM-DD HH:MM:SS\n return date.toISOString().slice(0, 19).replace('T', ' ')\n }\n\n isUniqueConstraintError(error: unknown): boolean {\n const e = error as DatabaseErrorLike\n const message = e.message?.toLowerCase() || ''\n const code = e.code || ''\n return code === 'ER_DUP_ENTRY' || code === '1062' || message.includes('duplicate entry')\n }\n\n isForeignKeyError(error: unknown): boolean {\n const e = error as DatabaseErrorLike\n const code = e.code || ''\n return (\n code === 'ER_ROW_IS_REFERENCED' ||\n code === '1451' ||\n code === 'ER_NO_REFERENCED_ROW' ||\n code === '1452'\n )\n }\n\n isNotNullError(error: unknown): boolean {\n const e = error as DatabaseErrorLike\n const code = e.code || ''\n return code === 'ER_BAD_NULL_ERROR' || code === '1048'\n }\n\n async tableExists(db: Kysely<any>, tableName: string): Promise<boolean> {\n assertValidIdentifier(tableName, 'table name')\n try {\n const result = await db\n .selectFrom('information_schema.tables')\n .select('table_name')\n .where('table_name', '=', tableName)\n .where('table_schema', '=', sql`DATABASE()`)\n .executeTakeFirst()\n return !!result\n } catch {\n return false\n }\n }\n\n async getTableColumns(db: Kysely<any>, tableName: string): Promise<string[]> {\n assertValidIdentifier(tableName, 'table name')\n try {\n const results = await db\n .selectFrom('information_schema.columns')\n .select('column_name')\n .where('table_name', '=', tableName)\n .where('table_schema', '=', sql`DATABASE()`)\n .execute()\n return results.map(r => r.column_name as string)\n } catch {\n return []\n }\n }\n\n async getTables(db: Kysely<any>): Promise<string[]> {\n try {\n const results = await db\n .selectFrom('information_schema.tables')\n .select('table_name')\n .where('table_schema', '=', sql`DATABASE()`)\n .where('table_type', '=', 'BASE TABLE')\n .execute()\n return results.map(r => r.table_name as string)\n } catch {\n return []\n }\n }\n\n async getDatabaseSize(db: Kysely<any>, databaseName?: string): Promise<number> {\n try {\n const dbName =\n databaseName ||\n (await sql<{ name: string }>`SELECT DATABASE() as name`\n .execute(db)\n .then(r => r.rows?.[0]?.name))\n\n if (!dbName) {\n return 0\n }\n\n // Use parameterized query to prevent SQL injection\n const result = await sql<{ size: number }>`\n SELECT SUM(data_length + index_length) as size\n FROM information_schema.tables\n WHERE table_schema = ${dbName}\n `.execute(db)\n\n return (result.rows?.[0] as { size?: number })?.size || 0\n } catch {\n return 0\n }\n }\n\n async truncateTable(db: Kysely<any>, tableName: string): Promise<boolean> {\n assertValidIdentifier(tableName, 'table name')\n try {\n await sql.raw('SET FOREIGN_KEY_CHECKS = 0').execute(db)\n try {\n await sql.raw(`TRUNCATE TABLE ${this.escapeIdentifier(tableName)}`).execute(db)\n return true\n } finally {\n // Always try to re-enable FK checks\n try {\n await sql.raw('SET FOREIGN_KEY_CHECKS = 1').execute(db)\n } catch (fkError) {\n this.logger.error('Failed to re-enable foreign key checks:', fkError)\n }\n }\n } catch (error) {\n const errorMessage = String(error)\n if (errorMessage.includes(\"doesn't exist\") || errorMessage.includes('Unknown table')) {\n return false\n }\n // Log and rethrow unexpected errors\n this.logger.error(`Failed to truncate table \"${tableName}\":`, error)\n throw error\n }\n }\n\n async truncateAllTables(db: Kysely<any>, exclude: string[] = []): Promise<void> {\n const tables = await this.getTables(db)\n for (const table of tables) {\n if (!exclude.includes(table)) {\n await this.truncateTable(db, table)\n }\n }\n }\n}\n\nexport const mysqlAdapter = new MySQLAdapter()\n","/**\n * SQLite Dialect Adapter\n */\n\nimport type { Kysely } from 'kysely'\nimport { sql } from 'kysely'\nimport { silentLogger, type KyseraLogger } from '@kysera/core'\nimport type { DialectAdapter, DatabaseErrorLike } from '../types.js'\nimport { assertValidIdentifier } from '../helpers.js'\n\nexport class SQLiteAdapter implements DialectAdapter {\n readonly dialect = 'sqlite' as const\n private logger: KyseraLogger\n\n constructor(logger: KyseraLogger = silentLogger) {\n this.logger = logger\n }\n\n getDefaultPort(): null {\n // SQLite is file-based, no port\n return null\n }\n\n getCurrentTimestamp(): string {\n return \"datetime('now')\"\n }\n\n escapeIdentifier(identifier: string): string {\n return '\"' + identifier.replace(/\"/g, '\"\"') + '\"'\n }\n\n formatDate(date: Date): string {\n return date.toISOString()\n }\n\n isUniqueConstraintError(error: unknown): boolean {\n const e = error as DatabaseErrorLike\n const message = e.message?.toLowerCase() || ''\n return message.includes('unique constraint failed')\n }\n\n isForeignKeyError(error: unknown): boolean {\n const e = error as DatabaseErrorLike\n const message = e.message?.toLowerCase() || ''\n return message.includes('foreign key constraint failed')\n }\n\n isNotNullError(error: unknown): boolean {\n const e = error as DatabaseErrorLike\n const message = e.message?.toLowerCase() || ''\n return message.includes('not null constraint failed')\n }\n\n async tableExists(db: Kysely<any>, tableName: string): Promise<boolean> {\n assertValidIdentifier(tableName, 'table name')\n try {\n const result = await db\n .selectFrom('sqlite_master')\n .select('name')\n .where('type', '=', 'table')\n .where('name', '=', tableName)\n .executeTakeFirst()\n return !!result\n } catch {\n return false\n }\n }\n\n async getTableColumns(db: Kysely<any>, tableName: string): Promise<string[]> {\n assertValidIdentifier(tableName, 'table name')\n try {\n const results = await sql\n .raw(`PRAGMA table_info(${this.escapeIdentifier(tableName)})`)\n .execute(db)\n return (results.rows as { name: string }[]).map(r => r.name)\n } catch {\n return []\n }\n }\n\n async getTables(db: Kysely<any>): Promise<string[]> {\n try {\n const results = await db\n .selectFrom('sqlite_master')\n .select('name')\n .where('type', '=', 'table')\n .where('name', 'not like', 'sqlite_%')\n .execute()\n return results.map(r => r.name as string)\n } catch {\n return []\n }\n }\n\n async getDatabaseSize(_db: Kysely<any>, _databaseName?: string): Promise<number> {\n // SQLite database size requires file system access\n // which is not available in a cross-runtime way\n return 0\n }\n\n async truncateTable(db: Kysely<any>, tableName: string): Promise<boolean> {\n assertValidIdentifier(tableName, 'table name')\n try {\n // SQLite doesn't support TRUNCATE, use DELETE instead\n await sql.raw(`DELETE FROM ${this.escapeIdentifier(tableName)}`).execute(db)\n return true\n } catch (error) {\n const errorMessage = String(error)\n if (errorMessage.includes('no such table')) {\n return false\n }\n // Log and rethrow unexpected errors\n this.logger.error(`Failed to truncate table \"${tableName}\":`, error)\n throw error\n }\n }\n\n async truncateAllTables(db: Kysely<any>, exclude: string[] = []): Promise<void> {\n const tables = await this.getTables(db)\n for (const table of tables) {\n if (!exclude.includes(table)) {\n await this.truncateTable(db, table)\n }\n }\n }\n}\n\nexport const sqliteAdapter = new SQLiteAdapter()\n","/**\n * Microsoft SQL Server Dialect Adapter\n *\n * Supports SQL Server 2017+, Azure SQL Database, and Azure SQL Edge\n */\n\nimport type { Kysely } from 'kysely'\nimport { sql } from 'kysely'\nimport type { DialectAdapter, DatabaseErrorLike } from '../types.js'\nimport { assertValidIdentifier } from '../helpers.js'\n\nexport class MSSQLAdapter implements DialectAdapter {\n readonly dialect = 'mssql' as const\n\n getDefaultPort(): number {\n return 1433\n }\n\n getCurrentTimestamp(): string {\n return 'GETDATE()'\n }\n\n escapeIdentifier(identifier: string): string {\n // MSSQL uses square brackets for escaping\n return '[' + identifier.replace(/\\]/g, ']]') + ']'\n }\n\n formatDate(date: Date): string {\n // MSSQL datetime format: YYYY-MM-DD HH:MM:SS.mmm\n return date.toISOString().replace('T', ' ').replace('Z', '')\n }\n\n isUniqueConstraintError(error: unknown): boolean {\n const e = error as DatabaseErrorLike\n const message = e.message?.toLowerCase() || ''\n const code = e.code || ''\n // MSSQL error 2627: Violation of PRIMARY KEY/UNIQUE constraint\n // MSSQL error 2601: Cannot insert duplicate key row\n return (\n code === '2627' ||\n code === '2601' ||\n message.includes('violation of unique key constraint') ||\n message.includes('cannot insert duplicate key') ||\n message.includes('unique constraint')\n )\n }\n\n isForeignKeyError(error: unknown): boolean {\n const e = error as DatabaseErrorLike\n const message = e.message?.toLowerCase() || ''\n const code = e.code || ''\n // MSSQL error 547: FOREIGN KEY constraint violation\n return (\n code === '547' ||\n message.includes('foreign key constraint') ||\n message.includes('conflicted with the foreign key')\n )\n }\n\n isNotNullError(error: unknown): boolean {\n const e = error as DatabaseErrorLike\n const message = e.message?.toLowerCase() || ''\n const code = e.code || ''\n // MSSQL error 515: Cannot insert NULL value\n return (\n code === '515' ||\n message.includes('cannot insert the value null') ||\n message.includes('does not allow nulls')\n )\n }\n\n async tableExists(db: Kysely<any>, tableName: string): Promise<boolean> {\n assertValidIdentifier(tableName, 'table name')\n try {\n const result = await db\n .selectFrom('INFORMATION_SCHEMA.TABLES')\n .select('TABLE_NAME')\n .where('TABLE_NAME', '=', tableName)\n .where('TABLE_TYPE', '=', 'BASE TABLE')\n .executeTakeFirst()\n return !!result\n } catch {\n return false\n }\n }\n\n async getTableColumns(db: Kysely<any>, tableName: string): Promise<string[]> {\n assertValidIdentifier(tableName, 'table name')\n try {\n const results = await db\n .selectFrom('INFORMATION_SCHEMA.COLUMNS')\n .select('COLUMN_NAME')\n .where('TABLE_NAME', '=', tableName)\n .execute()\n return results.map(r => (r as { COLUMN_NAME: string }).COLUMN_NAME)\n } catch {\n return []\n }\n }\n\n async getTables(db: Kysely<any>): Promise<string[]> {\n try {\n const results = await db\n .selectFrom('INFORMATION_SCHEMA.TABLES')\n .select('TABLE_NAME')\n .where('TABLE_TYPE', '=', 'BASE TABLE')\n .where('TABLE_SCHEMA', '=', 'dbo')\n .execute()\n return results.map(r => (r as { TABLE_NAME: string }).TABLE_NAME)\n } catch {\n return []\n }\n }\n\n async getDatabaseSize(db: Kysely<any>, _databaseName?: string): Promise<number> {\n try {\n // MSSQL: Get database size using sys.database_files\n // Note: _databaseName is ignored as MSSQL uses the current database context\n const result = await sql<{ size: number }>`\n SELECT SUM(size * 8 * 1024) as size\n FROM sys.database_files\n WHERE type = 0\n `.execute(db)\n return (result.rows?.[0] as { size?: number })?.size || 0\n } catch {\n return 0\n }\n }\n\n async truncateTable(db: Kysely<any>, tableName: string): Promise<boolean> {\n assertValidIdentifier(tableName, 'table name')\n try {\n // MSSQL: First try TRUNCATE, fall back to DELETE if FK constraints exist\n try {\n await sql.raw(`TRUNCATE TABLE ${this.escapeIdentifier(tableName)}`).execute(db)\n } catch (truncateError) {\n // If truncate fails due to FK, use DELETE\n const errorMsg = String(truncateError)\n if (errorMsg.includes('FOREIGN KEY') || errorMsg.includes('Cannot truncate')) {\n await sql.raw(`DELETE FROM ${this.escapeIdentifier(tableName)}`).execute(db)\n // Reset identity if table has one\n try {\n // Use escaped identifier for SQL injection prevention\n const escapedTableName = this.escapeIdentifier(tableName)\n await sql\n .raw(`DBCC CHECKIDENT (${escapedTableName}, RESEED, 0)`)\n .execute(db)\n } catch {\n // Ignore if table doesn't have identity column\n }\n } else {\n throw truncateError\n }\n }\n return true\n } catch (error) {\n const errorMessage = String(error)\n if (\n errorMessage.includes('Invalid object name') ||\n errorMessage.includes('does not exist')\n ) {\n return false\n }\n // Re-throw with context (logging should be handled by caller)\n throw new Error(`Failed to truncate MSSQL table \"${tableName}\": ${String(error)}`)\n }\n }\n\n async truncateAllTables(db: Kysely<any>, exclude: string[] = []): Promise<void> {\n const tables = await this.getTables(db)\n\n // MSSQL: Disable all FK constraints first\n for (const table of tables) {\n if (!exclude.includes(table)) {\n try {\n await sql\n .raw(`ALTER TABLE ${this.escapeIdentifier(table)} NOCHECK CONSTRAINT ALL`)\n .execute(db)\n } catch {\n // Ignore errors for tables without constraints\n }\n }\n }\n\n // Truncate all tables\n for (const table of tables) {\n if (!exclude.includes(table)) {\n await this.truncateTable(db, table)\n }\n }\n\n // Re-enable all FK constraints\n for (const table of tables) {\n if (!exclude.includes(table)) {\n try {\n await sql\n .raw(`ALTER TABLE ${this.escapeIdentifier(table)} CHECK CONSTRAINT ALL`)\n .execute(db)\n } catch {\n // Ignore errors\n }\n }\n }\n }\n}\n\nexport const mssqlAdapter = new MSSQLAdapter()\n","/**\n * Dialect Adapter Factory\n */\n\nimport type { Dialect, DialectAdapter } from './types.js'\nimport { PostgresAdapter, postgresAdapter } from './adapters/postgres.js'\nimport { MySQLAdapter, mysqlAdapter } from './adapters/mysql.js'\nimport { SQLiteAdapter, sqliteAdapter } from './adapters/sqlite.js'\nimport { MSSQLAdapter, mssqlAdapter } from './adapters/mssql.js'\n\nconst adapters: Record<Dialect, DialectAdapter> = {\n postgres: postgresAdapter,\n mysql: mysqlAdapter,\n sqlite: sqliteAdapter,\n mssql: mssqlAdapter\n}\n\n/**\n * Get a dialect adapter for the specified dialect\n *\n * @example\n * const adapter = getAdapter('postgres');\n * console.log(adapter.getDefaultPort()); // 5432\n */\nexport function getAdapter(dialect: Dialect): DialectAdapter {\n const adapter = adapters[dialect]\n if (!adapter) {\n throw new Error(`Unknown dialect: ${dialect}. Supported: postgres, mysql, sqlite, mssql`)\n }\n return adapter\n}\n\n/**\n * Create a new dialect adapter instance\n *\n * @example\n * const adapter = createDialectAdapter('mysql');\n */\nexport function createDialectAdapter(dialect: Dialect): DialectAdapter {\n switch (dialect) {\n case 'postgres':\n return new PostgresAdapter()\n case 'mysql':\n return new MySQLAdapter()\n case 'sqlite':\n return new SQLiteAdapter()\n case 'mssql':\n return new MSSQLAdapter()\n default:\n throw new Error(`Unknown dialect: ${dialect}. Supported: postgres, mysql, sqlite, mssql`)\n }\n}\n\n/**\n * Register a custom dialect adapter\n *\n * @example\n * registerAdapter(customAdapter);\n */\nexport function registerAdapter(adapter: DialectAdapter): void {\n adapters[adapter.dialect] = adapter\n}\n","/**\n * Connection URL utilities\n */\n\nimport type { Dialect, ConnectionConfig } from './types.js'\nimport { getAdapter } from './factory.js'\n\n/**\n * Parse database connection URL into ConnectionConfig\n *\n * @example\n * const config = parseConnectionUrl('postgresql://user:pass@localhost:5432/mydb?ssl=true');\n * // { host: 'localhost', port: 5432, database: 'mydb', user: 'user', password: 'pass', ssl: true }\n */\nexport function parseConnectionUrl(url: string): ConnectionConfig {\n const parsed = new URL(url)\n\n return {\n host: parsed.hostname,\n port: parsed.port ? parseInt(parsed.port) : undefined,\n database: parsed.pathname.slice(1),\n user: parsed.username || undefined,\n password: parsed.password || undefined,\n ssl:\n parsed.searchParams.get('ssl') === 'true' || parsed.searchParams.get('sslmode') === 'require'\n }\n}\n\n/**\n * Build connection URL from config\n *\n * @example\n * const url = buildConnectionUrl('postgres', { host: 'localhost', database: 'mydb' });\n * // 'postgresql://localhost:5432/mydb'\n */\nexport function buildConnectionUrl(dialect: Dialect, config: ConnectionConfig): string {\n // Map dialect to protocol\n const protocolMap: Record<Dialect, string> = {\n postgres: 'postgresql',\n mysql: 'mysql',\n sqlite: 'sqlite',\n mssql: 'mssql'\n }\n const protocol = protocolMap[dialect]\n const auth = config.user\n ? config.password\n ? `${config.user}:${config.password}@`\n : `${config.user}@`\n : ''\n\n const host = config.host || 'localhost'\n const port = config.port || getAdapter(dialect).getDefaultPort()\n const database = config.database\n\n let url = port\n ? `${protocol}://${auth}${host}:${port}/${database}`\n : `${protocol}://${auth}${host}/${database}`\n\n if (config.ssl) {\n url += '?ssl=true'\n }\n\n return url\n}\n\n/**\n * Get default port for a dialect\n *\n * @example\n * getDefaultPort('postgres') // 5432\n * getDefaultPort('mysql') // 3306\n * getDefaultPort('sqlite') // null\n */\nexport function getDefaultPort(dialect: Dialect): number | null {\n return getAdapter(dialect).getDefaultPort()\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kysera/dialects",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Dialect-specific utilities for Kysely - PostgreSQL, MySQL, SQLite support",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -18,6 +18,9 @@
|
|
|
18
18
|
"peerDependencies": {
|
|
19
19
|
"kysely": ">=0.28.8"
|
|
20
20
|
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@kysera/core": "0.8.0"
|
|
23
|
+
},
|
|
21
24
|
"devDependencies": {
|
|
22
25
|
"@types/better-sqlite3": "^7.6.13",
|
|
23
26
|
"@types/node": "^25.0.3",
|