boltstore 0.6.2 → 0.6.3

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.
Files changed (54) hide show
  1. package/README.md +19 -8
  2. package/dist/audit.d.ts.map +1 -1
  3. package/dist/audit.js +10 -2
  4. package/dist/audit.js.map +1 -1
  5. package/dist/auth/jwt.js +1 -1
  6. package/dist/bin.js +4 -4
  7. package/dist/bin.js.map +1 -1
  8. package/dist/cli/admin.d.ts +2 -0
  9. package/dist/cli/admin.d.ts.map +1 -0
  10. package/dist/cli/admin.js +65 -0
  11. package/dist/cli/admin.js.map +1 -0
  12. package/dist/cli/applications.d.ts +2 -0
  13. package/dist/cli/applications.d.ts.map +1 -0
  14. package/dist/cli/applications.js +105 -0
  15. package/dist/cli/applications.js.map +1 -0
  16. package/dist/cli/backup.d.ts +3 -0
  17. package/dist/cli/backup.d.ts.map +1 -0
  18. package/dist/cli/backup.js +49 -0
  19. package/dist/cli/backup.js.map +1 -0
  20. package/dist/cli/help.d.ts +3 -0
  21. package/dist/cli/help.d.ts.map +1 -0
  22. package/dist/cli/help.js +36 -0
  23. package/dist/cli/help.js.map +1 -0
  24. package/dist/cli/import-export.d.ts +3 -0
  25. package/dist/cli/import-export.d.ts.map +1 -0
  26. package/dist/cli/import-export.js +80 -0
  27. package/dist/cli/import-export.js.map +1 -0
  28. package/dist/cli/init.d.ts +4 -0
  29. package/dist/cli/init.d.ts.map +1 -0
  30. package/dist/cli/init.js +105 -0
  31. package/dist/cli/init.js.map +1 -0
  32. package/dist/cli/migrate.d.ts +4 -0
  33. package/dist/cli/migrate.d.ts.map +1 -0
  34. package/dist/cli/migrate.js +77 -0
  35. package/dist/cli/migrate.js.map +1 -0
  36. package/dist/cli/serve.d.ts +2 -0
  37. package/dist/cli/serve.d.ts.map +1 -0
  38. package/dist/cli/serve.js +33 -0
  39. package/dist/cli/serve.js.map +1 -0
  40. package/dist/cli/status.d.ts +2 -0
  41. package/dist/cli/status.d.ts.map +1 -0
  42. package/dist/cli/status.js +15 -0
  43. package/dist/cli/status.js.map +1 -0
  44. package/dist/cli.d.ts +0 -10
  45. package/dist/cli.d.ts.map +1 -1
  46. package/dist/cli.js +95 -402
  47. package/dist/cli.js.map +1 -1
  48. package/dist/db/manager.d.ts +21 -21
  49. package/dist/db/manager.d.ts.map +1 -1
  50. package/dist/db/manager.js +97 -65
  51. package/dist/db/manager.js.map +1 -1
  52. package/dist/entry.js +4 -4
  53. package/dist/entry.js.map +1 -1
  54. package/package.json +2 -2
package/dist/cli.js CHANGED
@@ -1,414 +1,107 @@
1
- /**
2
- * CLI entry point for Boltstore.
3
- *
4
- * Provides commands for starting the server, managing the database,
5
- * and performing administrative tasks.
6
- *
7
- * Usage: boltstore <command> [options]
8
- *
9
- * @module boltstore/cli
10
- */
11
- import { DatabaseManager } from "./db/manager";
12
- import { createServer, stopServerBackgroundTasks } from "./server";
13
- import { loadConfig } from "./config";
14
- import { listMigrations, applyMigrations, rollbackLastMigration } from "./migrations";
15
- import { importData, exportData } from "./admin/import-export";
16
- import { createBackup, restoreFromFile } from "./admin/backup";
17
- import { createAdminUser } from "./auth/users";
18
- import { info, success, warn, error as cliError, out } from "./cli-style";
19
- const HELP = `
20
- ⚡ boltstore — Lightweight backend-as-a-service
21
-
22
- Usage: boltstore <command> [options]
23
-
24
- Commands:
25
- serve Start the HTTP server
26
- init [--json] Generate a config file (boltstore.yaml by default)
27
- admin init Create an admin account interactively
28
- migrate [--db <path>] [--dir <path>] Run pending migrations
29
- migrate:rollback [--db <path>] Rollback last migration
30
- migrations [--db <path>] List migration status
31
- import <collection> <file> [--db <path>] [--format csv|json] Import data
32
- export <collection> [--db <path>] [--format csv|json] Export data (stdout)
33
- backup [--db <path>] [--label <text>] Create a backup snapshot
34
- restore <file> [--db <path>] Restore from a backup file
35
- status Display server health and stats
36
-
37
- Options:
38
- --port <number> HTTP server port (default: 8080)
39
- --db <path> Database path or data directory
40
- --config <path> Path to config file
41
- --log-level <level> Log level: debug, info, warn, error
42
- --timezone <tz> Server timezone
43
- --format <fmt> Format for import/export: csv or json
44
- --help Show this help
45
- `;
46
- export async function runCli(args) {
47
- const command = args[0];
48
- // Commands that don't require a config file
49
- const NO_CONFIG_COMMANDS = new Set(["init", "help", "--help", "-h"]);
50
- if (!NO_CONFIG_COMMANDS.has(command)) {
51
- let configExists = false;
52
- for (const candidate of ["boltstore.yaml", "boltstore.yml", "boltstore.json"]) {
53
- try {
54
- if (await Bun.file(candidate).exists()) {
55
- configExists = true;
56
- break;
57
- }
58
- }
59
- catch {
60
- // Skip
61
- }
1
+ import { error as cliError, out } from "./cli-style";
2
+ import { HELP, deprecateCommand } from "./cli/help";
3
+ import { serveCommand } from "./cli/serve";
4
+ import { initCommand } from "./cli/init";
5
+ import { applicationsCommand } from "./cli/applications";
6
+ import { adminCommand } from "./cli/admin";
7
+ import { migrateCommand, migrateRollbackCommand, migrateListCommand } from "./cli/migrate";
8
+ import { importCommand, exportCommand } from "./cli/import-export";
9
+ import { backupCommand, restoreCommand } from "./cli/backup";
10
+ import { statusCommand } from "./cli/status";
11
+ const NO_CONFIG_COMMANDS = new Set(["init", "admin", "help", "--help", "-h"]);
12
+ async function checkConfigExists() {
13
+ for (const candidate of ["boltstore.yaml", "boltstore.yml", "boltstore.json"]) {
14
+ try {
15
+ if (await Bun.file(candidate).exists())
16
+ return;
62
17
  }
63
- if (!configExists) {
64
- cliError("No config file found. Run boltstore init first to create one.");
65
- process.exit(1);
18
+ catch {
19
+ // Skip
66
20
  }
67
21
  }
68
- switch (command) {
69
- case "serve": {
70
- const config = await loadConfig();
71
- const manager = new DatabaseManager({ dataDir: config.databasePath });
72
- const server = createServer({
73
- port: config.port,
74
- manager,
75
- auth: { secret: config.jwtSecret },
76
- cors: {
77
- origins: config.corsOrigins,
78
- methods: config.corsMethods,
79
- headers: config.corsHeaders,
80
- },
81
- rateLimit: {
82
- public: config.rateLimitPublic,
83
- auth: config.rateLimitAuth,
84
- admin: config.rateLimitAdmin,
85
- windowSeconds: config.rateLimitWindowSeconds,
86
- },
87
- maxBodySize: config.maxBodySize,
88
- requestTimeoutMs: config.requestTimeoutMs,
89
- maxBatchSize: config.maxBatchSize,
90
- trustedProxies: config.trustedProxies,
91
- });
92
- info(`Server running on http://localhost:${config.port}`);
93
- info(`Data directory: ${config.databasePath}`);
94
- process.on("SIGINT", () => { info("Shutting down..."); stopServerBackgroundTasks(); manager.close(); server.stop(); process.exit(0); });
95
- process.on("SIGTERM", () => { info("Shutting down..."); stopServerBackgroundTasks(); manager.close(); server.stop(); process.exit(0); });
96
- break;
97
- }
98
- case "init": {
99
- const asJson = args.includes("--json");
100
- const jwtSecret = crypto.randomUUID().replace(/-/g, "") + crypto.randomUUID().replace(/-/g, "");
101
- const config = {
102
- port: 8080,
103
- databasePath: "./data",
104
- jwtSecret,
105
- rateLimitPublic: 100,
106
- rateLimitAuth: 1000,
107
- rateLimitAdmin: 500,
108
- rateLimitWindowSeconds: 60,
109
- serverTimezone: "UTC",
110
- corsOrigins: [],
111
- corsMethods: ["GET", "POST", "PATCH", "DELETE", "OPTIONS"],
112
- corsHeaders: ["Content-Type", "Authorization"],
113
- logLevel: "info",
114
- maxBodySize: 1048576,
115
- requestTimeoutMs: 30000,
116
- maxBatchSize: 1000,
117
- queryTimeoutMs: 0,
118
- trustedProxies: [],
119
- };
120
- if (asJson) {
121
- await Bun.write("boltstore.json", JSON.stringify(config, null, 2));
122
- success("Created boltstore.json");
123
- }
124
- else {
125
- const yaml = `# Boltstore configuration
126
- port: ${config.port}
127
- databasePath: ${config.databasePath}
128
- jwtSecret: "${config.jwtSecret}"
129
- rateLimitPublic: ${config.rateLimitPublic}
130
- rateLimitAuth: ${config.rateLimitAuth}
131
- rateLimitAdmin: ${config.rateLimitAdmin}
132
- rateLimitWindowSeconds: ${config.rateLimitWindowSeconds}
133
- serverTimezone: ${config.serverTimezone}
134
- corsOrigins:
135
- corsMethods:
136
- - GET
137
- - POST
138
- - PATCH
139
- - DELETE
140
- - OPTIONS
141
- corsHeaders:
142
- - Content-Type
143
- - Authorization
144
- logLevel: ${config.logLevel}
145
- maxBodySize: ${config.maxBodySize}
146
- requestTimeoutMs: ${config.requestTimeoutMs}
147
- maxBatchSize: ${config.maxBatchSize}
148
- queryTimeoutMs: ${config.queryTimeoutMs}
149
- trustedProxies:
150
- `;
151
- await Bun.write("boltstore.yaml", yaml);
152
- success("Created boltstore.yaml");
153
- }
154
- warn("A random JWT secret was generated. In production, set a strong JWT_SECRET and keep it secret.");
155
- break;
156
- }
157
- case "admin": {
158
- const subcommand = args[1];
159
- if (subcommand === "init") {
160
- const { prompt, promptPassword } = await import("./prompt");
161
- out("");
162
- info("Create an admin account for the Boltstore server.");
163
- const name = (await prompt(" Name (optional): ")) || undefined;
164
- const email = await prompt(" Email: ");
165
- const password = await promptPassword(" Password (min 8 chars): ");
166
- if (!email || !password) {
167
- cliError("Email and password are required.");
168
- break;
169
- }
170
- const config = await loadConfig();
171
- const manager = new DatabaseManager({ dataDir: config.databasePath });
172
- try {
173
- const metaPool = manager.getMetaPool();
174
- const user = await createAdminUser(metaPool, email.trim(), password, name?.trim() || undefined);
175
- out("");
176
- success(`Admin account created (source: ${user.source}).`);
177
- out(` ID: ${user.id}`);
178
- out(` Email: ${user.email}`);
179
- if (user.name)
180
- out(` Name: ${user.name}`);
181
- out("");
182
- info("You can now log in at POST /api/_system/auth/login");
183
- out(` { "email": "${user.email}", "password": "..." }`);
184
- out("");
185
- }
186
- finally {
187
- manager.close();
188
- }
189
- }
190
- else {
191
- cliError("Usage: boltstore admin init");
192
- }
193
- break;
194
- }
195
- case "migrate": {
196
- const config = await loadConfig();
197
- const dbName = args.includes("--db") ? args[args.indexOf("--db") + 1] : "default";
198
- const migrationDir = args.includes("--dir") ? args[args.indexOf("--dir") + 1] : "./migrations";
199
- const manager = new DatabaseManager({ dataDir: config.databasePath });
200
- try {
201
- if (!manager.exists(dbName)) {
202
- manager.createDatabase(dbName);
203
- }
204
- const pool = manager.get(dbName);
205
- const result = await applyMigrations(pool, migrationDir);
206
- if (result.applied.length === 0) {
207
- info("No pending migrations.");
208
- }
209
- else {
210
- success(`Applied ${result.applied.length} migration(s):`);
211
- for (const name of result.applied) {
212
- out(` ✓ ${name}`);
213
- }
214
- }
215
- }
216
- finally {
217
- manager.close();
218
- }
219
- break;
220
- }
221
- case "migrate:rollback": {
222
- const config = await loadConfig();
223
- const dbName = args.includes("--db") ? args[args.indexOf("--db") + 1] : "default";
224
- const manager = new DatabaseManager({ dataDir: config.databasePath });
225
- try {
226
- if (!manager.exists(dbName)) {
227
- cliError(`Database "${dbName}" not found.`);
228
- break;
229
- }
230
- const pool = manager.get(dbName);
231
- const result = rollbackLastMigration(pool);
232
- if (result.rolledBack) {
233
- success(`Rolled back: ${result.rolledBack}`);
234
- }
235
- else {
236
- info("No migrations to roll back.");
237
- }
238
- }
239
- finally {
240
- manager.close();
241
- }
242
- break;
243
- }
244
- case "migrations": {
245
- const config = await loadConfig();
246
- const dbName = args.includes("--db") ? args[args.indexOf("--db") + 1] : "default";
247
- const manager = new DatabaseManager({ dataDir: config.databasePath });
248
- try {
249
- if (!manager.exists(dbName)) {
250
- cliError(`Database "${dbName}" not found.`);
251
- break;
252
- }
253
- const pool = manager.get(dbName);
254
- const migrations = listMigrations(pool);
255
- if (migrations.length === 0) {
256
- info("No migrations applied.");
257
- }
258
- else {
259
- out(`Applied migrations (${migrations.length}):`);
260
- for (const m of migrations) {
261
- out(` ${m.name} — ${m.appliedAt}`);
262
- }
263
- }
264
- }
265
- finally {
266
- manager.close();
267
- }
268
- break;
22
+ cliError("No config file found. Run boltstore init first to create one.");
23
+ process.exit(1);
24
+ }
25
+ export async function runCli(args) {
26
+ const command = args[0];
27
+ try {
28
+ if (!NO_CONFIG_COMMANDS.has(command)) {
29
+ await checkConfigExists();
269
30
  }
270
- case "import": {
271
- const collection = args[1];
272
- const filePath = args[2];
273
- if (!collection || !filePath) {
274
- cliError("Usage: boltstore import <collection> <file> [--db <path>] [--format csv|json]");
31
+ switch (command) {
32
+ case "serve":
33
+ await serveCommand();
275
34
  break;
276
- }
277
- const config = await loadConfig();
278
- const dbName = args.includes("--db") ? args[args.indexOf("--db") + 1] : "default";
279
- const formatArg = args.includes("--format") ? args[args.indexOf("--format") + 1] : undefined;
280
- let format;
281
- if (formatArg === "csv")
282
- format = "csv";
283
- else if (formatArg === "json")
284
- format = "json";
285
- else {
286
- if (filePath.endsWith(".csv"))
287
- format = "csv";
288
- else
289
- format = "json";
290
- }
291
- const manager = new DatabaseManager({ dataDir: config.databasePath });
292
- try {
293
- if (!manager.exists(dbName)) {
294
- manager.createDatabase(dbName);
295
- }
296
- const input = await Bun.file(filePath).text();
297
- const pool = manager.get(dbName);
298
- const result = importData(pool, collection, input, { format, autoCreate: true });
299
- if (result.collection) {
300
- info(`Created collection "${collection}" with auto-detected schema.`);
301
- }
302
- success(`Imported ${result.imported} record(s).`);
303
- if (result.failed > 0) {
304
- warn(`${result.failed} row(s) failed validation.`);
305
- if (result.errors) {
306
- for (const err of result.errors) {
307
- cliError(`Row ${err.row + 1}: ${err.message}`);
308
- }
309
- }
310
- }
311
- }
312
- finally {
313
- manager.close();
314
- }
315
- break;
316
- }
317
- case "export": {
318
- const collection = args[1];
319
- if (!collection) {
320
- cliError("Usage: boltstore export <collection> [--db <path>] [--format csv|json]");
35
+ case "init":
36
+ await initCommand(args);
321
37
  break;
322
- }
323
- const config = await loadConfig();
324
- const dbName = args.includes("--db") ? args[args.indexOf("--db") + 1] : "default";
325
- const formatArg = args.includes("--format") ? args[args.indexOf("--format") + 1] : "json";
326
- const format = (formatArg === "csv" ? "csv" : "json");
327
- const manager = new DatabaseManager({ dataDir: config.databasePath });
328
- try {
329
- if (!manager.exists(dbName)) {
330
- cliError(`Database "${dbName}" not found.`);
331
- break;
332
- }
333
- const pool = manager.get(dbName);
334
- const result = exportData(pool, collection, { format });
335
- if (format === "csv") {
336
- process.stdout.write(result.data);
337
- }
338
- else {
339
- out(result.data);
340
- }
341
- }
342
- finally {
343
- manager.close();
344
- }
345
- break;
346
- }
347
- case "backup": {
348
- const config = await loadConfig();
349
- const dbName = args.includes("--db") ? args[args.indexOf("--db") + 1] : "default";
350
- const label = args.includes("--label") ? args[args.indexOf("--label") + 1] : undefined;
351
- const manager = new DatabaseManager({ dataDir: config.databasePath });
352
- try {
353
- if (!manager.exists(dbName)) {
354
- cliError(`Database "${dbName}" not found.`);
355
- break;
356
- }
357
- const pool = manager.get(dbName);
358
- const result = createBackup(pool, dbName, manager.getDataDir(), { label });
359
- success(`Backup created: ${result.id}`);
360
- out(` Path: ${result.path}`);
361
- out(` Size: ${result.sizeBytes} bytes`);
362
- if (result.label)
363
- out(` Label: ${result.label}`);
364
- }
365
- finally {
366
- manager.close();
367
- }
368
- break;
369
- }
370
- case "restore": {
371
- const filePath = args[1];
372
- if (!filePath) {
373
- cliError("Usage: boltstore restore <file> [--db <path>]");
38
+ case "applications":
39
+ await applicationsCommand(args);
40
+ break;
41
+ case "admin":
42
+ await adminCommand(args);
43
+ break;
44
+ case "migrate":
45
+ await migrateCommand(args);
374
46
  break;
375
- }
376
- const config = await loadConfig();
377
- const dbName = args.includes("--db") ? args[args.indexOf("--db") + 1] : "default";
378
- const manager = new DatabaseManager({ dataDir: config.databasePath });
379
- try {
380
- if (!manager.exists(dbName)) {
381
- cliError(`Database "${dbName}" not found.`);
382
- break;
383
- }
384
- const result = restoreFromFile(manager, dbName, filePath);
385
- success(`Restored database "${result.database}" from ${result.backupPath}`);
386
- out(` Restored at: ${result.restoredAt}`);
387
- }
388
- finally {
389
- manager.close();
390
- }
391
- break;
47
+ case "migrate:rollback":
48
+ await migrateRollbackCommand(args);
49
+ break;
50
+ case "migrate:list":
51
+ await migrateListCommand(args);
52
+ break;
53
+ case "migrations":
54
+ deprecateCommand("migrations", "migrate:list");
55
+ await migrateListCommand(args);
56
+ break;
57
+ case "db:import":
58
+ await importCommand(args);
59
+ break;
60
+ case "import":
61
+ deprecateCommand("import", "db:import");
62
+ await importCommand(args);
63
+ break;
64
+ case "db:export":
65
+ await exportCommand(args);
66
+ break;
67
+ case "export":
68
+ deprecateCommand("export", "db:export");
69
+ await exportCommand(args);
70
+ break;
71
+ case "db:backup":
72
+ await backupCommand(args);
73
+ break;
74
+ case "backup":
75
+ deprecateCommand("backup", "db:backup");
76
+ await backupCommand(args);
77
+ break;
78
+ case "db:restore":
79
+ await restoreCommand(args);
80
+ break;
81
+ case "restore":
82
+ deprecateCommand("restore", "db:restore");
83
+ await restoreCommand(args);
84
+ break;
85
+ case "status":
86
+ await statusCommand();
87
+ break;
88
+ case "--help":
89
+ case "-h":
90
+ case "help":
91
+ default:
92
+ out(HELP);
93
+ break;
94
+ }
95
+ }
96
+ catch (err) {
97
+ const e = err;
98
+ if (e.message) {
99
+ cliError(e.message);
392
100
  }
393
- case "status": {
394
- const config = await loadConfig();
395
- const healthUrl = `http://localhost:${config.port}/api/health`;
396
- try {
397
- const response = await fetch(healthUrl);
398
- const body = await response.json();
399
- out(JSON.stringify(body.data, null, 2));
400
- }
401
- catch {
402
- cliError("Server is not running.");
403
- }
404
- break;
101
+ else {
102
+ cliError(String(err));
405
103
  }
406
- case "--help":
407
- case "-h":
408
- case "help":
409
- default:
410
- out(HELP);
411
- break;
104
+ process.exit(1);
412
105
  }
413
106
  }
414
107
  //# sourceMappingURL=cli.js.map
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -8,22 +8,30 @@
8
8
  * db/
9
9
  * _boltstore.db (server meta database — _databases table)
10
10
  * files/ (future: system-level file storage)
11
- * {app}/
11
+ * dbs_{id}/
12
12
  * db/
13
- * {app}.db (application database)
13
+ * dbs_{id}.db (application database, directory named by database ID)
14
14
  * files/ (future: per-app file storage)
15
15
  * ```
16
16
  *
17
+ * Each database gets a unique ID (dbs_ prefix) on creation. The name is
18
+ * kept for display/alias purposes, but the ID is the primary identifier
19
+ * in URLs and file paths.
20
+ *
17
21
  * @module boltstore/db/manager
18
22
  */
19
23
  import { DatabasePool } from "./pool";
20
24
  export interface DatabaseInfo {
21
- /** Application (database) name. */
25
+ /** Unique database ID (dbs_ prefix). */
26
+ id: string;
27
+ /** Human-readable name for display. */
22
28
  name: string;
23
29
  /** Path to the SQLite file. */
24
30
  path: string;
25
31
  /** ISO-8601 timestamp of when the database was created. */
26
32
  createdAt: string;
33
+ /** ISO-8601 timestamp of last update. */
34
+ updatedAt?: string;
27
35
  }
28
36
  export interface ManagerConfig {
29
37
  /** Directory where all database files are stored. Default: "./data". */
@@ -41,34 +49,29 @@ export declare class DatabaseManager {
41
49
  private appPools;
42
50
  constructor(config?: ManagerConfig);
43
51
  /**
44
- * Get (or lazily create) a DatabasePool for the given application.
45
- *
46
- * If the application is not registered in `_databases`, this will throw.
47
- * The application must be explicitly created via `createDatabase()` first.
52
+ * Resolve a database pool by ID or name.
53
+ * If the identifier starts with "dbs_", it's treated as an ID; otherwise as a name.
48
54
  */
49
- get(name: string): DatabasePool;
55
+ get(nameOrId: string): DatabasePool;
50
56
  /**
51
- * Create a new application database.
57
+ * Create a new application database with a unique ID.
52
58
  *
53
59
  * This is an **admin-only** operation. A new SQLite file is created
54
- * and registered in the `_databases` metadata table.
60
+ * in a directory named by the database ID, and registered in `_databases`.
55
61
  */
56
62
  createDatabase(name: string): DatabaseInfo;
57
63
  /**
58
- * Delete an application database.
59
- *
60
- * This is an **admin-only** operation. The SQLite file is closed and removed,
61
- * and the entry is deleted from `_databases`.
64
+ * Delete an application database by ID or name.
62
65
  */
63
- deleteDatabase(name: string): void;
66
+ deleteDatabase(nameOrId: string): void;
64
67
  /**
65
68
  * List all registered application databases.
66
69
  */
67
70
  listDatabases(): DatabaseInfo[];
68
71
  /**
69
- * Check if a database exists (metadata check only, no pool created).
72
+ * Check if a database exists by ID or name (metadata check only, no pool created).
70
73
  */
71
- exists(name: string): boolean;
74
+ exists(nameOrId: string): boolean;
72
75
  /**
73
76
  * Get the data directory path.
74
77
  */
@@ -79,11 +82,8 @@ export declare class DatabaseManager {
79
82
  getMetaPool(): DatabasePool;
80
83
  /**
81
84
  * Close a specific database pool and remove it from the cache.
82
- * Used by backup/restore to swap database files.
83
- *
84
- * If the pool is not loaded, this is a no-op.
85
85
  */
86
- closePool(name: string): void;
86
+ closePool(nameOrId: string): void;
87
87
  /**
88
88
  * Close all application database pools and the meta database.
89
89
  */
@@ -1 +1 @@
1
- {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/db/manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAKtC,MAAM,WAAW,YAAY;IAC3B,mCAAmC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,+BAA+B;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,wEAAwE;IACxE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAMD;;;;;GAKG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,QAAQ,CAAe;IAC/B,OAAO,CAAC,QAAQ,CAAwC;gBAE5C,MAAM,CAAC,EAAE,aAAa;IAsBlC;;;;;OAKG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY;IAuC/B;;;;;OAKG;IACH,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY;IAuD1C;;;;;OAKG;IACH,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IA6ClC;;OAEG;IACH,aAAa,IAAI,YAAY,EAAE;IAe/B;;OAEG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAM7B;;OAEG;IACH,UAAU,IAAI,MAAM;IAIpB;;OAEG;IACH,WAAW,IAAI,YAAY;IAI3B;;;;;OAKG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAQ7B;;OAEG;IACH,KAAK,IAAI,IAAI;CAOd;AAED,eAAe,eAAe,CAAC"}
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/db/manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAKtC,MAAM,WAAW,YAAY;IAC3B,wCAAwC;IACxC,EAAE,EAAE,MAAM,CAAC;IACX,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,+BAA+B;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,SAAS,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,wEAAwE;IACxE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAMD;;;;;GAKG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,QAAQ,CAAe;IAC/B,OAAO,CAAC,QAAQ,CAAwC;gBAE5C,MAAM,CAAC,EAAE,aAAa;IAoClC;;;OAGG;IACH,GAAG,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY;IAwCnC;;;;;OAKG;IACH,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY;IAyD1C;;OAEG;IACH,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAmDtC;;OAEG;IACH,aAAa,IAAI,YAAY,EAAE;IAmB/B;;OAEG;IACH,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IASjC;;OAEG;IACH,UAAU,IAAI,MAAM;IAIpB;;OAEG;IACH,WAAW,IAAI,YAAY;IAI3B;;OAEG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAQjC;;OAEG;IACH,KAAK,IAAI,IAAI;CAOd;AAED,eAAe,eAAe,CAAC"}