@ku6epxboctuk/sqlite-up 0.0.0-stage → 0.6.1
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 +23 -0
- package/README.md +453 -2
- package/dist/errors.d.ts +26 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/index.d.ts +111 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +533 -0
- package/dist/index.js.map +1 -0
- package/dist/providers/better-sqlite3.d.ts +18 -0
- package/dist/providers/better-sqlite3.d.ts.map +1 -0
- package/dist/providers/bun-sql.d.ts +11 -0
- package/dist/providers/bun-sql.d.ts.map +1 -0
- package/dist/providers/bun-sqlite.d.ts +17 -0
- package/dist/providers/bun-sqlite.d.ts.map +1 -0
- package/dist/providers/index.d.ts +12 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/manual-transaction.d.ts +7 -0
- package/dist/providers/manual-transaction.d.ts.map +1 -0
- package/dist/providers/node-sqlite.d.ts +17 -0
- package/dist/providers/node-sqlite.d.ts.map +1 -0
- package/dist/providers/types.d.ts +15 -0
- package/dist/providers/types.d.ts.map +1 -0
- package/dist/types.d.ts +201 -0
- package/dist/types.d.ts.map +1 -0
- package/package.json +79 -4
package/dist/index.js
ADDED
|
@@ -0,0 +1,533 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import { EventEmitter } from "events";
|
|
3
|
+
import { promises as fs } from "fs";
|
|
4
|
+
import path from "path";
|
|
5
|
+
import { pathToFileURL } from "url";
|
|
6
|
+
|
|
7
|
+
// src/errors.ts
|
|
8
|
+
var MigrationError = class extends Error {
|
|
9
|
+
constructor(message, cause) {
|
|
10
|
+
super(message);
|
|
11
|
+
this.cause = cause;
|
|
12
|
+
this.name = "MigrationError";
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
var MigrationFileError = class extends MigrationError {
|
|
16
|
+
constructor(message, cause) {
|
|
17
|
+
super(message, cause);
|
|
18
|
+
this.name = "MigrationFileError";
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
var MigrationLockError = class extends MigrationError {
|
|
22
|
+
constructor(message, cause) {
|
|
23
|
+
super(message, cause);
|
|
24
|
+
this.name = "MigrationLockError";
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
var MigrationExecutionError = class extends MigrationError {
|
|
28
|
+
constructor(message, cause) {
|
|
29
|
+
super(message, cause);
|
|
30
|
+
this.name = "MigrationExecutionError";
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
// src/providers/manual-transaction.ts
|
|
35
|
+
function createManualTransactionProvider(db) {
|
|
36
|
+
return {
|
|
37
|
+
db,
|
|
38
|
+
/**
|
|
39
|
+
* Runs the callback between BEGIN IMMEDIATE and COMMIT, rolling back on failure.
|
|
40
|
+
*/
|
|
41
|
+
transaction: async (fn) => {
|
|
42
|
+
await db.exec("BEGIN IMMEDIATE");
|
|
43
|
+
try {
|
|
44
|
+
await fn();
|
|
45
|
+
await db.exec("COMMIT");
|
|
46
|
+
} catch (err) {
|
|
47
|
+
try {
|
|
48
|
+
await db.exec("ROLLBACK");
|
|
49
|
+
} catch {
|
|
50
|
+
}
|
|
51
|
+
throw err;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// src/providers/better-sqlite3.ts
|
|
58
|
+
function isBetterSqlite3Database(db) {
|
|
59
|
+
const candidate = db;
|
|
60
|
+
return typeof candidate.exec === "function" && typeof candidate.prepare === "function" && typeof candidate.transaction === "function" && typeof candidate.open === "boolean";
|
|
61
|
+
}
|
|
62
|
+
function createBetterSqlite3Provider(db) {
|
|
63
|
+
return createManualTransactionProvider(db);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// src/providers/bun-sql.ts
|
|
67
|
+
async function executeBunSql(client, sql, params = []) {
|
|
68
|
+
return await client.unsafe(sql, params.length > 0 ? params : void 0);
|
|
69
|
+
}
|
|
70
|
+
function isBunSqlDatabase(db) {
|
|
71
|
+
const candidate = db;
|
|
72
|
+
return typeof candidate.unsafe === "function" && typeof candidate.exec !== "function";
|
|
73
|
+
}
|
|
74
|
+
function createBunSqlProvider(rootClient) {
|
|
75
|
+
let activeClient = rootClient;
|
|
76
|
+
const db = {
|
|
77
|
+
/**
|
|
78
|
+
* Executes a SQL statement through the currently active Bun SQL client.
|
|
79
|
+
*/
|
|
80
|
+
exec: async (sql) => {
|
|
81
|
+
await executeBunSql(activeClient, sql);
|
|
82
|
+
},
|
|
83
|
+
/**
|
|
84
|
+
* Creates a prepared-statement facade backed by Bun SQL unsafe execution.
|
|
85
|
+
*/
|
|
86
|
+
prepare: (sql) => ({
|
|
87
|
+
/**
|
|
88
|
+
* Runs the statement and returns all rows.
|
|
89
|
+
*/
|
|
90
|
+
all: (...params) => executeBunSql(activeClient, sql, params),
|
|
91
|
+
/**
|
|
92
|
+
* Runs the statement and returns the first row.
|
|
93
|
+
*/
|
|
94
|
+
get: async (...params) => {
|
|
95
|
+
const rows = await executeBunSql(activeClient, sql, params);
|
|
96
|
+
return rows[0];
|
|
97
|
+
},
|
|
98
|
+
/**
|
|
99
|
+
* Runs the statement for side effects and returns the driver result.
|
|
100
|
+
*/
|
|
101
|
+
run: (...params) => executeBunSql(activeClient, sql, params)
|
|
102
|
+
}),
|
|
103
|
+
/**
|
|
104
|
+
* Creates a transaction runner using Bun SQL native transactions when available.
|
|
105
|
+
*/
|
|
106
|
+
transaction: (fn) => {
|
|
107
|
+
const run = async (...args) => {
|
|
108
|
+
if (typeof rootClient.begin === "function") {
|
|
109
|
+
return await rootClient.begin(async (tx) => {
|
|
110
|
+
const previousClient = activeClient;
|
|
111
|
+
activeClient = tx;
|
|
112
|
+
try {
|
|
113
|
+
return await fn(...args);
|
|
114
|
+
} finally {
|
|
115
|
+
activeClient = previousClient;
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
await db.exec("BEGIN");
|
|
120
|
+
try {
|
|
121
|
+
const result = await fn(...args);
|
|
122
|
+
await db.exec("COMMIT");
|
|
123
|
+
return result;
|
|
124
|
+
} catch (err) {
|
|
125
|
+
try {
|
|
126
|
+
await db.exec("ROLLBACK");
|
|
127
|
+
} catch {
|
|
128
|
+
}
|
|
129
|
+
throw err;
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
return run;
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
return {
|
|
136
|
+
db,
|
|
137
|
+
/**
|
|
138
|
+
* Runs migration work inside the Bun SQL transaction facade.
|
|
139
|
+
*/
|
|
140
|
+
transaction: async (fn) => {
|
|
141
|
+
const transaction = db.transaction(fn);
|
|
142
|
+
await transaction();
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// src/providers/bun-sqlite.ts
|
|
148
|
+
function isBunSqliteDatabase(db) {
|
|
149
|
+
const candidate = db;
|
|
150
|
+
return typeof candidate.exec === "function" && typeof candidate.prepare === "function" && typeof candidate.query === "function";
|
|
151
|
+
}
|
|
152
|
+
function createBunSqliteProvider(db) {
|
|
153
|
+
return createManualTransactionProvider(db);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// src/providers/node-sqlite.ts
|
|
157
|
+
function isNodeSqliteDatabase(db) {
|
|
158
|
+
const candidate = db;
|
|
159
|
+
return typeof candidate.exec === "function" && typeof candidate.prepare === "function" && typeof candidate.isOpen === "boolean";
|
|
160
|
+
}
|
|
161
|
+
function createNodeSqliteProvider(db) {
|
|
162
|
+
return createManualTransactionProvider(db);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// src/providers/index.ts
|
|
166
|
+
function isSqliteDatabase(db) {
|
|
167
|
+
const candidate = db;
|
|
168
|
+
return typeof candidate.exec === "function" && typeof candidate.prepare === "function";
|
|
169
|
+
}
|
|
170
|
+
function createSqliteProvider(db) {
|
|
171
|
+
if (isBunSqlDatabase(db)) {
|
|
172
|
+
return createBunSqlProvider(db);
|
|
173
|
+
}
|
|
174
|
+
if (isBunSqliteDatabase(db)) {
|
|
175
|
+
return createBunSqliteProvider(db);
|
|
176
|
+
}
|
|
177
|
+
if (isBetterSqlite3Database(db)) {
|
|
178
|
+
return createBetterSqlite3Provider(db);
|
|
179
|
+
}
|
|
180
|
+
if (isNodeSqliteDatabase(db)) {
|
|
181
|
+
return createNodeSqliteProvider(db);
|
|
182
|
+
}
|
|
183
|
+
if (isSqliteDatabase(db)) {
|
|
184
|
+
return createManualTransactionProvider(db);
|
|
185
|
+
}
|
|
186
|
+
if (typeof db === "object" && db !== null) {
|
|
187
|
+
return createManualTransactionProvider(db);
|
|
188
|
+
}
|
|
189
|
+
throw new TypeError("Unsupported SQLite database provider.");
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// src/index.ts
|
|
193
|
+
var Migrator = class extends EventEmitter {
|
|
194
|
+
constructor(options) {
|
|
195
|
+
super();
|
|
196
|
+
/**
|
|
197
|
+
* Migration modules loaded from disk in execution order.
|
|
198
|
+
*/
|
|
199
|
+
this.migrations = [];
|
|
200
|
+
/**
|
|
201
|
+
* Whether internal tables and migration files have already been initialized.
|
|
202
|
+
*/
|
|
203
|
+
this.initialized = false;
|
|
204
|
+
this.provider = createSqliteProvider(options.db);
|
|
205
|
+
this.db = this.provider.db;
|
|
206
|
+
this.migrationsDir = options.migrationsDir;
|
|
207
|
+
this.migrationsTable = options.migrationsTable ?? "schema_migrations";
|
|
208
|
+
this.lockTable = options.migrationsLockTable ?? "schema_migrations_lock";
|
|
209
|
+
this.fileExtensions = options.fileExtensions ?? ["ts", "js"];
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Ensures the `schema_migrations` and `schema_migrations_lock` tables exist,
|
|
213
|
+
* and loads migration files from the migrations directory.
|
|
214
|
+
*/
|
|
215
|
+
async init() {
|
|
216
|
+
if (this.initialized) {
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
await this.initTables();
|
|
220
|
+
await this.loadMigrationsFromDirectory();
|
|
221
|
+
this.initialized = true;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Initializes the `schema_migrations` and `schema_migrations_lock` tables.
|
|
225
|
+
*/
|
|
226
|
+
async initTables() {
|
|
227
|
+
try {
|
|
228
|
+
await this.db.exec(`
|
|
229
|
+
CREATE TABLE IF NOT EXISTS ${this.migrationsTable} (
|
|
230
|
+
name TEXT PRIMARY KEY,
|
|
231
|
+
executed_at TEXT NOT NULL, -- ISO string
|
|
232
|
+
batch INTEGER NOT NULL
|
|
233
|
+
)
|
|
234
|
+
`);
|
|
235
|
+
await this.db.exec(`
|
|
236
|
+
CREATE TABLE IF NOT EXISTS ${this.lockTable} (
|
|
237
|
+
id INTEGER PRIMARY KEY CHECK (id = 1),
|
|
238
|
+
locked INTEGER NOT NULL DEFAULT 0
|
|
239
|
+
)
|
|
240
|
+
`);
|
|
241
|
+
await this.db.exec(`
|
|
242
|
+
INSERT OR IGNORE INTO ${this.lockTable} (id, locked) VALUES (1, 0)
|
|
243
|
+
`);
|
|
244
|
+
} catch (err) {
|
|
245
|
+
throw new MigrationError("Failed to initialize migrator", err);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Load migration files from the `migrationsDir`.
|
|
250
|
+
* Migration files must export { up, down }.
|
|
251
|
+
* The migrations are loaded in alphabetical order.
|
|
252
|
+
*/
|
|
253
|
+
async loadMigrationsFromDirectory() {
|
|
254
|
+
try {
|
|
255
|
+
const entries = await fs.readdir(this.migrationsDir);
|
|
256
|
+
const migrationFiles = entries.filter((file) => {
|
|
257
|
+
if (file.endsWith(".d.ts")) {
|
|
258
|
+
return false;
|
|
259
|
+
}
|
|
260
|
+
return this.fileExtensions.some((ext) => file.endsWith(`.${ext}`));
|
|
261
|
+
}).sort();
|
|
262
|
+
const loadedMigrations = [];
|
|
263
|
+
for (const file of migrationFiles) {
|
|
264
|
+
const fullPath = path.join(this.migrationsDir, file);
|
|
265
|
+
let imported;
|
|
266
|
+
try {
|
|
267
|
+
imported = await import(pathToFileURL(fullPath).href);
|
|
268
|
+
} catch (err) {
|
|
269
|
+
throw new MigrationFileError(`Error loading migration "${file}": ${String(err)}`, err);
|
|
270
|
+
}
|
|
271
|
+
const { up, down } = imported;
|
|
272
|
+
if (typeof up !== "function" || typeof down !== "function") {
|
|
273
|
+
throw new MigrationFileError(`Migration "${file}" must export "up" and "down" functions.`);
|
|
274
|
+
}
|
|
275
|
+
loadedMigrations.push({ name: file, up, down });
|
|
276
|
+
}
|
|
277
|
+
this.migrations = loadedMigrations;
|
|
278
|
+
} catch (err) {
|
|
279
|
+
throw err instanceof MigrationFileError ? err : new MigrationFileError("Failed to load migrations", err);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Acquire a lock to prevent concurrent migrations.
|
|
284
|
+
* Throws an error if the lock is already held.
|
|
285
|
+
*/
|
|
286
|
+
async acquireLock() {
|
|
287
|
+
try {
|
|
288
|
+
await this.runTransaction(async () => {
|
|
289
|
+
const row = await this.db.prepare(`SELECT locked FROM ${this.lockTable} WHERE id = 1`).get();
|
|
290
|
+
if (row.locked === 1) {
|
|
291
|
+
throw new MigrationLockError("Migration lock already held by another process.");
|
|
292
|
+
}
|
|
293
|
+
await this.db.prepare(`UPDATE ${this.lockTable} SET locked = 1 WHERE id = 1`).run();
|
|
294
|
+
});
|
|
295
|
+
} catch (err) {
|
|
296
|
+
if (err instanceof MigrationLockError) {
|
|
297
|
+
throw err;
|
|
298
|
+
}
|
|
299
|
+
throw new MigrationLockError("Failed to acquire migration lock", err);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Release the migration lock.
|
|
304
|
+
*/
|
|
305
|
+
async releaseLock() {
|
|
306
|
+
try {
|
|
307
|
+
await this.db.prepare(`UPDATE ${this.lockTable} SET locked = 0 WHERE id = 1`).run();
|
|
308
|
+
} catch (err) {
|
|
309
|
+
throw new MigrationLockError("Failed to release migration lock", err);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Get the highest batch number.
|
|
314
|
+
*/
|
|
315
|
+
async getCurrentBatch() {
|
|
316
|
+
const row = await this.db.prepare(`SELECT MAX(batch) as batch FROM ${this.migrationsTable}`).get();
|
|
317
|
+
return row?.batch ?? 0;
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Insert a record for an applied migration.
|
|
321
|
+
*/
|
|
322
|
+
async recordMigration(name, batch) {
|
|
323
|
+
const executedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
324
|
+
await this.db.prepare(
|
|
325
|
+
`
|
|
326
|
+
INSERT INTO ${this.migrationsTable} (name, executed_at, batch)
|
|
327
|
+
VALUES (?, ?, ?)
|
|
328
|
+
`
|
|
329
|
+
).run(name, executedAt, batch);
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Delete a record for a migration that is being rolled back.
|
|
333
|
+
*/
|
|
334
|
+
async removeMigration(name, batch) {
|
|
335
|
+
await this.db.prepare(
|
|
336
|
+
`
|
|
337
|
+
DELETE FROM ${this.migrationsTable}
|
|
338
|
+
WHERE name = ? AND batch = ?
|
|
339
|
+
`
|
|
340
|
+
).run(name, batch);
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Run SQL operations in a transaction.
|
|
344
|
+
* @param fn The function to run in the transaction.
|
|
345
|
+
*/
|
|
346
|
+
async runTransaction(fn) {
|
|
347
|
+
await this.provider.transaction(fn);
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Apply all pending migrations in a single batch.
|
|
351
|
+
* Returns the names of applied migrations.
|
|
352
|
+
*/
|
|
353
|
+
async apply(...args) {
|
|
354
|
+
try {
|
|
355
|
+
await this.init();
|
|
356
|
+
} catch (err) {
|
|
357
|
+
return {
|
|
358
|
+
success: false,
|
|
359
|
+
error: err,
|
|
360
|
+
appliedMigrations: []
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
try {
|
|
364
|
+
await this.acquireLock();
|
|
365
|
+
} catch (err) {
|
|
366
|
+
return {
|
|
367
|
+
success: false,
|
|
368
|
+
error: err,
|
|
369
|
+
appliedMigrations: []
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
const appliedMigrations = [];
|
|
373
|
+
try {
|
|
374
|
+
const currentBatch = await this.getCurrentBatch();
|
|
375
|
+
const nextBatch = currentBatch + 1;
|
|
376
|
+
const appliedNames = new Set(
|
|
377
|
+
(await this.db.prepare(`SELECT name FROM ${this.migrationsTable}`).all()).map(
|
|
378
|
+
(row) => row.name
|
|
379
|
+
)
|
|
380
|
+
);
|
|
381
|
+
const pendingMigrations = this.migrations.filter((m) => !appliedNames.has(m.name));
|
|
382
|
+
if (pendingMigrations.length === 0) {
|
|
383
|
+
return { success: true, appliedMigrations };
|
|
384
|
+
}
|
|
385
|
+
await this.runTransaction(async () => {
|
|
386
|
+
for (const migration of pendingMigrations) {
|
|
387
|
+
try {
|
|
388
|
+
await migration.up(this.db, ...args);
|
|
389
|
+
await this.recordMigration(migration.name, nextBatch);
|
|
390
|
+
appliedMigrations.push(migration.name);
|
|
391
|
+
} catch (err) {
|
|
392
|
+
throw new MigrationExecutionError(`Failed to apply migration "${migration.name}"`, err);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
});
|
|
396
|
+
for (const migrationName of appliedMigrations) {
|
|
397
|
+
this.emit("migration:applied", migrationName, nextBatch);
|
|
398
|
+
}
|
|
399
|
+
return { success: true, appliedMigrations };
|
|
400
|
+
} catch (error) {
|
|
401
|
+
const err = error instanceof MigrationExecutionError ? error : new MigrationExecutionError("Migration failed", error);
|
|
402
|
+
return { success: false, error: err, appliedMigrations: [] };
|
|
403
|
+
} finally {
|
|
404
|
+
await this.releaseLock();
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* Roll back the most recent batch of migrations.
|
|
409
|
+
* Returns the names of rolled back migrations.
|
|
410
|
+
*/
|
|
411
|
+
async rollback(...args) {
|
|
412
|
+
try {
|
|
413
|
+
await this.init();
|
|
414
|
+
} catch (err) {
|
|
415
|
+
return {
|
|
416
|
+
success: false,
|
|
417
|
+
error: err,
|
|
418
|
+
appliedMigrations: []
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
try {
|
|
422
|
+
await this.acquireLock();
|
|
423
|
+
} catch (err) {
|
|
424
|
+
return {
|
|
425
|
+
success: false,
|
|
426
|
+
error: err,
|
|
427
|
+
appliedMigrations: []
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
const appliedMigrations = [];
|
|
431
|
+
try {
|
|
432
|
+
const currentBatch = await this.getCurrentBatch();
|
|
433
|
+
if (currentBatch === 0) {
|
|
434
|
+
return { success: true, appliedMigrations };
|
|
435
|
+
}
|
|
436
|
+
const rows = await this.db.prepare(
|
|
437
|
+
`
|
|
438
|
+
SELECT name
|
|
439
|
+
FROM ${this.migrationsTable}
|
|
440
|
+
WHERE batch = ?
|
|
441
|
+
ORDER BY name DESC
|
|
442
|
+
`
|
|
443
|
+
).all(currentBatch);
|
|
444
|
+
if (rows.length === 0) {
|
|
445
|
+
return { success: true, appliedMigrations };
|
|
446
|
+
}
|
|
447
|
+
await this.runTransaction(async () => {
|
|
448
|
+
for (const row of rows) {
|
|
449
|
+
const migration = this.migrations.find((m) => m.name === row.name);
|
|
450
|
+
if (!migration) {
|
|
451
|
+
throw new MigrationFileError(`Migration "${row.name}" not found.`);
|
|
452
|
+
}
|
|
453
|
+
try {
|
|
454
|
+
await migration.down(this.db, ...args);
|
|
455
|
+
await this.removeMigration(migration.name, currentBatch);
|
|
456
|
+
appliedMigrations.push(migration.name);
|
|
457
|
+
} catch (err) {
|
|
458
|
+
throw new MigrationExecutionError(`Failed to rollback migration "${migration.name}"`, err);
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
});
|
|
462
|
+
for (const migrationName of appliedMigrations) {
|
|
463
|
+
this.emit("migration:rollback", migrationName, currentBatch);
|
|
464
|
+
}
|
|
465
|
+
return { success: true, appliedMigrations };
|
|
466
|
+
} catch (error) {
|
|
467
|
+
const err = error instanceof MigrationExecutionError ? error : new MigrationExecutionError("Rollback failed", error);
|
|
468
|
+
return { success: false, error: err, appliedMigrations: [] };
|
|
469
|
+
} finally {
|
|
470
|
+
await this.releaseLock();
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* Get the status of migrations.
|
|
475
|
+
* Returns:
|
|
476
|
+
* - currentBatch: the highest batch number applied
|
|
477
|
+
* - pending: number of migrations not yet applied
|
|
478
|
+
* - applied: list of all applied migrations
|
|
479
|
+
*/
|
|
480
|
+
async status() {
|
|
481
|
+
await this.init();
|
|
482
|
+
try {
|
|
483
|
+
const currentBatch = await this.getCurrentBatch();
|
|
484
|
+
const rows = await this.db.prepare(
|
|
485
|
+
`
|
|
486
|
+
SELECT name, executed_at, batch
|
|
487
|
+
FROM ${this.migrationsTable}
|
|
488
|
+
ORDER BY batch ASC, name ASC
|
|
489
|
+
`
|
|
490
|
+
).all();
|
|
491
|
+
const appliedNames = new Set(rows.map((r) => r.name));
|
|
492
|
+
const pending = this.migrations.length - appliedNames.size;
|
|
493
|
+
return {
|
|
494
|
+
currentBatch,
|
|
495
|
+
pending,
|
|
496
|
+
applied: rows
|
|
497
|
+
};
|
|
498
|
+
} catch (err) {
|
|
499
|
+
throw new MigrationError("Failed to get migration status", err);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
/**
|
|
503
|
+
* Plan the pending migrations without applying them.
|
|
504
|
+
* Returns the next batch number and the list of pending migration names in order.
|
|
505
|
+
*/
|
|
506
|
+
async plan() {
|
|
507
|
+
await this.init();
|
|
508
|
+
try {
|
|
509
|
+
const currentBatch = await this.getCurrentBatch();
|
|
510
|
+
const nextBatch = currentBatch + 1;
|
|
511
|
+
const appliedNames = new Set(
|
|
512
|
+
(await this.db.prepare(`SELECT name FROM ${this.migrationsTable}`).all()).map(
|
|
513
|
+
(row) => row.name
|
|
514
|
+
)
|
|
515
|
+
);
|
|
516
|
+
const pendingMigrations = this.migrations.filter((m) => !appliedNames.has(m.name)).map((m) => m.name);
|
|
517
|
+
return {
|
|
518
|
+
nextBatch,
|
|
519
|
+
pendingMigrations
|
|
520
|
+
};
|
|
521
|
+
} catch (err) {
|
|
522
|
+
throw new MigrationError("Failed to create migration plan", err);
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
};
|
|
526
|
+
export {
|
|
527
|
+
MigrationError,
|
|
528
|
+
MigrationExecutionError,
|
|
529
|
+
MigrationFileError,
|
|
530
|
+
MigrationLockError,
|
|
531
|
+
Migrator
|
|
532
|
+
};
|
|
533
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/providers/manual-transaction.ts","../src/providers/better-sqlite3.ts","../src/providers/bun-sql.ts","../src/providers/bun-sqlite.ts","../src/providers/node-sqlite.ts","../src/providers/index.ts"],"sourcesContent":["import { EventEmitter } from 'node:events';\nimport { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport { MigrationError, MigrationExecutionError, MigrationFileError, MigrationLockError } from './errors.js';\nimport { createSqliteProvider, type SqliteProvider } from './providers/index.js';\nimport type {\n ContextArg,\n MaybePromise,\n Migration,\n MigrationPlan,\n MigrationRecord,\n MigrationResult,\n MigrationStatus,\n MigratorOptions,\n SqliteDatabase,\n} from './types.js';\n\n/**\n * Migration provider for SQLite databases.\n * @example\n * const db = new DatabaseSync('database.db');\n * const migrator = new Migrator({ db, migrationsDir: 'migrations' });\n * await migrator.apply();\n */\nexport class Migrator<T = undefined> extends EventEmitter {\n /**\n * Driver-specific provider normalized to the sqlite-up database surface.\n */\n private provider: SqliteProvider;\n\n /**\n * Database handle used by migrations and internal bookkeeping queries.\n */\n private db: SqliteDatabase;\n\n /**\n * Directory where migration modules are loaded from.\n */\n private migrationsDir: string;\n\n /**\n * Table that records successfully applied migrations.\n */\n private migrationsTable: string;\n\n /**\n * Table that stores the single-row migration lock.\n */\n private lockTable: string;\n\n /**\n * Migration modules loaded from disk in execution order.\n */\n private migrations: Migration<T>[] = [];\n\n /**\n * Whether internal tables and migration files have already been initialized.\n */\n private initialized = false;\n\n /**\n * File extensions considered when loading migration modules.\n */\n private fileExtensions: string[];\n\n constructor(options: MigratorOptions) {\n super();\n\n this.provider = createSqliteProvider(options.db);\n this.db = this.provider.db;\n this.migrationsDir = options.migrationsDir;\n this.migrationsTable = options.migrationsTable ?? 'schema_migrations';\n this.lockTable = options.migrationsLockTable ?? 'schema_migrations_lock';\n this.fileExtensions = options.fileExtensions ?? ['ts', 'js'];\n }\n\n /**\n * Ensures the `schema_migrations` and `schema_migrations_lock` tables exist,\n * and loads migration files from the migrations directory.\n */\n private async init(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n await this.initTables();\n await this.loadMigrationsFromDirectory();\n\n this.initialized = true;\n }\n\n /**\n * Initializes the `schema_migrations` and `schema_migrations_lock` tables.\n */\n private async initTables(): Promise<void> {\n try {\n // Create the migrations table if it doesn't exist\n await this.db.exec(`\n CREATE TABLE IF NOT EXISTS ${this.migrationsTable} (\n name TEXT PRIMARY KEY,\n executed_at TEXT NOT NULL, -- ISO string\n batch INTEGER NOT NULL\n )\n `);\n\n // Create the lock table if it doesn't exist\n await this.db.exec(`\n CREATE TABLE IF NOT EXISTS ${this.lockTable} (\n id INTEGER PRIMARY KEY CHECK (id = 1),\n locked INTEGER NOT NULL DEFAULT 0\n )\n `);\n\n // Ensure exactly one row in the lock table (id=1)\n await this.db.exec(`\n INSERT OR IGNORE INTO ${this.lockTable} (id, locked) VALUES (1, 0)\n `);\n\n // Load all migration files\n } catch (err) {\n throw new MigrationError('Failed to initialize migrator', err as Error);\n }\n }\n\n /**\n * Load migration files from the `migrationsDir`.\n * Migration files must export { up, down }.\n * The migrations are loaded in alphabetical order.\n */\n private async loadMigrationsFromDirectory(): Promise<void> {\n try {\n const entries = await fs.readdir(this.migrationsDir);\n // Filter and sort migration files alphabetically\n const migrationFiles = entries\n .filter((file) => {\n // Ignore .d.ts files\n if (file.endsWith('.d.ts')) {\n return false;\n }\n // Check if file has one of the allowed extensions\n return this.fileExtensions.some((ext) => file.endsWith(`.${ext}`));\n })\n .sort();\n\n const loadedMigrations: Migration<T>[] = [];\n for (const file of migrationFiles) {\n const fullPath = path.join(this.migrationsDir, file);\n\n let imported: {\n up: Migration<T>['up'];\n down: Migration<T>['down'];\n };\n\n try {\n imported = await import(pathToFileURL(fullPath).href);\n } catch (err) {\n throw new MigrationFileError(`Error loading migration \"${file}\": ${String(err)}`, err as Error);\n }\n\n const { up, down } = imported;\n if (typeof up !== 'function' || typeof down !== 'function') {\n throw new MigrationFileError(`Migration \"${file}\" must export \"up\" and \"down\" functions.`);\n }\n\n loadedMigrations.push({ name: file, up, down });\n }\n\n // Only update migrations array after all files are loaded successfully\n this.migrations = loadedMigrations;\n } catch (err) {\n throw err instanceof MigrationFileError ? err : new MigrationFileError('Failed to load migrations', err as Error);\n }\n }\n\n /**\n * Acquire a lock to prevent concurrent migrations.\n * Throws an error if the lock is already held.\n */\n private async acquireLock(): Promise<void> {\n try {\n await this.runTransaction(async () => {\n const row = (await this.db.prepare(`SELECT locked FROM ${this.lockTable} WHERE id = 1`).get()) as {\n locked: number;\n };\n\n if (row.locked === 1) {\n throw new MigrationLockError('Migration lock already held by another process.');\n }\n\n await this.db.prepare(`UPDATE ${this.lockTable} SET locked = 1 WHERE id = 1`).run();\n });\n } catch (err) {\n if (err instanceof MigrationLockError) {\n throw err;\n }\n\n throw new MigrationLockError('Failed to acquire migration lock', err as Error);\n }\n }\n\n /**\n * Release the migration lock.\n */\n private async releaseLock(): Promise<void> {\n try {\n await this.db.prepare(`UPDATE ${this.lockTable} SET locked = 0 WHERE id = 1`).run();\n } catch (err) {\n throw new MigrationLockError('Failed to release migration lock', err as Error);\n }\n }\n\n /**\n * Get the highest batch number.\n */\n private async getCurrentBatch(): Promise<number> {\n const row = (await this.db.prepare(`SELECT MAX(batch) as batch FROM ${this.migrationsTable}`).get()) as {\n batch: number | null;\n };\n return row?.batch ?? 0;\n }\n\n /**\n * Insert a record for an applied migration.\n */\n private async recordMigration(name: string, batch: number): Promise<void> {\n const executedAt = new Date().toISOString();\n await this.db\n .prepare(\n `\n INSERT INTO ${this.migrationsTable} (name, executed_at, batch)\n VALUES (?, ?, ?)\n `\n )\n .run(name, executedAt, batch);\n }\n\n /**\n * Delete a record for a migration that is being rolled back.\n */\n private async removeMigration(name: string, batch: number): Promise<void> {\n await this.db\n .prepare(\n `\n DELETE FROM ${this.migrationsTable}\n WHERE name = ? AND batch = ?\n `\n )\n .run(name, batch);\n }\n\n /**\n * Run SQL operations in a transaction.\n * @param fn The function to run in the transaction.\n */\n private async runTransaction(fn: () => MaybePromise<void>): Promise<void> {\n await this.provider.transaction(fn);\n }\n\n /**\n * Apply all pending migrations in a single batch.\n * Returns the names of applied migrations.\n */\n async apply(...args: ContextArg<T>): Promise<MigrationResult> {\n // Initialize the migrator\n try {\n await this.init();\n } catch (err) {\n return {\n success: false,\n error: err as Error,\n appliedMigrations: [],\n };\n }\n\n // Acquire lock\n try {\n await this.acquireLock();\n } catch (err) {\n return {\n success: false,\n error: err as Error,\n appliedMigrations: [],\n };\n }\n\n const appliedMigrations: string[] = [];\n try {\n const currentBatch = await this.getCurrentBatch();\n const nextBatch = currentBatch + 1;\n\n // Determine pending migrations: not present in schema_migrations\n const appliedNames = new Set(\n (await this.db.prepare(`SELECT name FROM ${this.migrationsTable}`).all()).map(\n (row) => (row as { name: string }).name\n )\n );\n\n // Get pending migrations, if any\n const pendingMigrations = this.migrations.filter((m) => !appliedNames.has(m.name));\n if (pendingMigrations.length === 0) {\n return { success: true, appliedMigrations };\n }\n\n // Perform the migration\n await this.runTransaction(async () => {\n for (const migration of pendingMigrations) {\n try {\n // Apply migration\n await migration.up(this.db, ...args);\n\n // Record migration\n await this.recordMigration(migration.name, nextBatch);\n appliedMigrations.push(migration.name);\n } catch (err) {\n throw new MigrationExecutionError(`Failed to apply migration \"${migration.name}\"`, err as Error);\n }\n }\n });\n\n for (const migrationName of appliedMigrations) {\n this.emit('migration:applied', migrationName, nextBatch);\n }\n\n return { success: true, appliedMigrations };\n } catch (error) {\n const err =\n error instanceof MigrationExecutionError\n ? error\n : new MigrationExecutionError('Migration failed', error as Error);\n return { success: false, error: err, appliedMigrations: [] };\n } finally {\n await this.releaseLock();\n }\n }\n\n /**\n * Roll back the most recent batch of migrations.\n * Returns the names of rolled back migrations.\n */\n async rollback(...args: ContextArg<T>): Promise<MigrationResult> {\n // Initialize the migrator\n try {\n await this.init();\n } catch (err) {\n return {\n success: false,\n error: err as Error,\n appliedMigrations: [],\n };\n }\n\n // Acquire lock\n try {\n await this.acquireLock();\n } catch (err) {\n return {\n success: false,\n error: err as Error,\n appliedMigrations: [],\n };\n }\n\n const appliedMigrations: string[] = [];\n try {\n // Check if there are migrations to rollback\n const currentBatch = await this.getCurrentBatch();\n if (currentBatch === 0) {\n return { success: true, appliedMigrations };\n }\n\n // Get migrations in the last batch, sorted descending\n const rows = (await this.db\n .prepare(\n `\n SELECT name\n FROM ${this.migrationsTable}\n WHERE batch = ?\n ORDER BY name DESC\n `\n )\n .all(currentBatch)) as { name: string }[];\n\n // No migrations found in the last batch\n if (rows.length === 0) {\n return { success: true, appliedMigrations };\n }\n\n // Perform the rollback\n await this.runTransaction(async () => {\n for (const row of rows) {\n const migration = this.migrations.find((m) => m.name === row.name);\n if (!migration) {\n throw new MigrationFileError(`Migration \"${row.name}\" not found.`);\n }\n\n try {\n // Revert migration\n await migration.down(this.db, ...args);\n\n // Remove migration record\n await this.removeMigration(migration.name, currentBatch);\n\n appliedMigrations.push(migration.name);\n } catch (err) {\n throw new MigrationExecutionError(`Failed to rollback migration \"${migration.name}\"`, err as Error);\n }\n }\n });\n\n for (const migrationName of appliedMigrations) {\n this.emit('migration:rollback', migrationName, currentBatch);\n }\n\n return { success: true, appliedMigrations };\n } catch (error) {\n const err =\n error instanceof MigrationExecutionError\n ? error\n : new MigrationExecutionError('Rollback failed', error as Error);\n return { success: false, error: err, appliedMigrations: [] };\n } finally {\n await this.releaseLock();\n }\n }\n\n /**\n * Get the status of migrations.\n * Returns:\n * - currentBatch: the highest batch number applied\n * - pending: number of migrations not yet applied\n * - applied: list of all applied migrations\n */\n async status(): Promise<MigrationStatus> {\n await this.init();\n\n try {\n const currentBatch = await this.getCurrentBatch();\n\n // Get all applied migrations\n const rows = (await this.db\n .prepare(\n `\n SELECT name, executed_at, batch\n FROM ${this.migrationsTable}\n ORDER BY batch ASC, name ASC\n `\n )\n .all()) as MigrationRecord[];\n\n // Determine pending migrations\n const appliedNames = new Set(rows.map((r) => r.name));\n const pending = this.migrations.length - appliedNames.size;\n\n return {\n currentBatch,\n pending,\n applied: rows,\n };\n } catch (err) {\n throw new MigrationError('Failed to get migration status', err as Error);\n }\n }\n\n /**\n * Plan the pending migrations without applying them.\n * Returns the next batch number and the list of pending migration names in order.\n */\n async plan(): Promise<MigrationPlan> {\n await this.init();\n\n try {\n const currentBatch = await this.getCurrentBatch();\n const nextBatch = currentBatch + 1;\n\n // Determine pending migrations: not present in schema_migrations\n const appliedNames = new Set(\n (await this.db.prepare(`SELECT name FROM ${this.migrationsTable}`).all()).map(\n (row) => (row as { name: string }).name\n )\n );\n\n const pendingMigrations = this.migrations.filter((m) => !appliedNames.has(m.name)).map((m) => m.name);\n\n return {\n nextBatch,\n pendingMigrations,\n };\n } catch (err) {\n throw new MigrationError('Failed to create migration plan', err as Error);\n }\n }\n}\n\nexport {\n MigrationError,\n MigrationExecutionError,\n MigrationFileError,\n MigrationLockError,\n} from './errors.js';\nexport type {\n BunSqliteDatabase,\n ContextArg,\n MaybePromise,\n Migration,\n MigrationPlan,\n MigrationRecord,\n MigrationResult,\n MigrationStatus,\n MigratorDatabase,\n MigratorOptions,\n SqliteDatabase,\n SqliteRunResult,\n SqliteStatement,\n SqliteTransaction,\n} from './types.js';\n","/**\n * Base error class for all sqlite-up errors\n */\nexport class MigrationError extends Error {\n constructor(\n message: string,\n public readonly cause?: Error\n ) {\n super(message);\n this.name = 'MigrationError';\n }\n}\n\n/**\n * Thrown when there's an issue with migration files\n */\nexport class MigrationFileError extends MigrationError {\n constructor(message: string, cause?: Error) {\n super(message, cause);\n this.name = 'MigrationFileError';\n }\n}\n\n/**\n * Thrown when there's a locking issue\n */\nexport class MigrationLockError extends MigrationError {\n constructor(message: string, cause?: Error) {\n super(message, cause);\n this.name = 'MigrationLockError';\n }\n}\n\n/**\n * Thrown when there's an issue during migration execution\n */\nexport class MigrationExecutionError extends MigrationError {\n constructor(message: string, cause?: Error) {\n super(message, cause);\n this.name = 'MigrationExecutionError';\n }\n}\n","import type { MaybePromise, SqliteDatabase } from '../types.js';\nimport type { SqliteProvider } from './types.js';\n\n/**\n * Creates a provider that wraps migration work in explicit SQL transactions.\n */\nexport function createManualTransactionProvider(db: SqliteDatabase): SqliteProvider {\n return {\n db,\n\n /**\n * Runs the callback between BEGIN IMMEDIATE and COMMIT, rolling back on failure.\n */\n transaction: async (fn: () => MaybePromise<void>): Promise<void> => {\n await db.exec('BEGIN IMMEDIATE');\n try {\n await fn();\n await db.exec('COMMIT');\n } catch (err) {\n try {\n await db.exec('ROLLBACK');\n } catch {\n // Preserve the original transaction failure.\n }\n throw err;\n }\n },\n };\n}\n","import type { SqliteDatabase } from '../types.js';\nimport { createManualTransactionProvider } from './manual-transaction.js';\nimport type { SqliteProvider } from './types.js';\n\n/**\n * Structural database shape used to identify better-sqlite3 connections.\n */\nexport type BetterSqlite3Database = SqliteDatabase & {\n transaction?: unknown;\n open?: boolean;\n};\n\n/**\n * Checks whether a value looks like a better-sqlite3 database instance.\n */\nexport function isBetterSqlite3Database(db: unknown): db is BetterSqlite3Database {\n const candidate = db as Partial<BetterSqlite3Database>;\n return (\n typeof candidate.exec === 'function' &&\n typeof candidate.prepare === 'function' &&\n typeof candidate.transaction === 'function' &&\n typeof candidate.open === 'boolean'\n );\n}\n\n/**\n * Creates a sqlite-up provider for better-sqlite3 database instances.\n */\nexport function createBetterSqlite3Provider(db: BetterSqlite3Database): SqliteProvider {\n return createManualTransactionProvider(db);\n}\n","import type { BunSqliteDatabase, MaybePromise, SqliteDatabase, SqliteTransaction } from '../types.js';\nimport type { SqliteProvider } from './types.js';\n\n/**\n * SQLite database facade whose transactions may complete asynchronously.\n */\ninterface AsyncTransactionalSqliteDatabase extends SqliteDatabase {\n /**\n * Creates a transaction runner that can await asynchronous transaction work.\n */\n transaction<Args extends unknown[], Result>(\n fn: (...args: Args) => MaybePromise<Result>\n ): SqliteTransaction<Args, Result>;\n}\n\n/**\n * Executes SQL through Bun SQL and normalizes empty parameter lists.\n */\nasync function executeBunSql(client: BunSqliteDatabase, sql: string, params: unknown[] = []): Promise<unknown[]> {\n return await client.unsafe(sql, params.length > 0 ? params : undefined);\n}\n\n/**\n * Checks whether a value looks like Bun's Promise-based SQL client for SQLite.\n */\nexport function isBunSqlDatabase(db: unknown): db is BunSqliteDatabase {\n const candidate = db as Partial<BunSqliteDatabase>;\n return typeof candidate.unsafe === 'function' && typeof (candidate as Partial<SqliteDatabase>).exec !== 'function';\n}\n\n/**\n * Creates a sqlite-up provider for Bun SQL SQLite clients.\n */\nexport function createBunSqlProvider(rootClient: BunSqliteDatabase): SqliteProvider {\n let activeClient = rootClient;\n\n const db: AsyncTransactionalSqliteDatabase = {\n /**\n * Executes a SQL statement through the currently active Bun SQL client.\n */\n exec: async (sql: string) => {\n await executeBunSql(activeClient, sql);\n },\n\n /**\n * Creates a prepared-statement facade backed by Bun SQL unsafe execution.\n */\n prepare: (sql: string) => ({\n /**\n * Runs the statement and returns all rows.\n */\n all: (...params: unknown[]) => executeBunSql(activeClient, sql, params),\n\n /**\n * Runs the statement and returns the first row.\n */\n get: async (...params: unknown[]) => {\n const rows = await executeBunSql(activeClient, sql, params);\n return rows[0];\n },\n\n /**\n * Runs the statement for side effects and returns the driver result.\n */\n run: (...params: unknown[]) => executeBunSql(activeClient, sql, params),\n }),\n\n /**\n * Creates a transaction runner using Bun SQL native transactions when available.\n */\n transaction: <Args extends unknown[], Result>(fn: (...args: Args) => MaybePromise<Result>) => {\n /**\n * Executes the transaction callback with the active transaction client.\n */\n const run = async (...args: Args): Promise<Result> => {\n if (typeof rootClient.begin === 'function') {\n return await rootClient.begin(async (tx) => {\n const previousClient = activeClient;\n activeClient = tx;\n\n try {\n return await fn(...args);\n } finally {\n activeClient = previousClient;\n }\n });\n }\n\n await db.exec('BEGIN');\n try {\n const result = await fn(...args);\n await db.exec('COMMIT');\n return result;\n } catch (err) {\n try {\n await db.exec('ROLLBACK');\n } catch {\n // Preserve the original transaction failure.\n }\n throw err;\n }\n };\n\n return run;\n },\n };\n\n return {\n db,\n\n /**\n * Runs migration work inside the Bun SQL transaction facade.\n */\n transaction: async (fn: () => MaybePromise<void>) => {\n const transaction = db.transaction(fn);\n await transaction();\n },\n };\n}\n","import type { SqliteDatabase, SqliteStatement } from '../types.js';\nimport { createManualTransactionProvider } from './manual-transaction.js';\nimport type { SqliteProvider } from './types.js';\n\n/**\n * Structural database shape used to identify Bun's synchronous SQLite client.\n */\nexport type BunSqliteSyncDatabase = SqliteDatabase & {\n query?: (sql: string) => SqliteStatement;\n};\n\n/**\n * Checks whether a value looks like a Bun SQLite database instance.\n */\nexport function isBunSqliteDatabase(db: unknown): db is BunSqliteSyncDatabase {\n const candidate = db as Partial<BunSqliteSyncDatabase>;\n return (\n typeof candidate.exec === 'function' &&\n typeof candidate.prepare === 'function' &&\n typeof candidate.query === 'function'\n );\n}\n\n/**\n * Creates a sqlite-up provider for Bun SQLite database instances.\n */\nexport function createBunSqliteProvider(db: BunSqliteSyncDatabase): SqliteProvider {\n return createManualTransactionProvider(db);\n}\n","import type { SqliteDatabase } from '../types.js';\nimport { createManualTransactionProvider } from './manual-transaction.js';\nimport type { SqliteProvider } from './types.js';\n\n/**\n * Structural database shape used to identify Node's node:sqlite DatabaseSync.\n */\nexport type NodeSqliteDatabase = SqliteDatabase & {\n isOpen?: boolean;\n};\n\n/**\n * Checks whether a value looks like a node:sqlite database instance.\n */\nexport function isNodeSqliteDatabase(db: unknown): db is NodeSqliteDatabase {\n const candidate = db as Partial<NodeSqliteDatabase>;\n return (\n typeof candidate.exec === 'function' &&\n typeof candidate.prepare === 'function' &&\n typeof candidate.isOpen === 'boolean'\n );\n}\n\n/**\n * Creates a sqlite-up provider for node:sqlite database instances.\n */\nexport function createNodeSqliteProvider(db: NodeSqliteDatabase): SqliteProvider {\n return createManualTransactionProvider(db);\n}\n","import type { MigratorDatabase, SqliteDatabase } from '../types.js';\nimport { createBetterSqlite3Provider, isBetterSqlite3Database } from './better-sqlite3.js';\nimport { createBunSqlProvider, isBunSqlDatabase } from './bun-sql.js';\nimport { createBunSqliteProvider, isBunSqliteDatabase } from './bun-sqlite.js';\nimport { createManualTransactionProvider } from './manual-transaction.js';\nimport { createNodeSqliteProvider, isNodeSqliteDatabase } from './node-sqlite.js';\nimport type { SqliteProvider } from './types.js';\n\n/**\n * Checks for the minimal SQLite database surface sqlite-up can use directly.\n */\nfunction isSqliteDatabase(db: unknown): db is SqliteDatabase {\n const candidate = db as Partial<SqliteDatabase>;\n return typeof candidate.exec === 'function' && typeof candidate.prepare === 'function';\n}\n\n/**\n * Creates the best provider adapter for a supported SQLite database client.\n */\nexport function createSqliteProvider(db: MigratorDatabase): SqliteProvider {\n if (isBunSqlDatabase(db)) {\n return createBunSqlProvider(db);\n }\n\n if (isBunSqliteDatabase(db)) {\n return createBunSqliteProvider(db);\n }\n\n if (isBetterSqlite3Database(db)) {\n return createBetterSqlite3Provider(db);\n }\n\n if (isNodeSqliteDatabase(db)) {\n return createNodeSqliteProvider(db);\n }\n\n if (isSqliteDatabase(db)) {\n return createManualTransactionProvider(db);\n }\n\n if (typeof db === 'object' && db !== null) {\n return createManualTransactionProvider(db as SqliteDatabase);\n }\n\n throw new TypeError('Unsupported SQLite database provider.');\n}\n\nexport { createBetterSqlite3Provider, isBetterSqlite3Database } from './better-sqlite3.js';\nexport { createBunSqlProvider, isBunSqlDatabase } from './bun-sql.js';\nexport { createBunSqliteProvider, isBunSqliteDatabase } from './bun-sqlite.js';\nexport { createNodeSqliteProvider, isNodeSqliteDatabase } from './node-sqlite.js';\nexport type { SqliteProvider } from './types.js';\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { SqliteDatabase } from '../types.js';
|
|
2
|
+
import type { SqliteProvider } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Structural database shape used to identify better-sqlite3 connections.
|
|
5
|
+
*/
|
|
6
|
+
export type BetterSqlite3Database = SqliteDatabase & {
|
|
7
|
+
transaction?: unknown;
|
|
8
|
+
open?: boolean;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Checks whether a value looks like a better-sqlite3 database instance.
|
|
12
|
+
*/
|
|
13
|
+
export declare function isBetterSqlite3Database(db: unknown): db is BetterSqlite3Database;
|
|
14
|
+
/**
|
|
15
|
+
* Creates a sqlite-up provider for better-sqlite3 database instances.
|
|
16
|
+
*/
|
|
17
|
+
export declare function createBetterSqlite3Provider(db: BetterSqlite3Database): SqliteProvider;
|
|
18
|
+
//# sourceMappingURL=better-sqlite3.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"better-sqlite3.d.ts","sourceRoot":"","sources":["../../src/providers/better-sqlite3.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG,cAAc,GAAG;IACnD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,OAAO,GAAG,EAAE,IAAI,qBAAqB,CAQhF;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,EAAE,EAAE,qBAAqB,GAAG,cAAc,CAErF"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { BunSqliteDatabase } from '../types.js';
|
|
2
|
+
import type { SqliteProvider } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Checks whether a value looks like Bun's Promise-based SQL client for SQLite.
|
|
5
|
+
*/
|
|
6
|
+
export declare function isBunSqlDatabase(db: unknown): db is BunSqliteDatabase;
|
|
7
|
+
/**
|
|
8
|
+
* Creates a sqlite-up provider for Bun SQL SQLite clients.
|
|
9
|
+
*/
|
|
10
|
+
export declare function createBunSqlProvider(rootClient: BunSqliteDatabase): SqliteProvider;
|
|
11
|
+
//# sourceMappingURL=bun-sql.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bun-sql.d.ts","sourceRoot":"","sources":["../../src/providers/bun-sql.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAmD,MAAM,aAAa,CAAC;AACtG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAqBjD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,OAAO,GAAG,EAAE,IAAI,iBAAiB,CAGrE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,iBAAiB,GAAG,cAAc,CAqFlF"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { SqliteDatabase, SqliteStatement } from '../types.js';
|
|
2
|
+
import type { SqliteProvider } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Structural database shape used to identify Bun's synchronous SQLite client.
|
|
5
|
+
*/
|
|
6
|
+
export type BunSqliteSyncDatabase = SqliteDatabase & {
|
|
7
|
+
query?: (sql: string) => SqliteStatement;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Checks whether a value looks like a Bun SQLite database instance.
|
|
11
|
+
*/
|
|
12
|
+
export declare function isBunSqliteDatabase(db: unknown): db is BunSqliteSyncDatabase;
|
|
13
|
+
/**
|
|
14
|
+
* Creates a sqlite-up provider for Bun SQLite database instances.
|
|
15
|
+
*/
|
|
16
|
+
export declare function createBunSqliteProvider(db: BunSqliteSyncDatabase): SqliteProvider;
|
|
17
|
+
//# sourceMappingURL=bun-sqlite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bun-sqlite.d.ts","sourceRoot":"","sources":["../../src/providers/bun-sqlite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG,cAAc,GAAG;IACnD,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,eAAe,CAAC;CAC1C,CAAC;AAEF;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,OAAO,GAAG,EAAE,IAAI,qBAAqB,CAO5E;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,qBAAqB,GAAG,cAAc,CAEjF"}
|