@carllee1983/dbcli 1.5.0 → 1.6.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/dist/cli.mjs CHANGED
@@ -6146,7 +6146,10 @@ var init_validation = __esm(() => {
6146
6146
  password: exports_external.union([exports_external.string(), EnvRefSchema]).default(""),
6147
6147
  database: StringOrEnvRef
6148
6148
  });
6149
- ConnectionConfigSchema = exports_external.union([SqlConnectionConfigSchema, MongoDBConnectionConfigSchema]);
6149
+ ConnectionConfigSchema = exports_external.union([
6150
+ SqlConnectionConfigSchema,
6151
+ MongoDBConnectionConfigSchema
6152
+ ]);
6150
6153
  PermissionSchema = exports_external.enum(["query-only", "read-write", "data-admin", "admin"]).default("query-only");
6151
6154
  MetadataSchema = exports_external.object({
6152
6155
  createdAt: exports_external.string().datetime().optional(),
@@ -6173,7 +6176,10 @@ var init_validation = __esm(() => {
6173
6176
  permission: PermissionSchema,
6174
6177
  envFile: exports_external.string().optional()
6175
6178
  });
6176
- NamedConnectionSchema = exports_external.union([SqlNamedConnectionSchema, MongoDBNamedConnectionSchema]);
6179
+ NamedConnectionSchema = exports_external.union([
6180
+ SqlNamedConnectionSchema,
6181
+ MongoDBNamedConnectionSchema
6182
+ ]);
6177
6183
  DbcliConfigV2Schema = exports_external.object({
6178
6184
  version: exports_external.literal(2),
6179
6185
  default: exports_external.string().min(1),
@@ -7297,16 +7303,16 @@ var init_esm = __esm(() => {
7297
7303
  });
7298
7304
 
7299
7305
  // src/utils/schema-path.ts
7300
- import { join as join2 } from "path";
7306
+ import { join as join3 } from "path";
7301
7307
  function resolveSchemaPath(dbcliPath, connectionName) {
7302
7308
  if (!connectionName)
7303
- return join2(dbcliPath, "schemas");
7304
- return join2(dbcliPath, "schemas", connectionName);
7309
+ return join3(dbcliPath, "schemas");
7310
+ return join3(dbcliPath, "schemas", connectionName);
7305
7311
  }
7306
7312
  var init_schema_path = () => {};
7307
7313
 
7308
7314
  // src/core/schema-cache.ts
7309
- import { join as join3 } from "path";
7315
+ import { join as join4 } from "path";
7310
7316
 
7311
7317
  class SchemaCacheManager {
7312
7318
  cache;
@@ -7332,13 +7338,13 @@ class SchemaCacheManager {
7332
7338
  }
7333
7339
  async initialize() {
7334
7340
  try {
7335
- const indexPath = join3(this.schemaRoot, "index.json");
7341
+ const indexPath = join4(this.schemaRoot, "index.json");
7336
7342
  const indexFile = Bun.file(indexPath);
7337
7343
  if (await indexFile.exists()) {
7338
7344
  const indexContent = await indexFile.text();
7339
7345
  this.index = JSON.parse(indexContent);
7340
7346
  }
7341
- const hotPath = join3(this.schemaRoot, "hot-schemas.json");
7347
+ const hotPath = join4(this.schemaRoot, "hot-schemas.json");
7342
7348
  const hotFile = Bun.file(hotPath);
7343
7349
  if (await hotFile.exists()) {
7344
7350
  const hotContent = await hotFile.text();
@@ -7371,7 +7377,7 @@ class SchemaCacheManager {
7371
7377
  return null;
7372
7378
  }
7373
7379
  try {
7374
- const filePath = join3(this.schemaRoot, tableInfo.file);
7380
+ const filePath = join4(this.schemaRoot, tableInfo.file);
7375
7381
  const file = Bun.file(filePath);
7376
7382
  if (!await file.exists()) {
7377
7383
  console.error(`Cold table file not found: ${tableInfo.file} for table ${tableName}`);
@@ -7426,12 +7432,12 @@ var init_schema_cache = __esm(() => {
7426
7432
  });
7427
7433
 
7428
7434
  // src/core/schema-index.ts
7429
- import { join as join4 } from "path";
7435
+ import { join as join5 } from "path";
7430
7436
 
7431
7437
  class SchemaIndexBuilder {
7432
7438
  static async loadIndex(dbcliPath, connectionName) {
7433
7439
  try {
7434
- const indexPath = join4(resolveSchemaPath(dbcliPath, connectionName), "index.json");
7440
+ const indexPath = join5(resolveSchemaPath(dbcliPath, connectionName), "index.json");
7435
7441
  const file = Bun.file(indexPath);
7436
7442
  if (!await file.exists()) {
7437
7443
  return null;
@@ -7478,7 +7484,7 @@ class SchemaIndexBuilder {
7478
7484
  try {
7479
7485
  const schemasDir = resolveSchemaPath(dbcliPath, connectionName);
7480
7486
  await this.ensureDir(schemasDir);
7481
- const indexPath = join4(schemasDir, "index.json");
7487
+ const indexPath = join5(schemasDir, "index.json");
7482
7488
  const indexFile = Bun.file(indexPath);
7483
7489
  await indexFile.write(JSON.stringify(index, null, 2));
7484
7490
  } catch (error) {
@@ -7524,7 +7530,7 @@ var exports_schema_loader = {};
7524
7530
  __export(exports_schema_loader, {
7525
7531
  SchemaLayeredLoader: () => SchemaLayeredLoader2
7526
7532
  });
7527
- import { join as join5 } from "path";
7533
+ import { join as join6 } from "path";
7528
7534
 
7529
7535
  class SchemaLayeredLoader2 {
7530
7536
  dbcliPath;
@@ -7591,7 +7597,7 @@ class SchemaLayeredLoader2 {
7591
7597
  }
7592
7598
  async ensureDirectories() {
7593
7599
  const base = resolveSchemaPath(this.dbcliPath, this.connectionName);
7594
- const dirs = [base, join5(base, "cold")];
7600
+ const dirs = [base, join6(base, "cold")];
7595
7601
  for (const dir of dirs) {
7596
7602
  try {
7597
7603
  const dirFile = Bun.file(dir);
@@ -10287,13 +10293,13 @@ var PromisePolyfill;
10287
10293
  var init_promise_polyfill = __esm(() => {
10288
10294
  PromisePolyfill = class PromisePolyfill extends Promise {
10289
10295
  static withResolver() {
10290
- let resolve;
10296
+ let resolve2;
10291
10297
  let reject;
10292
10298
  const promise = new Promise((res, rej) => {
10293
- resolve = res;
10299
+ resolve2 = res;
10294
10300
  reject = rej;
10295
10301
  });
10296
- return { promise, resolve, reject };
10302
+ return { promise, resolve: resolve2, reject };
10297
10303
  }
10298
10304
  };
10299
10305
  });
@@ -10313,7 +10319,7 @@ function createPrompt(view) {
10313
10319
  output
10314
10320
  });
10315
10321
  const screen = new ScreenManager(rl);
10316
- const { promise, resolve, reject } = PromisePolyfill.withResolver();
10322
+ const { promise, resolve: resolve2, reject } = PromisePolyfill.withResolver();
10317
10323
  const cancel = () => reject(new CancelPromptError);
10318
10324
  if (signal) {
10319
10325
  const abort = () => reject(new AbortPromptError({ cause: signal.reason }));
@@ -10337,7 +10343,7 @@ function createPrompt(view) {
10337
10343
  cycle(() => {
10338
10344
  try {
10339
10345
  const nextView = view(config, (value) => {
10340
- setImmediate(() => resolve(value));
10346
+ setImmediate(() => resolve2(value));
10341
10347
  });
10342
10348
  const [content, bottomContent] = typeof nextView === "string" ? [nextView] : nextView;
10343
10349
  screen.render(content, bottomContent);
@@ -23694,7 +23700,7 @@ var require_dist = __commonJS((exports) => {
23694
23700
  function parse(stream, callback) {
23695
23701
  const parser = new parser_1.Parser;
23696
23702
  stream.on("data", (buffer) => parser.parse(buffer, callback));
23697
- return new Promise((resolve) => stream.on("end", () => resolve()));
23703
+ return new Promise((resolve2) => stream.on("end", () => resolve2()));
23698
23704
  }
23699
23705
  exports.parse = parse;
23700
23706
  });
@@ -24373,12 +24379,12 @@ var require_client = __commonJS((exports, module) => {
24373
24379
  this._connect(callback);
24374
24380
  return;
24375
24381
  }
24376
- return new this._Promise((resolve, reject) => {
24382
+ return new this._Promise((resolve2, reject) => {
24377
24383
  this._connect((error) => {
24378
24384
  if (error) {
24379
24385
  reject(error);
24380
24386
  } else {
24381
- resolve(this);
24387
+ resolve2(this);
24382
24388
  }
24383
24389
  });
24384
24390
  });
@@ -24710,8 +24716,8 @@ var require_client = __commonJS((exports, module) => {
24710
24716
  readTimeout = config.query_timeout || this.connectionParameters.query_timeout;
24711
24717
  query = new Query(config, values, callback);
24712
24718
  if (!query.callback) {
24713
- result = new this._Promise((resolve, reject) => {
24714
- query.callback = (err, res) => err ? reject(err) : resolve(res);
24719
+ result = new this._Promise((resolve2, reject) => {
24720
+ query.callback = (err, res) => err ? reject(err) : resolve2(res);
24715
24721
  }).catch((err) => {
24716
24722
  Error.captureStackTrace(err);
24717
24723
  throw err;
@@ -24786,8 +24792,8 @@ var require_client = __commonJS((exports, module) => {
24786
24792
  if (cb) {
24787
24793
  this.connection.once("end", cb);
24788
24794
  } else {
24789
- return new this._Promise((resolve) => {
24790
- this.connection.once("end", resolve);
24795
+ return new this._Promise((resolve2) => {
24796
+ this.connection.once("end", resolve2);
24791
24797
  });
24792
24798
  }
24793
24799
  }
@@ -24834,8 +24840,8 @@ var require_pg_pool = __commonJS((exports, module) => {
24834
24840
  const cb = function(err, client) {
24835
24841
  err ? rej(err) : res(client);
24836
24842
  };
24837
- const result = new Promise2(function(resolve, reject) {
24838
- res = resolve;
24843
+ const result = new Promise2(function(resolve2, reject) {
24844
+ res = resolve2;
24839
24845
  rej = reject;
24840
24846
  }).catch((err) => {
24841
24847
  Error.captureStackTrace(err);
@@ -24896,7 +24902,7 @@ var require_pg_pool = __commonJS((exports, module) => {
24896
24902
  if (typeof Promise2.try === "function") {
24897
24903
  return Promise2.try(f);
24898
24904
  }
24899
- return new Promise2((resolve) => resolve(f()));
24905
+ return new Promise2((resolve2) => resolve2(f()));
24900
24906
  }
24901
24907
  _isFull() {
24902
24908
  return this._clients.length >= this.options.max;
@@ -25272,8 +25278,8 @@ var require_query2 = __commonJS((exports, module) => {
25272
25278
  NativeQuery.prototype._getPromise = function() {
25273
25279
  if (this._promise)
25274
25280
  return this._promise;
25275
- this._promise = new Promise(function(resolve, reject) {
25276
- this._once("end", resolve);
25281
+ this._promise = new Promise(function(resolve2, reject) {
25282
+ this._once("end", resolve2);
25277
25283
  this._once("error", reject);
25278
25284
  }.bind(this));
25279
25285
  return this._promise;
@@ -25447,12 +25453,12 @@ var require_client2 = __commonJS((exports, module) => {
25447
25453
  this._connect(callback);
25448
25454
  return;
25449
25455
  }
25450
- return new this._Promise((resolve, reject) => {
25456
+ return new this._Promise((resolve2, reject) => {
25451
25457
  this._connect((error) => {
25452
25458
  if (error) {
25453
25459
  reject(error);
25454
25460
  } else {
25455
- resolve(this);
25461
+ resolve2(this);
25456
25462
  }
25457
25463
  });
25458
25464
  });
@@ -25476,8 +25482,8 @@ var require_client2 = __commonJS((exports, module) => {
25476
25482
  query = new NativeQuery(config, values, callback);
25477
25483
  if (!query.callback) {
25478
25484
  let resolveOut, rejectOut;
25479
- result = new this._Promise((resolve, reject) => {
25480
- resolveOut = resolve;
25485
+ result = new this._Promise((resolve2, reject) => {
25486
+ resolveOut = resolve2;
25481
25487
  rejectOut = reject;
25482
25488
  }).catch((err) => {
25483
25489
  Error.captureStackTrace(err);
@@ -25535,8 +25541,8 @@ var require_client2 = __commonJS((exports, module) => {
25535
25541
  }
25536
25542
  let result;
25537
25543
  if (!cb) {
25538
- result = new this._Promise(function(resolve, reject) {
25539
- cb = (err) => err ? reject(err) : resolve();
25544
+ result = new this._Promise(function(resolve2, reject) {
25545
+ cb = (err) => err ? reject(err) : resolve2();
25540
25546
  });
25541
25547
  }
25542
25548
  this.native.end(function() {
@@ -44473,7 +44479,7 @@ var require_named_placeholders = __commonJS((exports, module) => {
44473
44479
  }
44474
44480
  return s;
44475
44481
  }
44476
- function join7(tree) {
44482
+ function join8(tree) {
44477
44483
  if (tree.length === 1) {
44478
44484
  return tree;
44479
44485
  }
@@ -44499,7 +44505,7 @@ var require_named_placeholders = __commonJS((exports, module) => {
44499
44505
  if (cache && (tree = cache.get(query))) {
44500
44506
  return toArrayParams(tree, paramsObj);
44501
44507
  }
44502
- tree = join7(parse(query));
44508
+ tree = join8(parse(query));
44503
44509
  if (cache) {
44504
44510
  cache.set(query, tree);
44505
44511
  }
@@ -44650,11 +44656,11 @@ var require_connection2 = __commonJS((exports, module) => {
44650
44656
  this.addCommand(handshakeCommand);
44651
44657
  if (shouldTrace(connectChannel)) {
44652
44658
  const config = this.config;
44653
- tracePromise(connectChannel, () => new Promise((resolve, reject) => {
44659
+ tracePromise(connectChannel, () => new Promise((resolve2, reject) => {
44654
44660
  let onConnect, onError;
44655
44661
  onConnect = (param) => {
44656
44662
  this.removeListener("error", onError);
44657
- resolve(param);
44663
+ resolve2(param);
44658
44664
  };
44659
44665
  onError = (err) => {
44660
44666
  this.removeListener("connect", onConnect);
@@ -45017,9 +45023,9 @@ var require_connection2 = __commonJS((exports, module) => {
45017
45023
  };
45018
45024
  }, null, cmdQuery.onResult);
45019
45025
  } else if (shouldTrace(queryChannel)) {
45020
- tracePromise(queryChannel, () => new Promise((resolve, reject) => {
45026
+ tracePromise(queryChannel, () => new Promise((resolve2, reject) => {
45021
45027
  cmdQuery.once("error", reject);
45022
- cmdQuery.once("end", () => resolve());
45028
+ cmdQuery.once("end", () => resolve2());
45023
45029
  this.addCommand(cmdQuery);
45024
45030
  }), () => {
45025
45031
  const server = getServerContext(this.config);
@@ -45145,12 +45151,12 @@ var require_connection2 = __commonJS((exports, module) => {
45145
45151
  };
45146
45152
  }, null, origExecCb);
45147
45153
  } else if (shouldTrace(executeChannel)) {
45148
- tracePromise(executeChannel, () => new Promise((resolve, reject) => {
45154
+ tracePromise(executeChannel, () => new Promise((resolve2, reject) => {
45149
45155
  prepareAndExecute((err) => {
45150
45156
  executeCommand.emit("error", err);
45151
45157
  });
45152
45158
  executeCommand.once("error", reject);
45153
- executeCommand.once("end", () => resolve());
45159
+ executeCommand.once("end", () => resolve2());
45154
45160
  }), () => {
45155
45161
  const server = getServerContext(this.config);
45156
45162
  return {
@@ -45367,7 +45373,7 @@ var require_connection2 = __commonJS((exports, module) => {
45367
45373
 
45368
45374
  // node_modules/mysql2/lib/promise/make_done_cb.js
45369
45375
  var require_make_done_cb = __commonJS((exports, module) => {
45370
- function makeDoneCb(resolve, reject, localErr) {
45376
+ function makeDoneCb(resolve2, reject, localErr) {
45371
45377
  return function(err, rows, fields) {
45372
45378
  if (err) {
45373
45379
  localErr.message = err.message;
@@ -45378,7 +45384,7 @@ var require_make_done_cb = __commonJS((exports, module) => {
45378
45384
  localErr.sqlMessage = err.sqlMessage;
45379
45385
  reject(localErr);
45380
45386
  } else {
45381
- resolve([rows, fields]);
45387
+ resolve2([rows, fields]);
45382
45388
  }
45383
45389
  };
45384
45390
  }
@@ -45397,8 +45403,8 @@ var require_prepared_statement_info = __commonJS((exports, module) => {
45397
45403
  execute(parameters) {
45398
45404
  const s = this.statement;
45399
45405
  const localErr = new Error;
45400
- return new this.Promise((resolve, reject) => {
45401
- const done = makeDoneCb(resolve, reject, localErr);
45406
+ return new this.Promise((resolve2, reject) => {
45407
+ const done = makeDoneCb(resolve2, reject, localErr);
45402
45408
  if (parameters) {
45403
45409
  s.execute(parameters, done);
45404
45410
  } else {
@@ -45407,9 +45413,9 @@ var require_prepared_statement_info = __commonJS((exports, module) => {
45407
45413
  });
45408
45414
  }
45409
45415
  close() {
45410
- return new this.Promise((resolve) => {
45416
+ return new this.Promise((resolve2) => {
45411
45417
  this.statement.close();
45412
- resolve();
45418
+ resolve2();
45413
45419
  });
45414
45420
  }
45415
45421
  }
@@ -45468,8 +45474,8 @@ var require_connection3 = __commonJS((exports, module) => {
45468
45474
  if (typeof params === "function") {
45469
45475
  throw new Error("Callback function is not available with promise clients.");
45470
45476
  }
45471
- return new this.Promise((resolve, reject) => {
45472
- const done = makeDoneCb(resolve, reject, localErr);
45477
+ return new this.Promise((resolve2, reject) => {
45478
+ const done = makeDoneCb(resolve2, reject, localErr);
45473
45479
  if (params !== undefined) {
45474
45480
  c.query(query, params, done);
45475
45481
  } else {
@@ -45483,8 +45489,8 @@ var require_connection3 = __commonJS((exports, module) => {
45483
45489
  if (typeof params === "function") {
45484
45490
  throw new Error("Callback function is not available with promise clients.");
45485
45491
  }
45486
- return new this.Promise((resolve, reject) => {
45487
- const done = makeDoneCb(resolve, reject, localErr);
45492
+ return new this.Promise((resolve2, reject) => {
45493
+ const done = makeDoneCb(resolve2, reject, localErr);
45488
45494
  if (params !== undefined) {
45489
45495
  c.execute(query, params, done);
45490
45496
  } else {
@@ -45493,8 +45499,8 @@ var require_connection3 = __commonJS((exports, module) => {
45493
45499
  });
45494
45500
  }
45495
45501
  end() {
45496
- return new this.Promise((resolve) => {
45497
- this.connection.end(resolve);
45502
+ return new this.Promise((resolve2) => {
45503
+ this.connection.end(resolve2);
45498
45504
  });
45499
45505
  }
45500
45506
  async[Symbol.asyncDispose]() {
@@ -45505,31 +45511,31 @@ var require_connection3 = __commonJS((exports, module) => {
45505
45511
  beginTransaction() {
45506
45512
  const c = this.connection;
45507
45513
  const localErr = new Error;
45508
- return new this.Promise((resolve, reject) => {
45509
- const done = makeDoneCb(resolve, reject, localErr);
45514
+ return new this.Promise((resolve2, reject) => {
45515
+ const done = makeDoneCb(resolve2, reject, localErr);
45510
45516
  c.beginTransaction(done);
45511
45517
  });
45512
45518
  }
45513
45519
  commit() {
45514
45520
  const c = this.connection;
45515
45521
  const localErr = new Error;
45516
- return new this.Promise((resolve, reject) => {
45517
- const done = makeDoneCb(resolve, reject, localErr);
45522
+ return new this.Promise((resolve2, reject) => {
45523
+ const done = makeDoneCb(resolve2, reject, localErr);
45518
45524
  c.commit(done);
45519
45525
  });
45520
45526
  }
45521
45527
  rollback() {
45522
45528
  const c = this.connection;
45523
45529
  const localErr = new Error;
45524
- return new this.Promise((resolve, reject) => {
45525
- const done = makeDoneCb(resolve, reject, localErr);
45530
+ return new this.Promise((resolve2, reject) => {
45531
+ const done = makeDoneCb(resolve2, reject, localErr);
45526
45532
  c.rollback(done);
45527
45533
  });
45528
45534
  }
45529
45535
  ping() {
45530
45536
  const c = this.connection;
45531
45537
  const localErr = new Error;
45532
- return new this.Promise((resolve, reject) => {
45538
+ return new this.Promise((resolve2, reject) => {
45533
45539
  c.ping((err) => {
45534
45540
  if (err) {
45535
45541
  localErr.message = err.message;
@@ -45539,7 +45545,7 @@ var require_connection3 = __commonJS((exports, module) => {
45539
45545
  localErr.sqlMessage = err.sqlMessage;
45540
45546
  reject(localErr);
45541
45547
  } else {
45542
- resolve(true);
45548
+ resolve2(true);
45543
45549
  }
45544
45550
  });
45545
45551
  });
@@ -45547,7 +45553,7 @@ var require_connection3 = __commonJS((exports, module) => {
45547
45553
  connect() {
45548
45554
  const c = this.connection;
45549
45555
  const localErr = new Error;
45550
- return new this.Promise((resolve, reject) => {
45556
+ return new this.Promise((resolve2, reject) => {
45551
45557
  c.connect((err, param) => {
45552
45558
  if (err) {
45553
45559
  localErr.message = err.message;
@@ -45557,7 +45563,7 @@ var require_connection3 = __commonJS((exports, module) => {
45557
45563
  localErr.sqlMessage = err.sqlMessage;
45558
45564
  reject(localErr);
45559
45565
  } else {
45560
- resolve(param);
45566
+ resolve2(param);
45561
45567
  }
45562
45568
  });
45563
45569
  });
@@ -45566,7 +45572,7 @@ var require_connection3 = __commonJS((exports, module) => {
45566
45572
  const c = this.connection;
45567
45573
  const promiseImpl = this.Promise;
45568
45574
  const localErr = new Error;
45569
- return new this.Promise((resolve, reject) => {
45575
+ return new this.Promise((resolve2, reject) => {
45570
45576
  c.prepare(options, (err, statement) => {
45571
45577
  if (err) {
45572
45578
  localErr.message = err.message;
@@ -45577,7 +45583,7 @@ var require_connection3 = __commonJS((exports, module) => {
45577
45583
  reject(localErr);
45578
45584
  } else {
45579
45585
  const wrappedStatement = new PromisePreparedStatementInfo(statement, promiseImpl);
45580
- resolve(wrappedStatement);
45586
+ resolve2(wrappedStatement);
45581
45587
  }
45582
45588
  });
45583
45589
  });
@@ -45585,7 +45591,7 @@ var require_connection3 = __commonJS((exports, module) => {
45585
45591
  changeUser(options) {
45586
45592
  const c = this.connection;
45587
45593
  const localErr = new Error;
45588
- return new this.Promise((resolve, reject) => {
45594
+ return new this.Promise((resolve2, reject) => {
45589
45595
  c.changeUser(options, (err) => {
45590
45596
  if (err) {
45591
45597
  localErr.message = err.message;
@@ -45595,7 +45601,7 @@ var require_connection3 = __commonJS((exports, module) => {
45595
45601
  localErr.sqlMessage = err.sqlMessage;
45596
45602
  reject(localErr);
45597
45603
  } else {
45598
- resolve();
45604
+ resolve2();
45599
45605
  }
45600
45606
  });
45601
45607
  });
@@ -45997,12 +46003,12 @@ var require_pool2 = __commonJS((exports, module) => {
45997
46003
  }
45998
46004
  getConnection() {
45999
46005
  const corePool = this.pool;
46000
- return new this.Promise((resolve, reject) => {
46006
+ return new this.Promise((resolve2, reject) => {
46001
46007
  corePool.getConnection((err, coreConnection) => {
46002
46008
  if (err) {
46003
46009
  reject(err);
46004
46010
  } else {
46005
- resolve(new PromisePoolConnection(coreConnection, this.Promise));
46011
+ resolve2(new PromisePoolConnection(coreConnection, this.Promise));
46006
46012
  }
46007
46013
  });
46008
46014
  });
@@ -46017,8 +46023,8 @@ var require_pool2 = __commonJS((exports, module) => {
46017
46023
  if (typeof args === "function") {
46018
46024
  throw new Error("Callback function is not available with promise clients.");
46019
46025
  }
46020
- return new this.Promise((resolve, reject) => {
46021
- const done = makeDoneCb(resolve, reject, localErr);
46026
+ return new this.Promise((resolve2, reject) => {
46027
+ const done = makeDoneCb(resolve2, reject, localErr);
46022
46028
  if (args !== undefined) {
46023
46029
  corePool.query(sql, args, done);
46024
46030
  } else {
@@ -46032,8 +46038,8 @@ var require_pool2 = __commonJS((exports, module) => {
46032
46038
  if (typeof args === "function") {
46033
46039
  throw new Error("Callback function is not available with promise clients.");
46034
46040
  }
46035
- return new this.Promise((resolve, reject) => {
46036
- const done = makeDoneCb(resolve, reject, localErr);
46041
+ return new this.Promise((resolve2, reject) => {
46042
+ const done = makeDoneCb(resolve2, reject, localErr);
46037
46043
  if (args) {
46038
46044
  corePool.execute(sql, args, done);
46039
46045
  } else {
@@ -46044,7 +46050,7 @@ var require_pool2 = __commonJS((exports, module) => {
46044
46050
  end() {
46045
46051
  const corePool = this.pool;
46046
46052
  const localErr = new Error;
46047
- return new this.Promise((resolve, reject) => {
46053
+ return new this.Promise((resolve2, reject) => {
46048
46054
  corePool.end((err) => {
46049
46055
  if (err) {
46050
46056
  localErr.message = err.message;
@@ -46054,7 +46060,7 @@ var require_pool2 = __commonJS((exports, module) => {
46054
46060
  localErr.sqlMessage = err.sqlMessage;
46055
46061
  reject(localErr);
46056
46062
  } else {
46057
- resolve();
46063
+ resolve2();
46058
46064
  }
46059
46065
  });
46060
46066
  });
@@ -46452,12 +46458,12 @@ var require_pool_cluster2 = __commonJS((exports, module) => {
46452
46458
  }
46453
46459
  getConnection() {
46454
46460
  const corePoolNamespace = this.poolNamespace;
46455
- return new this.Promise((resolve, reject) => {
46461
+ return new this.Promise((resolve2, reject) => {
46456
46462
  corePoolNamespace.getConnection((err, coreConnection) => {
46457
46463
  if (err) {
46458
46464
  reject(err);
46459
46465
  } else {
46460
- resolve(new PromisePoolConnection(coreConnection, this.Promise));
46466
+ resolve2(new PromisePoolConnection(coreConnection, this.Promise));
46461
46467
  }
46462
46468
  });
46463
46469
  });
@@ -46468,8 +46474,8 @@ var require_pool_cluster2 = __commonJS((exports, module) => {
46468
46474
  if (typeof values === "function") {
46469
46475
  throw new Error("Callback function is not available with promise clients.");
46470
46476
  }
46471
- return new this.Promise((resolve, reject) => {
46472
- const done = makeDoneCb(resolve, reject, localErr);
46477
+ return new this.Promise((resolve2, reject) => {
46478
+ const done = makeDoneCb(resolve2, reject, localErr);
46473
46479
  corePoolNamespace.query(sql, values, done);
46474
46480
  });
46475
46481
  }
@@ -46479,8 +46485,8 @@ var require_pool_cluster2 = __commonJS((exports, module) => {
46479
46485
  if (typeof values === "function") {
46480
46486
  throw new Error("Callback function is not available with promise clients.");
46481
46487
  }
46482
- return new this.Promise((resolve, reject) => {
46483
- const done = makeDoneCb(resolve, reject, localErr);
46488
+ return new this.Promise((resolve2, reject) => {
46489
+ const done = makeDoneCb(resolve2, reject, localErr);
46484
46490
  corePoolNamespace.execute(sql, values, done);
46485
46491
  });
46486
46492
  }
@@ -46510,9 +46516,9 @@ var require_promise = __commonJS((exports) => {
46510
46516
  if (!thePromise) {
46511
46517
  throw new Error("no Promise implementation available." + "Use promise-enabled node version or pass userland Promise" + " implementation as parameter, for example: { Promise: require('bluebird') }");
46512
46518
  }
46513
- return new thePromise((resolve, reject) => {
46519
+ return new thePromise((resolve2, reject) => {
46514
46520
  coreConnection.once("connect", () => {
46515
- resolve(new PromiseConnection(coreConnection, thePromise));
46521
+ resolve2(new PromiseConnection(coreConnection, thePromise));
46516
46522
  });
46517
46523
  coreConnection.once("error", (err) => {
46518
46524
  createConnectionErr.message = err.message;
@@ -46541,12 +46547,12 @@ var require_promise = __commonJS((exports) => {
46541
46547
  }
46542
46548
  getConnection(pattern, selector) {
46543
46549
  const corePoolCluster = this.poolCluster;
46544
- return new this.Promise((resolve, reject) => {
46550
+ return new this.Promise((resolve2, reject) => {
46545
46551
  corePoolCluster.getConnection(pattern, selector, (err, coreConnection) => {
46546
46552
  if (err) {
46547
46553
  reject(err);
46548
46554
  } else {
46549
- resolve(new PromisePoolConnection(coreConnection, this.Promise));
46555
+ resolve2(new PromisePoolConnection(coreConnection, this.Promise));
46550
46556
  }
46551
46557
  });
46552
46558
  });
@@ -46557,8 +46563,8 @@ var require_promise = __commonJS((exports) => {
46557
46563
  if (typeof args === "function") {
46558
46564
  throw new Error("Callback function is not available with promise clients.");
46559
46565
  }
46560
- return new this.Promise((resolve, reject) => {
46561
- const done = makeDoneCb(resolve, reject, localErr);
46566
+ return new this.Promise((resolve2, reject) => {
46567
+ const done = makeDoneCb(resolve2, reject, localErr);
46562
46568
  corePoolCluster.query(sql, args, done);
46563
46569
  });
46564
46570
  }
@@ -46568,8 +46574,8 @@ var require_promise = __commonJS((exports) => {
46568
46574
  if (typeof args === "function") {
46569
46575
  throw new Error("Callback function is not available with promise clients.");
46570
46576
  }
46571
- return new this.Promise((resolve, reject) => {
46572
- const done = makeDoneCb(resolve, reject, localErr);
46577
+ return new this.Promise((resolve2, reject) => {
46578
+ const done = makeDoneCb(resolve2, reject, localErr);
46573
46579
  corePoolCluster.execute(sql, args, done);
46574
46580
  });
46575
46581
  }
@@ -46579,7 +46585,7 @@ var require_promise = __commonJS((exports) => {
46579
46585
  end() {
46580
46586
  const corePoolCluster = this.poolCluster;
46581
46587
  const localErr = new Error;
46582
- return new this.Promise((resolve, reject) => {
46588
+ return new this.Promise((resolve2, reject) => {
46583
46589
  corePoolCluster.end((err) => {
46584
46590
  if (err) {
46585
46591
  localErr.message = err.message;
@@ -46589,7 +46595,7 @@ var require_promise = __commonJS((exports) => {
46589
46595
  localErr.sqlMessage = err.sqlMessage;
46590
46596
  reject(localErr);
46591
46597
  } else {
46592
- resolve();
46598
+ resolve2();
46593
46599
  }
46594
46600
  });
46595
46601
  });
@@ -53612,7 +53618,7 @@ var require_utils3 = __commonJS((exports) => {
53612
53618
  }
53613
53619
  }
53614
53620
  function get(url, options = {}) {
53615
- return new Promise((resolve, reject) => {
53621
+ return new Promise((resolve2, reject) => {
53616
53622
  let timeoutId;
53617
53623
  const request = http.get(url, options, (response) => {
53618
53624
  response.setEncoding("utf8");
@@ -53620,7 +53626,7 @@ var require_utils3 = __commonJS((exports) => {
53620
53626
  response.on("data", (chunk) => body += chunk);
53621
53627
  response.on("end", () => {
53622
53628
  (0, timers_1.clearTimeout)(timeoutId);
53623
- resolve({ status: response.statusCode, body });
53629
+ resolve2({ status: response.statusCode, body });
53624
53630
  });
53625
53631
  }).on("error", (error) => {
53626
53632
  (0, timers_1.clearTimeout)(timeoutId);
@@ -53639,13 +53645,13 @@ var require_utils3 = __commonJS((exports) => {
53639
53645
  return host && match.test(host.toLowerCase()) ? true : false;
53640
53646
  }
53641
53647
  function promiseWithResolvers() {
53642
- let resolve;
53648
+ let resolve2;
53643
53649
  let reject;
53644
53650
  const promise = new Promise(function withResolversExecutor(promiseResolve, promiseReject) {
53645
- resolve = promiseResolve;
53651
+ resolve2 = promiseResolve;
53646
53652
  reject = promiseReject;
53647
53653
  });
53648
- return { promise, resolve, reject };
53654
+ return { promise, resolve: resolve2, reject };
53649
53655
  }
53650
53656
  function squashError(_error) {
53651
53657
  return;
@@ -53656,8 +53662,8 @@ var require_utils3 = __commonJS((exports) => {
53656
53662
  exports.randomBytes = randomBytes;
53657
53663
  async function once(ee, name, options) {
53658
53664
  options?.signal?.throwIfAborted();
53659
- const { promise, resolve, reject } = promiseWithResolvers();
53660
- const onEvent = (data) => resolve(data);
53665
+ const { promise, resolve: resolve2, reject } = promiseWithResolvers();
53666
+ const onEvent = (data) => resolve2(data);
53661
53667
  const onError = (error) => reject(error);
53662
53668
  const abortListener = addAbortListener(options?.signal, function() {
53663
53669
  reject(this.reason);
@@ -55980,13 +55986,13 @@ var require_mongo_logger = __commonJS((exports) => {
55980
55986
  function createStdioLogger(stream) {
55981
55987
  return {
55982
55988
  write: (log) => {
55983
- return new Promise((resolve, reject) => {
55989
+ return new Promise((resolve2, reject) => {
55984
55990
  const logLine = (0, util_1.inspect)(log, { compact: true, breakLength: Infinity });
55985
55991
  stream.write(`${logLine}
55986
55992
  `, "utf-8", (error) => {
55987
55993
  if (error)
55988
55994
  return reject(error);
55989
- resolve(true);
55995
+ resolve2(true);
55990
55996
  });
55991
55997
  });
55992
55998
  }
@@ -63644,7 +63650,7 @@ var require_URLSearchParams = __commonJS((exports) => {
63644
63650
  }
63645
63651
  const ctorRegistry = utils.initCtorRegistry(globalObject);
63646
63652
 
63647
- class URLSearchParams {
63653
+ class URLSearchParams2 {
63648
63654
  constructor() {
63649
63655
  const args = [];
63650
63656
  {
@@ -63923,7 +63929,7 @@ var require_URLSearchParams = __commonJS((exports) => {
63923
63929
  return esValue[implSymbol]["size"];
63924
63930
  }
63925
63931
  }
63926
- Object.defineProperties(URLSearchParams.prototype, {
63932
+ Object.defineProperties(URLSearchParams2.prototype, {
63927
63933
  append: { enumerable: true },
63928
63934
  delete: { enumerable: true },
63929
63935
  get: { enumerable: true },
@@ -63938,9 +63944,9 @@ var require_URLSearchParams = __commonJS((exports) => {
63938
63944
  forEach: { enumerable: true },
63939
63945
  size: { enumerable: true },
63940
63946
  [Symbol.toStringTag]: { value: "URLSearchParams", configurable: true },
63941
- [Symbol.iterator]: { value: URLSearchParams.prototype.entries, configurable: true, writable: true }
63947
+ [Symbol.iterator]: { value: URLSearchParams2.prototype.entries, configurable: true, writable: true }
63942
63948
  });
63943
- ctorRegistry[interfaceName] = URLSearchParams;
63949
+ ctorRegistry[interfaceName] = URLSearchParams2;
63944
63950
  ctorRegistry["URLSearchParams Iterator"] = Object.create(ctorRegistry["%IteratorPrototype%"], {
63945
63951
  [Symbol.toStringTag]: {
63946
63952
  configurable: true,
@@ -63967,7 +63973,7 @@ var require_URLSearchParams = __commonJS((exports) => {
63967
63973
  Object.defineProperty(globalObject, interfaceName, {
63968
63974
  configurable: true,
63969
63975
  writable: true,
63970
- value: URLSearchParams
63976
+ value: URLSearchParams2
63971
63977
  });
63972
63978
  };
63973
63979
  var Impl = require_URLSearchParams_impl();
@@ -63977,7 +63983,7 @@ var require_URLSearchParams = __commonJS((exports) => {
63977
63983
  var require_URL_impl = __commonJS((exports) => {
63978
63984
  var usm = require_url_state_machine();
63979
63985
  var urlencoded = require_urlencoded();
63980
- var URLSearchParams = require_URLSearchParams();
63986
+ var URLSearchParams2 = require_URLSearchParams();
63981
63987
  exports.implementation = class URLImpl {
63982
63988
  constructor(globalObject, [url, base]) {
63983
63989
  let parsedBase = null;
@@ -63993,7 +63999,7 @@ var require_URL_impl = __commonJS((exports) => {
63993
63999
  }
63994
64000
  const query = parsedURL.query !== null ? parsedURL.query : "";
63995
64001
  this._url = parsedURL;
63996
- this._query = URLSearchParams.createImpl(globalObject, [query], { doNotStripQMark: true });
64002
+ this._query = URLSearchParams2.createImpl(globalObject, [query], { doNotStripQMark: true });
63997
64003
  this._query._url = this;
63998
64004
  }
63999
64005
  static parse(globalObject, input, base) {
@@ -64551,19 +64557,19 @@ var require_URL = __commonJS((exports) => {
64551
64557
  // node_modules/whatwg-url/webidl2js-wrapper.js
64552
64558
  var require_webidl2js_wrapper = __commonJS((exports) => {
64553
64559
  var URL2 = require_URL();
64554
- var URLSearchParams = require_URLSearchParams();
64560
+ var URLSearchParams2 = require_URLSearchParams();
64555
64561
  exports.URL = URL2;
64556
- exports.URLSearchParams = URLSearchParams;
64562
+ exports.URLSearchParams = URLSearchParams2;
64557
64563
  });
64558
64564
 
64559
64565
  // node_modules/whatwg-url/index.js
64560
64566
  var require_whatwg_url = __commonJS((exports) => {
64561
- var { URL: URL2, URLSearchParams } = require_webidl2js_wrapper();
64567
+ var { URL: URL2, URLSearchParams: URLSearchParams2 } = require_webidl2js_wrapper();
64562
64568
  var urlStateMachine = require_url_state_machine();
64563
64569
  var percentEncoding = require_percent_encoding();
64564
64570
  var sharedGlobalObject = { Array, Object, Promise, String, TypeError };
64565
64571
  URL2.install(sharedGlobalObject, ["Window"]);
64566
- URLSearchParams.install(sharedGlobalObject, ["Window"]);
64572
+ URLSearchParams2.install(sharedGlobalObject, ["Window"]);
64567
64573
  exports.URL = sharedGlobalObject.URL;
64568
64574
  exports.URLSearchParams = sharedGlobalObject.URLSearchParams;
64569
64575
  exports.parseURL = urlStateMachine.parseURL;
@@ -65372,20 +65378,20 @@ var require_compression = __commonJS((exports) => {
65372
65378
  ]);
65373
65379
  var ZSTD_COMPRESSION_LEVEL = 3;
65374
65380
  var zlibInflate = (buf) => {
65375
- return new Promise((resolve, reject) => {
65381
+ return new Promise((resolve2, reject) => {
65376
65382
  zlib.inflate(buf, (error, result) => {
65377
65383
  if (error)
65378
65384
  return reject(error);
65379
- resolve(result);
65385
+ resolve2(result);
65380
65386
  });
65381
65387
  });
65382
65388
  };
65383
65389
  var zlibDeflate = (buf, options) => {
65384
- return new Promise((resolve, reject) => {
65390
+ return new Promise((resolve2, reject) => {
65385
65391
  zlib.deflate(buf, options, (error, result) => {
65386
65392
  if (error)
65387
65393
  return reject(error);
65388
- resolve(result);
65394
+ resolve2(result);
65389
65395
  });
65390
65396
  });
65391
65397
  };
@@ -66016,7 +66022,7 @@ var require_state_machine = __commonJS((exports) => {
66016
66022
  socket = tls.connect(socketOptions, () => {
66017
66023
  socket.write(message);
66018
66024
  });
66019
- const { promise: willResolveKmsRequest, reject: rejectOnTlsSocketError, resolve } = (0, utils_1.promiseWithResolvers)();
66025
+ const { promise: willResolveKmsRequest, reject: rejectOnTlsSocketError, resolve: resolve2 } = (0, utils_1.promiseWithResolvers)();
66020
66026
  abortListener = (0, utils_1.addAbortListener)(options?.signal, function() {
66021
66027
  destroySockets();
66022
66028
  rejectOnTlsSocketError(this.reason);
@@ -66028,7 +66034,7 @@ var require_state_machine = __commonJS((exports) => {
66028
66034
  request.addResponse(buffer.read(bytesNeeded));
66029
66035
  }
66030
66036
  if (request.bytesNeeded <= 0) {
66031
- resolve();
66037
+ resolve2();
66032
66038
  }
66033
66039
  });
66034
66040
  await (options?.timeoutContext?.csotEnabled() ? Promise.all([
@@ -67142,8 +67148,8 @@ var require_on_data = __commonJS((exports) => {
67142
67148
  }
67143
67149
  if (finished)
67144
67150
  return closeHandler();
67145
- const { promise, resolve, reject } = (0, utils_1.promiseWithResolvers)();
67146
- unconsumedPromises.push({ resolve, reject });
67151
+ const { promise, resolve: resolve2, reject } = (0, utils_1.promiseWithResolvers)();
67152
+ unconsumedPromises.push({ resolve: resolve2, reject });
67147
67153
  return promise;
67148
67154
  },
67149
67155
  return() {
@@ -68253,13 +68259,13 @@ var require_connect = __commonJS((exports) => {
68253
68259
  socket.setNoDelay(noDelay);
68254
68260
  socket.setTimeout(connectTimeoutMS);
68255
68261
  let cancellationHandler = null;
68256
- const { promise: connectedSocket, resolve, reject } = (0, utils_1.promiseWithResolvers)();
68262
+ const { promise: connectedSocket, resolve: resolve2, reject } = (0, utils_1.promiseWithResolvers)();
68257
68263
  if (existingSocket) {
68258
- resolve(socket);
68264
+ resolve2(socket);
68259
68265
  } else {
68260
68266
  const start = performance.now();
68261
68267
  const connectEvent = useTLS ? "secureConnect" : "connect";
68262
- socket.once(connectEvent, () => resolve(socket)).once("error", (cause) => reject(new error_1.MongoNetworkError(error_1.MongoError.buildErrorMessage(cause), { cause }))).once("timeout", () => {
68268
+ socket.once(connectEvent, () => resolve2(socket)).once("error", (cause) => reject(new error_1.MongoNetworkError(error_1.MongoError.buildErrorMessage(cause), { cause }))).once("timeout", () => {
68263
68269
  reject(new error_1.MongoNetworkTimeoutError(`Socket '${connectEvent}' timed out after ${performance.now() - start | 0}ms (connectTimeoutMS: ${connectTimeoutMS})`));
68264
68270
  }).once("close", () => reject(new error_1.MongoNetworkError(`Socket closed after ${performance.now() - start | 0} during connection establishment`)));
68265
68271
  if (options.cancellationToken != null) {
@@ -68734,10 +68740,10 @@ var require_connection_pool = __commonJS((exports) => {
68734
68740
  async checkOut(options) {
68735
68741
  const checkoutTime = (0, utils_1.processTimeMS)();
68736
68742
  this.emitAndLog(ConnectionPool.CONNECTION_CHECK_OUT_STARTED, new connection_pool_events_1.ConnectionCheckOutStartedEvent(this));
68737
- const { promise, resolve, reject } = (0, utils_1.promiseWithResolvers)();
68743
+ const { promise, resolve: resolve2, reject } = (0, utils_1.promiseWithResolvers)();
68738
68744
  const timeout = options.timeoutContext.connectionCheckoutTimeout;
68739
68745
  const waitQueueMember = {
68740
- resolve,
68746
+ resolve: resolve2,
68741
68747
  reject,
68742
68748
  cancelled: false,
68743
68749
  checkoutTime
@@ -69882,13 +69888,13 @@ var require_connection_string = __commonJS((exports) => {
69882
69888
  var LB_REPLICA_SET_ERROR = "loadBalanced option not supported with a replicaSet option";
69883
69889
  var LB_DIRECT_CONNECTION_ERROR = "loadBalanced option not supported when directConnection is provided";
69884
69890
  function retryDNSTimeoutFor(rrtype) {
69885
- const resolve = rrtype === "SRV" ? (address) => dns.promises.resolve(address, "SRV") : (address) => dns.promises.resolve(address, "TXT");
69891
+ const resolve2 = rrtype === "SRV" ? (address) => dns.promises.resolve(address, "SRV") : (address) => dns.promises.resolve(address, "TXT");
69886
69892
  return async function dnsReqRetryTimeout(lookupAddress) {
69887
69893
  try {
69888
- return await resolve(lookupAddress);
69894
+ return await resolve2(lookupAddress);
69889
69895
  } catch (firstDNSError) {
69890
69896
  if (firstDNSError.code === dns.TIMEOUT) {
69891
- return await resolve(lookupAddress);
69897
+ return await resolve2(lookupAddress);
69892
69898
  } else {
69893
69899
  throw firstDNSError;
69894
69900
  }
@@ -73356,13 +73362,13 @@ var require_topology = __commonJS((exports) => {
73356
73362
  }
73357
73363
  return transaction.server;
73358
73364
  }
73359
- const { promise: serverPromise, resolve, reject } = (0, utils_1.promiseWithResolvers)();
73365
+ const { promise: serverPromise, resolve: resolve2, reject } = (0, utils_1.promiseWithResolvers)();
73360
73366
  const waitQueueMember = {
73361
73367
  serverSelector,
73362
73368
  topologyDescription: this.description,
73363
73369
  mongoLogger: this.client.mongoLogger,
73364
73370
  transaction,
73365
- resolve,
73371
+ resolve: resolve2,
73366
73372
  reject,
73367
73373
  cancelled: false,
73368
73374
  startTime: (0, utils_1.processTimeMS)(),
@@ -77140,7 +77146,7 @@ var {
77140
77146
  // package.json
77141
77147
  var package_default = {
77142
77148
  name: "@carllee1983/dbcli",
77143
- version: "1.5.0",
77149
+ version: "1.6.0",
77144
77150
  description: "Database CLI for AI agents",
77145
77151
  type: "module",
77146
77152
  publishConfig: {
@@ -77244,24 +77250,24 @@ var messages_default = {
77244
77250
  skip_test: "Skipping connection test (--skip-test)",
77245
77251
  connection_hints: "Hints:",
77246
77252
  config_exists_use_force: ".dbcli exists. Use --force option to overwrite.",
77247
- connection_added: "Connection '{{name}}' added",
77248
- connection_removed: "Connection '{{name}}' removed",
77249
- connection_removed_switched: "Connection '{{name}}' removed. Default connection switched to '{{newDefault}}'",
77250
- connection_renamed: "Connection '{{oldName}}' renamed to '{{newName}}'",
77253
+ connection_added: "Connection '{name}' added",
77254
+ connection_removed: "Connection '{name}' removed",
77255
+ connection_removed_switched: "Connection '{name}' removed. Default connection switched to '{newDefault}'",
77256
+ connection_renamed: "Connection '{oldName}' renamed to '{newName}'",
77251
77257
  v1_migration_prompt: "Detected old config format. Create new format and import existing connection as 'default'?",
77252
77258
  config_saved_v2: "V2 configuration saved to .dbcli",
77253
77259
  config_not_found: "Configuration file not found",
77254
77260
  requires_v2_remove: "Removing a connection requires V2 config format",
77255
77261
  requires_v2_rename: "Renaming a connection requires V2 config format",
77256
- connection_not_found: "Connection '{{name}}' does not exist",
77262
+ connection_not_found: "Connection '{name}' does not exist",
77257
77263
  cannot_remove_last: "Cannot remove the last connection",
77258
- connection_already_exists: "Connection '{{name}}' already exists",
77264
+ connection_already_exists: "Connection '{name}' already exists",
77259
77265
  rename_invalid_format: "Usage: --rename <old-name>:<new-name>"
77260
77266
  },
77261
77267
  use: {
77262
77268
  description: "Switch or display the default database connection",
77263
- switched: "Switched default connection to {{name}}",
77264
- current: "Current default connection: {{name}}",
77269
+ switched: "Switched default connection to {name}",
77270
+ current: "Current default connection: {name}",
77265
77271
  requires_v2: "This feature requires v2 config format. Use 'dbcli init --conn-name <name>' to create one",
77266
77272
  available: "Available connections"
77267
77273
  },
@@ -77361,7 +77367,8 @@ Hint: run 'export {envKey}=<value>' and retry`
77361
77367
  },
77362
77368
  skill: {
77363
77369
  description: "Generate AI skill documentation",
77364
- installed: "Skill installed to {path}",
77370
+ installed: `Skill: {path}
77371
+ Reference: {referencePath}`,
77365
77372
  update_available: "Skill updates available for the following platforms:",
77366
77373
  update_hint: 'Run "dbcli skill --install <platform>" to update.'
77367
77374
  },
@@ -77434,24 +77441,24 @@ var messages_default2 = {
77434
77441
  skip_test: "\u8DF3\u904E\u9023\u7DDA\u6E2C\u8A66\uFF08--skip-test\uFF09",
77435
77442
  connection_hints: "\u63D0\u793A\uFF1A",
77436
77443
  config_exists_use_force: ".dbcli \u5DF2\u5B58\u5728\u3002\u4F7F\u7528 --force \u9078\u9805\u8986\u84CB\u3002",
77437
- connection_added: "\u5DF2\u65B0\u589E\u9023\u7DDA '{{name}}'",
77438
- connection_removed: "\u5DF2\u79FB\u9664\u9023\u7DDA '{{name}}'",
77439
- connection_removed_switched: "\u5DF2\u79FB\u9664\u9023\u7DDA '{{name}}'\uFF0C\u9810\u8A2D\u9023\u7DDA\u5DF2\u5207\u63DB\u70BA '{{newDefault}}'",
77440
- connection_renamed: "\u5DF2\u5C07\u9023\u7DDA '{{oldName}}' \u91CD\u65B0\u547D\u540D\u70BA '{{newName}}'",
77444
+ connection_added: "\u5DF2\u65B0\u589E\u9023\u7DDA '{name}'",
77445
+ connection_removed: "\u5DF2\u79FB\u9664\u9023\u7DDA '{name}'",
77446
+ connection_removed_switched: "\u5DF2\u79FB\u9664\u9023\u7DDA '{name}'\uFF0C\u9810\u8A2D\u9023\u7DDA\u5DF2\u5207\u63DB\u70BA '{newDefault}'",
77447
+ connection_renamed: "\u5DF2\u5C07\u9023\u7DDA '{oldName}' \u91CD\u65B0\u547D\u540D\u70BA '{newName}'",
77441
77448
  v1_migration_prompt: "\u5075\u6E2C\u5230\u820A\u683C\u5F0F\u8A2D\u5B9A\uFF0C\u5C07\u5EFA\u7ACB\u65B0\u683C\u5F0F\u4E26\u5C07\u73FE\u6709\u9023\u7DDA\u532F\u5165\u70BA 'default'\uFF0C\u662F\u5426\u7E7C\u7E8C\uFF1F",
77442
77449
  config_saved_v2: "V2 \u8A2D\u5B9A\u5DF2\u5132\u5B58\u81F3 .dbcli",
77443
77450
  config_not_found: "\u627E\u4E0D\u5230\u8A2D\u5B9A\u6A94",
77444
77451
  requires_v2_remove: "\u79FB\u9664\u9023\u7DDA\u9700\u8981 V2 \u683C\u5F0F\u8A2D\u5B9A",
77445
77452
  requires_v2_rename: "\u91CD\u65B0\u547D\u540D\u9023\u7DDA\u9700\u8981 V2 \u683C\u5F0F\u8A2D\u5B9A",
77446
- connection_not_found: "\u9023\u7DDA '{{name}}' \u4E0D\u5B58\u5728",
77453
+ connection_not_found: "\u9023\u7DDA '{name}' \u4E0D\u5B58\u5728",
77447
77454
  cannot_remove_last: "\u7121\u6CD5\u79FB\u9664\u6700\u5F8C\u4E00\u500B\u9023\u7DDA",
77448
- connection_already_exists: "\u9023\u7DDA '{{name}}' \u5DF2\u5B58\u5728",
77455
+ connection_already_exists: "\u9023\u7DDA '{name}' \u5DF2\u5B58\u5728",
77449
77456
  rename_invalid_format: "\u7528\u6CD5\uFF1A--rename <\u820A\u540D\u7A31>:<\u65B0\u540D\u7A31>"
77450
77457
  },
77451
77458
  use: {
77452
77459
  description: "\u5207\u63DB\u6216\u986F\u793A\u9810\u8A2D\u8CC7\u6599\u5EAB\u9023\u7DDA",
77453
- switched: "\u5DF2\u5207\u63DB\u9810\u8A2D\u9023\u7DDA\u70BA {{name}}",
77454
- current: "\u76EE\u524D\u9810\u8A2D\u9023\u7DDA\uFF1A{{name}}",
77460
+ switched: "\u5DF2\u5207\u63DB\u9810\u8A2D\u9023\u7DDA\u70BA {name}",
77461
+ current: "\u76EE\u524D\u7684\u9810\u8A2D\u9023\u7DDA\uFF1A{name}",
77455
77462
  requires_v2: "\u6B64\u529F\u80FD\u9700\u8981\u65B0\u683C\u5F0F\u8A2D\u5B9A\u3002\u8ACB\u4F7F\u7528 dbcli init --conn-name <\u540D\u7A31> \u5EFA\u7ACB\u591A\u9023\u7DDA\u8A2D\u5B9A",
77456
77463
  available: "\u53EF\u7528\u9023\u7DDA"
77457
77464
  },
@@ -77551,7 +77558,8 @@ var messages_default2 = {
77551
77558
  },
77552
77559
  skill: {
77553
77560
  description: "\u751F\u6210 AI \u6280\u80FD\u6587\u6A94",
77554
- installed: "\u6280\u80FD\u5DF2\u5B89\u88DD\u81F3 {path}",
77561
+ installed: `\u6280\u80FD: {path}
77562
+ \u53C3\u8003: {referencePath}`,
77555
77563
  update_available: "\u4EE5\u4E0B\u5E73\u53F0\u7684\u6280\u80FD\u9700\u8981\u66F4\u65B0\uFF1A",
77556
77564
  update_hint: '\u57F7\u884C "dbcli skill --install <platform>" \u9032\u884C\u66F4\u65B0\u3002'
77557
77565
  },
@@ -77757,7 +77765,7 @@ function getLogger() {
77757
77765
  }
77758
77766
 
77759
77767
  // src/commands/init.ts
77760
- import { join as join7 } from "path";
77768
+ import { join as join8 } from "path";
77761
77769
 
77762
77770
  // src/utils/errors.ts
77763
77771
  class EnvParseError extends Error {
@@ -77823,7 +77831,11 @@ function parseConnectionUrl(url) {
77823
77831
  throw new Error(`Unsupported protocol: ${protocol}`);
77824
77832
  }
77825
77833
  const host = parsed.hostname || "localhost";
77826
- const port = parsed.port !== "" ? parseInt(parsed.port, 10) : getDefaultsForSystem(system).port || 5432;
77834
+ const defaultPort = (() => {
77835
+ const p = getDefaultsForSystem(system).port;
77836
+ return typeof p === "number" ? p : 5432;
77837
+ })();
77838
+ const port = parsed.port !== "" ? parseInt(parsed.port, 10) : defaultPort;
77827
77839
  const user = decodeURIComponent(parsed.username || "");
77828
77840
  const password = decodeURIComponent(parsed.password || "");
77829
77841
  const database = parsed.pathname.slice(1);
@@ -77847,13 +77859,14 @@ function parseEnvDatabase(env) {
77847
77859
  throw new EnvParseError("DB_NAME or DB_DATABASE is required when using component format");
77848
77860
  }
77849
77861
  const defaults = getDefaultsForSystem(system);
77850
- const port = env.DB_PORT ? parseInt(env.DB_PORT, 10) : defaults.port || 5432;
77862
+ const defaultPort = typeof defaults.port === "number" ? defaults.port : 5432;
77863
+ const port = env.DB_PORT ? parseInt(env.DB_PORT, 10) : defaultPort;
77851
77864
  if (isNaN(port) || port < 1 || port > 65535) {
77852
77865
  throw new EnvParseError(`DB_PORT must be between 1 and 65535, got: ${env.DB_PORT}`);
77853
77866
  }
77854
77867
  return {
77855
77868
  system,
77856
- host: env.DB_HOST || defaults.host || "localhost",
77869
+ host: env.DB_HOST || (typeof defaults.host === "string" ? defaults.host : "localhost"),
77857
77870
  port,
77858
77871
  user,
77859
77872
  password: env.DB_PASSWORD || "",
@@ -77904,8 +77917,72 @@ async function loadEnvFile(filePath) {
77904
77917
  }
77905
77918
  }
77906
77919
 
77920
+ // src/core/config-binding.ts
77921
+ import { createHash } from "crypto";
77922
+ import { homedir } from "os";
77923
+ import { basename, join, resolve } from "path";
77924
+ var BINDING_FILE_NAME = "config.json";
77925
+ var DBCLI_HOME_ROOT = join(homedir(), ".config", "dbcli");
77926
+ function isProjectConfigBinding(raw) {
77927
+ if (typeof raw !== "object" || raw === null)
77928
+ return false;
77929
+ const candidate = raw;
77930
+ return candidate.version === 3 && typeof candidate.binding === "object" && candidate.binding !== null && candidate.binding.type === "home-storage" && typeof candidate.binding.storagePath === "string" && candidate.binding.storagePath.length > 0 && typeof candidate.binding.projectPath === "string" && candidate.binding.projectPath.length > 0 && typeof candidate.binding.createdAt === "string" && candidate.binding.createdAt.length > 0;
77931
+ }
77932
+ function getDbcliHomeRoot() {
77933
+ return DBCLI_HOME_ROOT;
77934
+ }
77935
+ function getProjectStoragePath(projectPath) {
77936
+ const normalizedProjectPath = resolve(projectPath);
77937
+ const projectName = basename(normalizedProjectPath) || "project";
77938
+ const hash = createHash("sha1").update(normalizedProjectPath).digest("hex").slice(0, 12);
77939
+ return join(getDbcliHomeRoot(), "projects", `${projectName}-${hash}`);
77940
+ }
77941
+ async function readProjectBinding(projectPath) {
77942
+ const configFile = Bun.file(join(projectPath, BINDING_FILE_NAME));
77943
+ if (!await configFile.exists())
77944
+ return null;
77945
+ try {
77946
+ const raw = JSON.parse(await configFile.text());
77947
+ return isProjectConfigBinding(raw) ? raw : null;
77948
+ } catch {
77949
+ return null;
77950
+ }
77951
+ }
77952
+ async function resolveConfigStoragePath(path) {
77953
+ const binding = await readProjectBinding(path);
77954
+ return binding?.binding.storagePath ?? path;
77955
+ }
77956
+ async function writeProjectBinding(projectPath, storagePath = getProjectStoragePath(projectPath)) {
77957
+ const binding = {
77958
+ version: 3,
77959
+ binding: {
77960
+ type: "home-storage",
77961
+ storagePath,
77962
+ projectPath: resolve(projectPath),
77963
+ createdAt: new Date().toISOString()
77964
+ }
77965
+ };
77966
+ await Bun.$`mkdir -p ${projectPath}`;
77967
+ await Bun.$`mkdir -p ${storagePath}`;
77968
+ await Bun.file(join(projectPath, BINDING_FILE_NAME)).write(JSON.stringify(binding, null, 2));
77969
+ return binding;
77970
+ }
77971
+ async function migrateLegacyProjectEnvLocal(projectPath, storagePath = getProjectStoragePath(projectPath)) {
77972
+ const projectEnvPath = join(projectPath, ".env.local");
77973
+ const projectEnvFile = Bun.file(projectEnvPath);
77974
+ if (!await projectEnvFile.exists())
77975
+ return;
77976
+ const storageEnvPath = join(storagePath, ".env.local");
77977
+ await Bun.$`mkdir -p ${storagePath}`;
77978
+ if (!await Bun.file(storageEnvPath).exists()) {
77979
+ await Bun.file(storageEnvPath).write(await projectEnvFile.text());
77980
+ }
77981
+ await Bun.$`rm -f ${projectEnvPath}`;
77982
+ }
77983
+
77907
77984
  // src/core/config-v2.ts
77908
- import { join } from "path";
77985
+ import { join as join2 } from "path";
77909
77986
  function detectConfigVersion(raw) {
77910
77987
  if (typeof raw === "object" && raw !== null && "version" in raw && raw.version === 2 && "connections" in raw) {
77911
77988
  return 2;
@@ -77929,12 +78006,13 @@ function resolveConnection(config, name) {
77929
78006
  }
77930
78007
  async function loadConnectionEnv(resolved, basePath) {
77931
78008
  if (resolved.envFile) {
77932
- const envPath = join(basePath, "..", resolved.envFile);
78009
+ const envPath = join2(basePath, resolved.envFile);
77933
78010
  await loadEnvFile(envPath);
77934
78011
  }
77935
78012
  }
77936
78013
  async function readV2Config(path) {
77937
- const configPath = join(path, "config.json");
78014
+ const storagePath = await resolveConfigStoragePath(path);
78015
+ const configPath = join2(storagePath, "config.json");
77938
78016
  const file = Bun.file(configPath);
77939
78017
  if (!await file.exists()) {
77940
78018
  throw new ConfigError(`\u627E\u4E0D\u5230 V2 \u8A2D\u5B9A\u6A94\uFF1A${configPath}`);
@@ -77945,12 +78023,15 @@ async function readV2Config(path) {
77945
78023
  }
77946
78024
  async function writeV2Config(path, config) {
77947
78025
  DbcliConfigV2Schema.parse(config);
77948
- const configPath = join(path, "config.json");
78026
+ const storagePath = await resolveConfigStoragePath(path);
78027
+ const configPath = join2(storagePath, "config.json");
78028
+ await Bun.$`mkdir -p ${storagePath}`;
77949
78029
  const json = JSON.stringify(config, null, 2);
77950
78030
  await Bun.write(configPath, json);
77951
78031
  }
77952
78032
  async function patchConnectionSchema(dbcliPath, connectionName, schema, metadataUpdate) {
77953
- const v2Config = await readV2Config(dbcliPath);
78033
+ const storagePath = await resolveConfigStoragePath(dbcliPath);
78034
+ const v2Config = await readV2Config(storagePath);
77954
78035
  const updated = {
77955
78036
  ...v2Config,
77956
78037
  schemas: {
@@ -77962,11 +78043,11 @@ async function patchConnectionSchema(dbcliPath, connectionName, schema, metadata
77962
78043
  ...metadataUpdate ?? {}
77963
78044
  }
77964
78045
  };
77965
- await writeV2Config(dbcliPath, updated);
78046
+ await writeV2Config(storagePath, updated);
77966
78047
  }
77967
78048
 
77968
78049
  // src/core/config.ts
77969
- import { join as join6 } from "path";
78050
+ import { join as join7 } from "path";
77970
78051
  var _globalConnectionName;
77971
78052
  function setGlobalConnectionName(name) {
77972
78053
  _globalConnectionName = name;
@@ -77977,11 +78058,12 @@ function getGlobalConnectionName() {
77977
78058
  async function getSchemaIsolationConnectionName(dbcliPath) {
77978
78059
  const effectiveName = getGlobalConnectionName();
77979
78060
  try {
77980
- const stat = await Bun.file(dbcliPath).stat();
78061
+ const storagePath = await resolveConfigStoragePath(dbcliPath);
78062
+ const stat = await Bun.file(storagePath).stat();
77981
78063
  const isDirectory = stat?.isDirectory() ?? false;
77982
78064
  if (!isDirectory)
77983
78065
  return;
77984
- const configJsonPath = join6(dbcliPath, "config.json");
78066
+ const configJsonPath = join7(storagePath, "config.json");
77985
78067
  const configFile = Bun.file(configJsonPath);
77986
78068
  if (!await configFile.exists())
77987
78069
  return;
@@ -78007,7 +78089,8 @@ var DEFAULT_CONFIG = {
78007
78089
  schema: {},
78008
78090
  metadata: {
78009
78091
  version: "1.0"
78010
- }
78092
+ },
78093
+ blacklist: { tables: [], columns: {} }
78011
78094
  };
78012
78095
  function isEnvReference(value) {
78013
78096
  return typeof value === "object" && value !== null && "$env" in value && typeof value.$env === "string";
@@ -78047,21 +78130,29 @@ function resolveEnvReferences(config, env, parentKey, strict = false) {
78047
78130
  }
78048
78131
  function parseEnvPassword(content) {
78049
78132
  const match = content.match(/^DBCLI_PASSWORD=(.+)$/m);
78050
- return match ? match[1].trim() : null;
78133
+ return match?.[1] != null ? match[1].trim() : null;
78051
78134
  }
78052
78135
  var configModule = {
78053
78136
  async read(path, connectionName) {
78054
78137
  const effectiveConnectionName = connectionName ?? _globalConnectionName;
78055
78138
  try {
78139
+ const binding = await readProjectBinding(path);
78140
+ const storagePath = await resolveConfigStoragePath(path);
78141
+ if (binding) {
78142
+ const storageConfigExists = await Bun.file(join7(storagePath, "config.json")).exists();
78143
+ if (!storageConfigExists) {
78144
+ throw new ConfigError(`Bound dbcli config not found: ${join7(storagePath, "config.json")}`);
78145
+ }
78146
+ }
78056
78147
  let isDirectory = false;
78057
78148
  try {
78058
- const stat = await Bun.file(path).stat();
78149
+ const stat = await Bun.file(storagePath).stat();
78059
78150
  isDirectory = stat?.isDirectory() ?? false;
78060
78151
  } catch {
78061
78152
  isDirectory = false;
78062
78153
  }
78063
78154
  if (isDirectory) {
78064
- const configPath = join6(path, "config.json");
78155
+ const configPath = join7(storagePath, "config.json");
78065
78156
  const configFile = Bun.file(configPath);
78066
78157
  const configExists = await configFile.exists();
78067
78158
  if (configExists) {
@@ -78070,8 +78161,8 @@ var configModule = {
78070
78161
  if (detectConfigVersion(config) === 2) {
78071
78162
  const v2Config = DbcliConfigV2Schema.parse(config);
78072
78163
  const resolved = resolveConnection(v2Config, effectiveConnectionName);
78073
- await loadConnectionEnv(resolved, path);
78074
- const envLocalPath = join6(path, ".env.local");
78164
+ await loadConnectionEnv(resolved, storagePath);
78165
+ const envLocalPath = join7(storagePath, ".env.local");
78075
78166
  const envLocalFile = Bun.file(envLocalPath);
78076
78167
  let legacyPassword = null;
78077
78168
  if (await envLocalFile.exists()) {
@@ -78088,7 +78179,7 @@ var configModule = {
78088
78179
  let schema = (v2Config.schemas ?? {})[resolved.name] ?? v2Config.schema;
78089
78180
  try {
78090
78181
  const { SchemaLayeredLoader: SchemaLayeredLoader3 } = await Promise.resolve().then(() => (init_schema_loader(), exports_schema_loader));
78091
- const loader = new SchemaLayeredLoader3(path, { connectionName: resolved.name });
78182
+ const loader = new SchemaLayeredLoader3(storagePath, { connectionName: resolved.name });
78092
78183
  const { cache, index } = await loader.initialize();
78093
78184
  if (index && Object.keys(index.tables).length > 0) {
78094
78185
  const layeredSchema = {};
@@ -78113,7 +78204,7 @@ var configModule = {
78113
78204
  });
78114
78205
  }
78115
78206
  const resolvedConfig = resolveEnvReferences(config, process.env, undefined, false);
78116
- const envPath = join6(path, ".env.local");
78207
+ const envPath = join7(storagePath, ".env.local");
78117
78208
  const envFile = Bun.file(envPath);
78118
78209
  if (await envFile.exists()) {
78119
78210
  const envContent = await envFile.text();
@@ -78175,12 +78266,19 @@ var configModule = {
78175
78266
  async write(path, config) {
78176
78267
  try {
78177
78268
  this.validate(config);
78178
- const pathObj = Bun.file(path);
78179
- const isDirectory = await pathObj.exists() && pathObj.type === "directory";
78180
- if (isDirectory || path.endsWith(".dbcli")) {
78269
+ const storagePath = await resolveConfigStoragePath(path);
78270
+ let isDirectory = false;
78271
+ try {
78272
+ const stat = await Bun.file(storagePath).stat();
78273
+ isDirectory = stat?.isDirectory() ?? false;
78274
+ } catch {
78275
+ isDirectory = false;
78276
+ }
78277
+ if (isDirectory || path.endsWith(".dbcli") || path === storagePath && isDirectory) {
78278
+ await Bun.$`mkdir -p ${storagePath}`;
78181
78279
  const hasEnvReferences = isEnvReference(config.connection.password);
78182
78280
  if (hasEnvReferences) {
78183
- const configPath = join6(path, "config.json");
78281
+ const configPath = join7(storagePath, "config.json");
78184
78282
  const configJson = JSON.stringify(config, null, 2);
78185
78283
  await Bun.file(configPath).write(configJson);
78186
78284
  } else {
@@ -78193,11 +78291,11 @@ var configModule = {
78193
78291
  }
78194
78292
  };
78195
78293
  delete configWithoutPassword.connection.password;
78196
- const configPath = join6(path, "config.json");
78294
+ const configPath = join7(storagePath, "config.json");
78197
78295
  const configJson = JSON.stringify(configWithoutPassword, null, 2);
78198
78296
  await Bun.file(configPath).write(configJson);
78199
78297
  if (password) {
78200
- const envPath = join6(path, ".env.local");
78298
+ const envPath = join7(storagePath, ".env.local");
78201
78299
  const envContent = `# Database Credentials - DO NOT commit to git
78202
78300
 
78203
78301
  DBCLI_PASSWORD=${password}
@@ -78220,7 +78318,7 @@ DBCLI_PASSWORD=${password}
78220
78318
 
78221
78319
  // src/utils/prompts.ts
78222
78320
  async function readLineFromStdin(prompt = "") {
78223
- return new Promise((resolve) => {
78321
+ return new Promise((resolve2) => {
78224
78322
  if (prompt) {
78225
78323
  process.stdout.write(prompt);
78226
78324
  }
@@ -78235,12 +78333,12 @@ async function readLineFromStdin(prompt = "") {
78235
78333
  process.stdin.pause();
78236
78334
  process.stdin.removeListener("data", onData);
78237
78335
  process.stdin.removeListener("end", onEnd);
78238
- resolve(lines2[0].trim());
78336
+ resolve2(lines2[0].trim());
78239
78337
  }
78240
78338
  };
78241
78339
  const onEnd = () => {
78242
78340
  process.stdin.removeListener("data", onData);
78243
- resolve(data.trim());
78341
+ resolve2(data.trim());
78244
78342
  };
78245
78343
  process.stdin.on("data", onData);
78246
78344
  process.stdin.on("end", onEnd);
@@ -78535,7 +78633,9 @@ class PostgreSQLAdapter {
78535
78633
  }
78536
78634
  async testConnection() {
78537
78635
  if (!this.pool) {
78538
- throw new ConnectionError("UNKNOWN", "Database connection not established", ["Call connect() to establish a connection"]);
78636
+ throw new ConnectionError("UNKNOWN", "Database connection not established", [
78637
+ "Call connect() to establish a connection"
78638
+ ]);
78539
78639
  }
78540
78640
  try {
78541
78641
  const result = await this.execute("SELECT 1 as count");
@@ -78546,7 +78646,9 @@ class PostgreSQLAdapter {
78546
78646
  }
78547
78647
  async execute(sql, params) {
78548
78648
  if (!this.pool) {
78549
- throw new ConnectionError("UNKNOWN", "Database connection not established", ["Call connect() to establish a connection"]);
78649
+ throw new ConnectionError("UNKNOWN", "Database connection not established", [
78650
+ "Call connect() to establish a connection"
78651
+ ]);
78550
78652
  }
78551
78653
  try {
78552
78654
  const result = params ? await this.pool.query(sql, params) : await this.pool.query(sql);
@@ -78564,7 +78666,9 @@ class PostgreSQLAdapter {
78564
78666
  }
78565
78667
  async listTables() {
78566
78668
  if (!this.pool) {
78567
- throw new ConnectionError("UNKNOWN", "Database connection not established", ["Call connect() to establish a connection"]);
78669
+ throw new ConnectionError("UNKNOWN", "Database connection not established", [
78670
+ "Call connect() to establish a connection"
78671
+ ]);
78568
78672
  }
78569
78673
  try {
78570
78674
  const query = `
@@ -78601,7 +78705,9 @@ class PostgreSQLAdapter {
78601
78705
  }
78602
78706
  async getTableSchema(tableName) {
78603
78707
  if (!this.pool) {
78604
- throw new ConnectionError("UNKNOWN", "Database connection not established", ["Call connect() to establish a connection"]);
78708
+ throw new ConnectionError("UNKNOWN", "Database connection not established", [
78709
+ "Call connect() to establish a connection"
78710
+ ]);
78605
78711
  }
78606
78712
  try {
78607
78713
  const columnQuery = `
@@ -78695,7 +78801,9 @@ class PostgreSQLAdapter {
78695
78801
  FROM pg_class
78696
78802
  WHERE relname = $1
78697
78803
  `;
78698
- const estimateResult = await this.execute(estimateQuery, [tableName]);
78804
+ const estimateResult = await this.execute(estimateQuery, [
78805
+ tableName
78806
+ ]);
78699
78807
  const estimateResults = estimateResult.rows;
78700
78808
  const pkQuery = `
78701
78809
  SELECT array_agg(a.attname) as columns
@@ -78799,7 +78907,9 @@ class MySQLAdapter {
78799
78907
  }
78800
78908
  async testConnection() {
78801
78909
  if (!this.db) {
78802
- throw new ConnectionError("UNKNOWN", "Database connection not established", ["Call connect() to establish a connection"]);
78910
+ throw new ConnectionError("UNKNOWN", "Database connection not established", [
78911
+ "Call connect() to establish a connection"
78912
+ ]);
78803
78913
  }
78804
78914
  try {
78805
78915
  const result = await this.execute("SELECT 1 as count");
@@ -78810,7 +78920,9 @@ class MySQLAdapter {
78810
78920
  }
78811
78921
  async execute(sql, params) {
78812
78922
  if (!this.db) {
78813
- throw new ConnectionError("UNKNOWN", "Database connection not established", ["Call connect() to establish a connection"]);
78923
+ throw new ConnectionError("UNKNOWN", "Database connection not established", [
78924
+ "Call connect() to establish a connection"
78925
+ ]);
78814
78926
  }
78815
78927
  try {
78816
78928
  const [result] = params ? await this.db.execute(sql, params) : await this.db.execute(sql);
@@ -78836,7 +78948,9 @@ class MySQLAdapter {
78836
78948
  }
78837
78949
  async listTables() {
78838
78950
  if (!this.db) {
78839
- throw new ConnectionError("UNKNOWN", "Database connection not established", ["Call connect() to establish a connection"]);
78951
+ throw new ConnectionError("UNKNOWN", "Database connection not established", [
78952
+ "Call connect() to establish a connection"
78953
+ ]);
78840
78954
  }
78841
78955
  try {
78842
78956
  const query = `
@@ -78869,7 +78983,9 @@ class MySQLAdapter {
78869
78983
  }
78870
78984
  async getTableSchema(tableName) {
78871
78985
  if (!this.db) {
78872
- throw new ConnectionError("UNKNOWN", "Database connection not established", ["Call connect() to establish a connection"]);
78986
+ throw new ConnectionError("UNKNOWN", "Database connection not established", [
78987
+ "Call connect() to establish a connection"
78988
+ ]);
78873
78989
  }
78874
78990
  try {
78875
78991
  const columnQuery = `
@@ -78937,7 +79053,9 @@ class MySQLAdapter {
78937
79053
  FROM information_schema.TABLES
78938
79054
  WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?
78939
79055
  `;
78940
- const estimateResult = await this.execute(estimateQuery, [tableName]);
79056
+ const estimateResult = await this.execute(estimateQuery, [
79057
+ tableName
79058
+ ]);
78941
79059
  const estimateResults = estimateResult.rows;
78942
79060
  const schema = {
78943
79061
  name: tableName,
@@ -78976,6 +79094,7 @@ class MySQLAdapter {
78976
79094
  }
78977
79095
 
78978
79096
  // src/adapters/mongodb-adapter.ts
79097
+ import { resolveSrv, resolveTxt } from "dns/promises";
78979
79098
  class MongoDBAdapter {
78980
79099
  options;
78981
79100
  ClientClass;
@@ -79000,9 +79119,101 @@ class MongoDBAdapter {
79000
79119
  }
79001
79120
  return `mongodb://${host}:${port}/${database}`;
79002
79121
  }
79122
+ parseTxtRecords(records) {
79123
+ const combined = records.flat().map((record) => record.replace(/^"|"$/g, "")).join("&");
79124
+ if (!combined)
79125
+ return {};
79126
+ const params = new URLSearchParams(combined);
79127
+ return Object.fromEntries(params.entries());
79128
+ }
79129
+ async resolveSrvHosts(hostname) {
79130
+ const srvName = `_mongodb._tcp.${hostname}`;
79131
+ try {
79132
+ const records = await resolveSrv(srvName);
79133
+ if (!records.length) {
79134
+ throw new Error(`No SRV records found for ${srvName}`);
79135
+ }
79136
+ return records.map((record) => {
79137
+ const target = String(record.name || record.target || "").replace(/\.$/, "");
79138
+ return `${target}:${record.port}`;
79139
+ });
79140
+ } catch (error) {
79141
+ const code = error?.code;
79142
+ if (code !== "ECONNREFUSED") {
79143
+ throw error;
79144
+ }
79145
+ }
79146
+ const response = await fetch(`https://dns.google/resolve?name=${encodeURIComponent(srvName)}&type=SRV`);
79147
+ if (!response.ok) {
79148
+ throw new Error(`SRV lookup failed with HTTP ${response.status}`);
79149
+ }
79150
+ const payload = await response.json();
79151
+ if (payload.Status !== 0 || !payload.Answer?.length) {
79152
+ throw new Error(payload.Comment || `No SRV records found for ${srvName}`);
79153
+ }
79154
+ return payload.Answer.map((answer) => {
79155
+ const parts = answer.data.trim().split(/\s+/);
79156
+ const port = parts[2];
79157
+ const target = parts.slice(3).join(" ").replace(/\.$/, "");
79158
+ return `${target}:${port}`;
79159
+ });
79160
+ }
79161
+ async resolveTxtOptions(hostname) {
79162
+ try {
79163
+ const records = await resolveTxt(hostname);
79164
+ return this.parseTxtRecords(records);
79165
+ } catch (error) {
79166
+ const code = error?.code;
79167
+ if (code !== "ECONNREFUSED") {
79168
+ throw error;
79169
+ }
79170
+ }
79171
+ const response = await fetch(`https://dns.google/resolve?name=${encodeURIComponent(hostname)}&type=TXT`);
79172
+ if (!response.ok) {
79173
+ throw new Error(`TXT lookup failed with HTTP ${response.status}`);
79174
+ }
79175
+ const payload = await response.json();
79176
+ if (payload.Status !== 0 || !payload.Answer?.length) {
79177
+ return {};
79178
+ }
79179
+ return this.parseTxtRecords(payload.Answer.map((answer) => [answer.data]));
79180
+ }
79181
+ async buildResolvedUri() {
79182
+ if (!this.options.uri) {
79183
+ return this.buildUri();
79184
+ }
79185
+ if (!this.options.uri.startsWith("mongodb+srv://")) {
79186
+ return this.options.uri;
79187
+ }
79188
+ const url = new URL(this.options.uri);
79189
+ const hosts = await this.resolveSrvHosts(url.hostname);
79190
+ const txtOptions = await this.resolveTxtOptions(url.hostname);
79191
+ const query = new URLSearchParams(url.searchParams);
79192
+ for (const [key2, value] of Object.entries(txtOptions)) {
79193
+ if (!query.has(key2)) {
79194
+ query.set(key2, value);
79195
+ }
79196
+ }
79197
+ if (!query.has("tls") && !query.has("ssl")) {
79198
+ query.set("tls", "true");
79199
+ }
79200
+ if ((url.username || url.password) && !query.has("authSource")) {
79201
+ query.set("authSource", "admin");
79202
+ }
79203
+ const userInfo = url.username || url.password ? `${encodeURIComponent(decodeURIComponent(url.username))}${url.password ? `:${encodeURIComponent(decodeURIComponent(url.password))}` : ""}@` : "";
79204
+ const path = url.pathname && url.pathname !== "/" ? url.pathname : `/${this.options.database || "test"}`;
79205
+ const search = query.toString();
79206
+ return `mongodb://${userInfo}${hosts.join(",")}${path}${search ? `?${search}` : ""}`;
79207
+ }
79208
+ getDatabase() {
79209
+ if (!this.client) {
79210
+ throw new ConnectionError("UNKNOWN", "\u5C1A\u672A\u9023\u7DDA\uFF0C\u8ACB\u5148\u547C\u53EB connect()", []);
79211
+ }
79212
+ return this.client.db(this.options.database || undefined);
79213
+ }
79003
79214
  async connect() {
79004
79215
  const ClientClass = await this.resolveClientClass();
79005
- const uri = this.buildUri();
79216
+ const uri = await this.buildResolvedUri();
79006
79217
  try {
79007
79218
  this.client = new ClientClass(uri, { serverSelectionTimeoutMS: this.options.timeout ?? 5000 });
79008
79219
  await this.client.connect();
@@ -79022,11 +79233,8 @@ class MongoDBAdapter {
79022
79233
  }
79023
79234
  }
79024
79235
  async execute(query, params) {
79025
- if (!this.client) {
79026
- throw new ConnectionError("UNKNOWN", "\u5C1A\u672A\u9023\u7DDA\uFF0C\u8ACB\u5148\u547C\u53EB connect()", []);
79027
- }
79236
+ const db = this.getDatabase();
79028
79237
  const collectionName = params?.[0];
79029
- const db = this.client.db();
79030
79238
  const collection = db.collection(collectionName);
79031
79239
  let parsed;
79032
79240
  try {
@@ -79043,10 +79251,7 @@ class MongoDBAdapter {
79043
79251
  return { rows: docs, affectedRows: docs.length };
79044
79252
  }
79045
79253
  async listCollections() {
79046
- if (!this.client) {
79047
- throw new ConnectionError("UNKNOWN", "\u5C1A\u672A\u9023\u7DDA\uFF0C\u8ACB\u5148\u547C\u53EB connect()", []);
79048
- }
79049
- const db = this.client.db();
79254
+ const db = this.getDatabase();
79050
79255
  const colls = await db.listCollections().toArray();
79051
79256
  const results = await Promise.all(colls.map(async (col) => {
79052
79257
  try {
@@ -79058,19 +79263,75 @@ class MongoDBAdapter {
79058
79263
  }));
79059
79264
  return results;
79060
79265
  }
79266
+ async listTables() {
79267
+ const collections = await this.listCollections();
79268
+ return collections.map((c) => ({
79269
+ name: c.name,
79270
+ estimatedRowCount: c.documentCount,
79271
+ columns: []
79272
+ }));
79273
+ }
79274
+ async getTableSchema(collectionName) {
79275
+ const db = this.getDatabase();
79276
+ const collection = db.collection(collectionName);
79277
+ const estimatedRowCount = await collection.estimatedDocumentCount();
79278
+ const samples = await collection.find().limit(5).toArray();
79279
+ const columnMap = new Map;
79280
+ for (const doc of samples) {
79281
+ for (const [key2, value] of Object.entries(doc)) {
79282
+ if (!columnMap.has(key2)) {
79283
+ columnMap.set(key2, new Set);
79284
+ }
79285
+ columnMap.get(key2).add(typeof value);
79286
+ }
79287
+ }
79288
+ const columns = Array.from(columnMap.entries()).map(([name, types3]) => ({
79289
+ name,
79290
+ type: Array.from(types3).join(" | "),
79291
+ nullable: true
79292
+ }));
79293
+ return {
79294
+ name: collectionName,
79295
+ columns,
79296
+ estimatedRowCount,
79297
+ tableType: "collection"
79298
+ };
79299
+ }
79061
79300
  async testConnection() {
79062
79301
  if (!this.client)
79063
79302
  return false;
79064
- await this.client.db().command({ ping: 1 });
79303
+ await this.getDatabase().command({ ping: 1 });
79065
79304
  return true;
79066
79305
  }
79067
79306
  async getServerVersion() {
79068
- if (!this.client) {
79069
- throw new ConnectionError("UNKNOWN", "\u5C1A\u672A\u9023\u7DDA\uFF0C\u8ACB\u5148\u547C\u53EB connect()", []);
79070
- }
79071
- const info = await this.client.db().admin().serverInfo();
79307
+ const info = await this.getDatabase().admin().serverInfo();
79072
79308
  return info.version ?? "unknown";
79073
79309
  }
79310
+ async insert(collection, data) {
79311
+ const db = this.getDatabase();
79312
+ const result = await db.collection(collection).insertOne(data);
79313
+ return {
79314
+ rows: [],
79315
+ affectedRows: result.acknowledged ? 1 : 0,
79316
+ lastInsertId: result.insertedId.toString()
79317
+ };
79318
+ }
79319
+ async update(collection, filter, update) {
79320
+ const db = this.getDatabase();
79321
+ const result = await db.collection(collection).updateMany(filter, update);
79322
+ return {
79323
+ rows: [],
79324
+ affectedRows: result.modifiedCount
79325
+ };
79326
+ }
79327
+ async delete(collection, filter) {
79328
+ const db = this.getDatabase();
79329
+ const result = await db.collection(collection).deleteMany(filter);
79330
+ return {
79331
+ rows: [],
79332
+ affectedRows: result.deletedCount
79333
+ };
79334
+ }
79074
79335
  }
79075
79336
 
79076
79337
  // src/adapters/factory.ts
@@ -79082,6 +79343,8 @@ class AdapterFactory {
79082
79343
  case "mysql":
79083
79344
  case "mariadb":
79084
79345
  return new MySQLAdapter(options);
79346
+ case "mongodb":
79347
+ return new MongoDBAdapter(options);
79085
79348
  default:
79086
79349
  throw new Error(`Unsupported database system: ${options.system}`);
79087
79350
  }
@@ -79113,9 +79376,11 @@ function resolveConfigPath(command, options, fallback = ".dbcli") {
79113
79376
  // src/commands/init.ts
79114
79377
  var VALID_PERMISSIONS = ["query-only", "read-write", "data-admin", "admin"];
79115
79378
  async function checkOverwrite(configPath, shouldPrompt, force) {
79379
+ const storagePath = await resolveConfigStoragePath(configPath);
79116
79380
  const fileExists = await Bun.file(configPath).exists();
79117
- const dirConfigExists = await Bun.file(join7(configPath, "config.json")).exists();
79118
- if (!fileExists && !dirConfigExists || force)
79381
+ const dirConfigExists = await Bun.file(join8(configPath, "config.json")).exists();
79382
+ const storageConfigExists = await Bun.file(join8(storagePath, "config.json")).exists();
79383
+ if (!fileExists && !dirConfigExists && !storageConfigExists || force)
79119
79384
  return true;
79120
79385
  if (shouldPrompt) {
79121
79386
  const overwrite = await promptUser.confirm(t("init.config_exists_overwrite"));
@@ -79128,7 +79393,8 @@ async function checkOverwrite(configPath, shouldPrompt, force) {
79128
79393
  throw new Error(t("init.config_exists_use_force"));
79129
79394
  }
79130
79395
  async function handleRemove(configPath, name) {
79131
- const configFile = Bun.file(join7(configPath, "config.json"));
79396
+ const storagePath = await resolveConfigStoragePath(configPath);
79397
+ const configFile = Bun.file(join8(storagePath, "config.json"));
79132
79398
  if (!await configFile.exists()) {
79133
79399
  throw new Error(t("init.config_not_found"));
79134
79400
  }
@@ -79136,7 +79402,7 @@ async function handleRemove(configPath, name) {
79136
79402
  if (detectConfigVersion(raw) !== 2) {
79137
79403
  throw new Error(t("init.requires_v2_remove"));
79138
79404
  }
79139
- const config = await readV2Config(configPath);
79405
+ const config = await readV2Config(storagePath);
79140
79406
  if (!config.connections[name]) {
79141
79407
  throw new Error(t_vars("init.connection_not_found", { name }));
79142
79408
  }
@@ -79144,14 +79410,14 @@ async function handleRemove(configPath, name) {
79144
79410
  if (connectionCount <= 1) {
79145
79411
  throw new Error(t("init.cannot_remove_last"));
79146
79412
  }
79147
- const { [name]: _removed, ...remaining } = config.connections;
79413
+ const remaining = Object.fromEntries(Object.entries(config.connections).filter(([connectionName]) => connectionName !== name));
79148
79414
  const newDefault = config.default === name ? Object.keys(remaining)[0] : config.default;
79149
79415
  const updated = {
79150
79416
  ...config,
79151
79417
  default: newDefault,
79152
79418
  connections: remaining
79153
79419
  };
79154
- await writeV2Config(configPath, updated);
79420
+ await writeV2Config(storagePath, updated);
79155
79421
  if (config.default === name) {
79156
79422
  console.log(t_vars("init.connection_removed_switched", { name, newDefault }));
79157
79423
  } else {
@@ -79163,7 +79429,8 @@ async function handleRename(configPath, renameArg) {
79163
79429
  if (!oldName || !newName) {
79164
79430
  throw new Error(t("init.rename_invalid_format"));
79165
79431
  }
79166
- const configFile = Bun.file(join7(configPath, "config.json"));
79432
+ const storagePath = await resolveConfigStoragePath(configPath);
79433
+ const configFile = Bun.file(join8(storagePath, "config.json"));
79167
79434
  if (!await configFile.exists()) {
79168
79435
  throw new Error(t("init.config_not_found"));
79169
79436
  }
@@ -79171,7 +79438,7 @@ async function handleRename(configPath, renameArg) {
79171
79438
  if (detectConfigVersion(raw) !== 2) {
79172
79439
  throw new Error(t("init.requires_v2_rename"));
79173
79440
  }
79174
- const config = await readV2Config(configPath);
79441
+ const config = await readV2Config(storagePath);
79175
79442
  if (!config.connections[oldName]) {
79176
79443
  throw new Error(t_vars("init.connection_not_found", { name: oldName }));
79177
79444
  }
@@ -79184,17 +79451,54 @@ async function handleRename(configPath, renameArg) {
79184
79451
  default: config.default === oldName ? newName : config.default,
79185
79452
  connections: Object.fromEntries(entries)
79186
79453
  };
79187
- await writeV2Config(configPath, updated);
79454
+ await writeV2Config(storagePath, updated);
79188
79455
  console.log(t_vars("init.connection_renamed", { oldName, newName }));
79189
79456
  }
79190
79457
  async function writeV2InitConfig(configPath, connectionName, connection, permission, envFile) {
79191
- const configJsonPath = join7(configPath, "config.json");
79458
+ const storagePath = getProjectStoragePath(configPath);
79459
+ const configJsonPath = join8(storagePath, "config.json");
79192
79460
  const configFile = Bun.file(configJsonPath);
79461
+ const projectConfigFile = Bun.file(join8(configPath, "config.json"));
79193
79462
  let existingV2 = null;
79194
79463
  if (await configFile.exists()) {
79195
79464
  const raw = JSON.parse(await configFile.text());
79196
79465
  if (detectConfigVersion(raw) === 2) {
79197
- existingV2 = await readV2Config(configPath);
79466
+ existingV2 = await readV2Config(storagePath);
79467
+ } else {
79468
+ const v1Config = await configModule.read(storagePath);
79469
+ existingV2 = {
79470
+ version: 2,
79471
+ default: "default",
79472
+ connections: {
79473
+ default: {
79474
+ ...v1Config.connection,
79475
+ permission: v1Config.permission
79476
+ }
79477
+ },
79478
+ schema: v1Config.schema || {},
79479
+ schemas: { default: v1Config.schema || {} },
79480
+ metadata: v1Config.metadata || { version: "1.0" },
79481
+ blacklist: v1Config.blacklist || { tables: [], columns: {} }
79482
+ };
79483
+ }
79484
+ } else if (await projectConfigFile.exists()) {
79485
+ const raw = JSON.parse(await projectConfigFile.text());
79486
+ if (detectConfigVersion(raw) === 2) {
79487
+ const v1Config = await configModule.read(configPath);
79488
+ existingV2 = {
79489
+ version: 2,
79490
+ default: "default",
79491
+ connections: {
79492
+ default: {
79493
+ ...v1Config.connection,
79494
+ permission: v1Config.permission
79495
+ }
79496
+ },
79497
+ schema: v1Config.schema || {},
79498
+ schemas: { default: v1Config.schema || {} },
79499
+ metadata: v1Config.metadata || { version: "1.0" },
79500
+ blacklist: v1Config.blacklist || { tables: [], columns: {} }
79501
+ };
79198
79502
  } else {
79199
79503
  const v1Config = await configModule.read(configPath);
79200
79504
  existingV2 = {
@@ -79207,16 +79511,17 @@ async function writeV2InitConfig(configPath, connectionName, connection, permiss
79207
79511
  }
79208
79512
  },
79209
79513
  schema: v1Config.schema || {},
79514
+ schemas: { default: v1Config.schema || {} },
79210
79515
  metadata: v1Config.metadata || { version: "1.0" },
79211
79516
  blacklist: v1Config.blacklist || { tables: [], columns: {} }
79212
79517
  };
79213
79518
  }
79214
79519
  } else {
79215
- const legacyFile = Bun.file(configPath);
79520
+ const legacyFile = Bun.file(storagePath);
79216
79521
  if (await legacyFile.exists()) {
79217
79522
  const raw = JSON.parse(await legacyFile.text());
79218
79523
  if (detectConfigVersion(raw) !== 2) {
79219
- const v1Config = await configModule.read(configPath);
79524
+ const v1Config = await configModule.read(storagePath);
79220
79525
  existingV2 = {
79221
79526
  version: 2,
79222
79527
  default: "default",
@@ -79227,6 +79532,7 @@ async function writeV2InitConfig(configPath, connectionName, connection, permiss
79227
79532
  }
79228
79533
  },
79229
79534
  schema: v1Config.schema || {},
79535
+ schemas: { default: v1Config.schema || {} },
79230
79536
  metadata: v1Config.metadata || { version: "1.0" },
79231
79537
  blacklist: v1Config.blacklist || { tables: [], columns: {} }
79232
79538
  };
@@ -79253,11 +79559,13 @@ async function writeV2InitConfig(configPath, connectionName, connection, permiss
79253
79559
  [connectionName]: connEntry
79254
79560
  },
79255
79561
  schema: {},
79562
+ schemas: {},
79256
79563
  metadata: { version: "1.0", createdAt: new Date().toISOString() },
79257
79564
  blacklist: { tables: [], columns: {} }
79258
79565
  };
79259
- await Bun.$`mkdir -p ${configPath}`;
79260
- await writeV2Config(configPath, v2Config);
79566
+ await writeV2Config(storagePath, v2Config);
79567
+ await migrateLegacyProjectEnvLocal(configPath, storagePath);
79568
+ await writeProjectBinding(configPath, storagePath);
79261
79569
  console.log(t("init.config_saved"));
79262
79570
  }
79263
79571
  var initCommand = new Command("init").description("Initialize dbcli configuration with .env parsing and interactive prompts").option("--host <host>", "Database host").option("--port <port>", "Database port").option("--user <user>", "Database user").option("--password <password>", "Database password").option("--name <name>", "Database name").option("--system <system>", "Database system (postgresql, mysql, mariadb, mongodb)").option("--uri <uri>", "MongoDB connection URI (mongodb://user:pass@host:port/db?authSource=admin)").option("--auth-source <authSource>", "MongoDB auth database (default: admin when user/password are set)").option("--permission <permission>", "Permission level (query-only, read-write, data-admin, admin)", "query-only").option("--use-env-refs", "Store env var references in config instead of actual values (for CI/CD or multi-env)", false).option("--env-host <var>", "Env var name for host (with --use-env-refs)").option("--env-port <var>", "Env var name for port (with --use-env-refs)").option("--env-user <var>", "Env var name for user (with --use-env-refs)").option("--env-password <var>", "Env var name for password (with --use-env-refs)").option("--env-database <var>", "Env var name for database (with --use-env-refs)").option("--skip-test", "Skip database connection test").option("--no-interactive", "Non-interactive mode (requires all values via flags)").option("--force", "Skip overwrite confirmation if .dbcli exists").option("--conn-name <name>", "Connection name (creates v2 multi-connection config)").option("--env-file <path>", "Path to env file for this connection").option("--remove <name>", "Remove a named connection").option("--rename <names>", "Rename a connection (format: old:new)").action(async (options) => {
@@ -79296,7 +79604,8 @@ async function initCommandHandler(options, command) {
79296
79604
  console.log(t("init.env_parse_note"));
79297
79605
  }
79298
79606
  }
79299
- let system = options.system || envConfig?.system || "postgresql";
79607
+ const systemFromCli = typeof options.system === "string" ? options.system : undefined;
79608
+ let system = systemFromCli ?? envConfig?.system ?? "postgresql";
79300
79609
  if (shouldPrompt && !options.system && !envConfig?.system) {
79301
79610
  system = await promptUser.select(t("init.select_system"), [
79302
79611
  "postgresql",
@@ -79325,11 +79634,11 @@ async function initCommandHandler(options, command) {
79325
79634
  };
79326
79635
  let configForWrite;
79327
79636
  if (options.useEnvRefs && shouldPrompt) {
79328
- let envHost = options.envHost || await promptUser.text(t("init.prompt_host"), "DB_HOST");
79329
- let envPort = options.envPort || await promptUser.text(t("init.prompt_port"), "DB_PORT");
79330
- let envUser = options.envUser || await promptUser.text(t("init.prompt_user"), "DB_USER");
79331
- let envPassword = options.envPassword || await promptUser.text(t("init.prompt_password"), "DB_PASSWORD");
79332
- let envDatabase = options.envDatabase || await promptUser.text(t("init.prompt_name"), "DB_DATABASE");
79637
+ const envHost = options.envHost || await promptUser.text(t("init.prompt_host"), "DB_HOST");
79638
+ const envPort = options.envPort || await promptUser.text(t("init.prompt_port"), "DB_PORT");
79639
+ const envUser = options.envUser || await promptUser.text(t("init.prompt_user"), "DB_USER");
79640
+ const envPassword = options.envPassword || await promptUser.text(t("init.prompt_password"), "DB_PASSWORD");
79641
+ const envDatabase = options.envDatabase || await promptUser.text(t("init.prompt_name"), "DB_DATABASE");
79333
79642
  configForWrite = {
79334
79643
  system: connection.system,
79335
79644
  host: { $env: envHost },
@@ -79338,7 +79647,8 @@ async function initCommandHandler(options, command) {
79338
79647
  password: { $env: envPassword },
79339
79648
  database: { $env: envDatabase }
79340
79649
  };
79341
- let permission2 = options.permission || "query-only";
79650
+ const permissionFromCli2 = typeof options.permission === "string" ? options.permission : undefined;
79651
+ let permission2 = permissionFromCli2 ?? "query-only";
79342
79652
  if (!options.permission) {
79343
79653
  permission2 = await promptUser.select(t("init.prompt_permission"), [
79344
79654
  "query-only",
@@ -79362,27 +79672,36 @@ async function initCommandHandler(options, command) {
79362
79672
  await writeV2InitConfig(configPath, connectionName, configForWrite, permission2, options.envFile);
79363
79673
  return;
79364
79674
  }
79365
- await configModule.write(configPath, newConfig2);
79675
+ const storagePath2 = getProjectStoragePath(configPath);
79676
+ await Bun.$`mkdir -p ${storagePath2}`;
79677
+ await configModule.write(storagePath2, newConfig2);
79678
+ await migrateLegacyProjectEnvLocal(configPath, storagePath2);
79679
+ await writeProjectBinding(configPath, storagePath2);
79366
79680
  console.log(t("init.config_saved"));
79367
79681
  return;
79368
79682
  }
79369
- connection.host = options.host || envConfig?.host || (shouldPrompt ? await promptUser.text(t("init.prompt_host"), defaults2.host || "localhost") : defaults2.host || "localhost");
79370
- const portStr = options.port || (envConfig?.port ? String(envConfig.port) : null) || (shouldPrompt ? await promptUser.text(t("init.prompt_port"), String(defaults2.port || 5432)) : String(defaults2.port || 5432));
79683
+ const strOpt = (v) => typeof v === "string" ? v : undefined;
79684
+ const portStrOpt = (v) => typeof v === "string" || typeof v === "number" ? String(v) : undefined;
79685
+ const defaultHost = typeof defaults2.host === "string" ? defaults2.host : "localhost";
79686
+ const defaultPort = typeof defaults2.port === "number" ? defaults2.port : 5432;
79687
+ connection.host = strOpt(options.host) ?? envConfig?.host ?? (shouldPrompt ? await promptUser.text(t("init.prompt_host"), defaultHost) : defaultHost);
79688
+ const portStr = portStrOpt(options.port) ?? (envConfig?.port != null ? String(envConfig.port) : null) ?? (shouldPrompt ? await promptUser.text(t("init.prompt_port"), String(defaultPort)) : String(defaultPort));
79371
79689
  const port = parseInt(portStr, 10);
79372
79690
  if (isNaN(port) || port < 1 || port > 65535) {
79373
79691
  throw new Error(t_vars("errors.invalid_port", { port: portStr }));
79374
79692
  }
79375
79693
  connection.port = port;
79376
- connection.user = options.user || envConfig?.user || (shouldPrompt ? await promptUser.text(t("init.prompt_user")) : "");
79694
+ connection.user = strOpt(options.user) ?? envConfig?.user ?? (shouldPrompt ? await promptUser.text(t("init.prompt_user")) : "");
79377
79695
  if (!connection.user && !shouldPrompt && !options.useEnvRefs) {
79378
79696
  throw new Error(t("errors.require_user"));
79379
79697
  }
79380
- connection.password = options.password || envConfig?.password || (shouldPrompt ? await promptUser.text(t("init.prompt_password")) : "");
79381
- connection.database = options.name || envConfig?.database || (shouldPrompt ? await promptUser.text(t("init.prompt_name")) : "");
79698
+ connection.password = strOpt(options.password) ?? envConfig?.password ?? (shouldPrompt ? await promptUser.text(t("init.prompt_password")) : "");
79699
+ connection.database = strOpt(options.name) ?? envConfig?.database ?? (shouldPrompt ? await promptUser.text(t("init.prompt_name")) : "");
79382
79700
  if (!connection.database && !shouldPrompt && !options.useEnvRefs) {
79383
79701
  throw new Error(t("errors.require_name"));
79384
79702
  }
79385
- let permission = options.permission || "query-only";
79703
+ const permissionFromCli = typeof options.permission === "string" ? options.permission : undefined;
79704
+ let permission = permissionFromCli ?? "query-only";
79386
79705
  if (shouldPrompt && !options.permission) {
79387
79706
  permission = await promptUser.select(t("init.prompt_permission"), [
79388
79707
  "query-only",
@@ -79467,7 +79786,11 @@ async function initCommandHandler(options, command) {
79467
79786
  await writeV2InitConfig(configPath, connectionName, configForWrite, permission, options.envFile);
79468
79787
  return;
79469
79788
  }
79470
- await configModule.write(configPath, newConfig);
79789
+ const storagePath = getProjectStoragePath(configPath);
79790
+ await Bun.$`mkdir -p ${storagePath}`;
79791
+ await configModule.write(storagePath, newConfig);
79792
+ await migrateLegacyProjectEnvLocal(configPath, storagePath);
79793
+ await writeProjectBinding(configPath, storagePath);
79471
79794
  console.log(t("init.config_saved"));
79472
79795
  }
79473
79796
  async function handleMongoDBInit(ctx) {
@@ -79548,7 +79871,11 @@ async function handleMongoDBInit(ctx) {
79548
79871
  connection: mongoConfig,
79549
79872
  permission
79550
79873
  });
79551
- await configModule.write(configPath, newConfig);
79874
+ const storagePath = getProjectStoragePath(configPath);
79875
+ await Bun.$`mkdir -p ${storagePath}`;
79876
+ await configModule.write(storagePath, newConfig);
79877
+ await migrateLegacyProjectEnvLocal(configPath, storagePath);
79878
+ await writeProjectBinding(configPath, storagePath);
79552
79879
  console.log(t("init.config_saved"));
79553
79880
  }
79554
79881
 
@@ -79569,13 +79896,7 @@ class TableFormatter {
79569
79896
  } else if (col.foreignKey) {
79570
79897
  keyType = `FK \u2192 ${col.foreignKey.table}.${col.foreignKey.column}`;
79571
79898
  }
79572
- table.push([
79573
- col.name,
79574
- col.type,
79575
- col.nullable ? "YES" : "NO",
79576
- col.default || "NULL",
79577
- keyType
79578
- ]);
79899
+ table.push([col.name, col.type, col.nullable ? "YES" : "NO", col.default || "NULL", keyType]);
79579
79900
  });
79580
79901
  return table.toString();
79581
79902
  }
@@ -79891,7 +80212,7 @@ init_schema_cache();
79891
80212
 
79892
80213
  // src/core/schema-writer.ts
79893
80214
  init_schema_index();
79894
- import { join as join8 } from "path";
80215
+ import { join as join9 } from "path";
79895
80216
 
79896
80217
  // src/core/atomic-writer.ts
79897
80218
  class AtomicFileWriter {
@@ -80024,7 +80345,7 @@ class SchemaWriter {
80024
80345
  for (const item of mapping.hot) {
80025
80346
  hotSchemas[item.table] = schema[item.table];
80026
80347
  }
80027
- await this.writer.writeJSON(join8(schemaRoot, "hot-schemas.json"), hotSchemas);
80348
+ await this.writer.writeJSON(join9(schemaRoot, "hot-schemas.json"), hotSchemas);
80028
80349
  const coldGroups = {};
80029
80350
  for (const item of mapping.cold) {
80030
80351
  if (!coldGroups[item.file]) {
@@ -80032,10 +80353,10 @@ class SchemaWriter {
80032
80353
  }
80033
80354
  coldGroups[item.file][item.table] = schema[item.table];
80034
80355
  }
80035
- const coldDir = join8(schemaRoot, "cold");
80356
+ const coldDir = join9(schemaRoot, "cold");
80036
80357
  await this.ensureDir(coldDir);
80037
80358
  for (const [fileName, tables] of Object.entries(coldGroups)) {
80038
- const filePath = join8(schemaRoot, fileName);
80359
+ const filePath = join9(schemaRoot, fileName);
80039
80360
  await this.writer.writeJSON(filePath, tables);
80040
80361
  }
80041
80362
  }
@@ -80467,20 +80788,17 @@ var schemaCommand = new Command().name("schema").description("Display table sche
80467
80788
  async function schemaAction(table, options) {
80468
80789
  try {
80469
80790
  validateFormat(options.format, ALLOWED_FORMATS2, "schema");
80791
+ const storagePath = await resolveConfigStoragePath(options.config);
80470
80792
  const config = await configModule.read(options.config);
80471
80793
  if (!config.connection) {
80472
80794
  console.error("Database not configured. Run: dbcli init");
80473
80795
  process.exit(1);
80474
80796
  }
80475
- if (config.connection?.system === "mongodb") {
80476
- console.error("\u6B64\u547D\u4EE4\u76EE\u524D\u4E0D\u652F\u63F4 MongoDB");
80477
- process.exit(1);
80478
- }
80479
80797
  const connectionName = await getSchemaIsolationConnectionName(options.config);
80480
80798
  let existingSchemaCount;
80481
80799
  if (connectionName !== undefined) {
80482
80800
  try {
80483
- const v2Raw = await readV2Config(options.config);
80801
+ const v2Raw = await readV2Config(storagePath);
80484
80802
  existingSchemaCount = Object.keys(v2Raw.schemas?.[connectionName] ?? {}).length;
80485
80803
  } catch {
80486
80804
  existingSchemaCount = 0;
@@ -80492,13 +80810,13 @@ async function schemaAction(table, options) {
80492
80810
  await adapter.connect();
80493
80811
  try {
80494
80812
  if (options.reset) {
80495
- await handleSchemaReset(adapter, config, options, connectionName, existingSchemaCount);
80813
+ await handleSchemaReset(adapter, config, options, connectionName, existingSchemaCount, storagePath);
80496
80814
  } else if (options.refresh) {
80497
- await handleSchemaRefresh(adapter, config, options, connectionName);
80815
+ await handleSchemaRefresh(adapter, config, options, connectionName, storagePath);
80498
80816
  } else if (table) {
80499
80817
  await handleSingleTableSchema(adapter, table, options.format);
80500
80818
  } else {
80501
- await handleFullDatabaseScan(adapter, config, options, connectionName, existingSchemaCount);
80819
+ await handleFullDatabaseScan(adapter, config, options, connectionName, existingSchemaCount, storagePath);
80502
80820
  }
80503
80821
  } finally {
80504
80822
  await adapter.disconnect();
@@ -80558,7 +80876,7 @@ Indexes:`);
80558
80876
  }
80559
80877
  }
80560
80878
  }
80561
- async function handleSchemaRefresh(adapter, config, options, connectionName) {
80879
+ async function handleSchemaRefresh(adapter, config, options, connectionName, storagePath) {
80562
80880
  const diffEngine = new SchemaDiffEngine(adapter, config);
80563
80881
  const report = await diffEngine.diff();
80564
80882
  if (report.tablesAdded.length === 0 && report.tablesRemoved.length === 0 && Object.keys(report.tablesModified).length === 0) {
@@ -80569,7 +80887,7 @@ async function handleSchemaRefresh(adapter, config, options, connectionName) {
80569
80887
  schemaTableCount: Object.keys(config.schema || {}).length
80570
80888
  }
80571
80889
  });
80572
- await writeSchema(options.config, updatedConfig2, connectionName);
80890
+ await writeSchema(storagePath, updatedConfig2, connectionName);
80573
80891
  console.log("\u2705 Schema is up-to-date (no changes detected)");
80574
80892
  return;
80575
80893
  }
@@ -80593,16 +80911,16 @@ async function handleSchemaRefresh(adapter, config, options, connectionName) {
80593
80911
  schemaTableCount: Object.keys(newSchema).length
80594
80912
  }
80595
80913
  });
80596
- const writer = new SchemaWriter(options.config);
80914
+ const writer = new SchemaWriter(storagePath);
80597
80915
  await writer.save(newSchema, connectionName);
80598
80916
  console.log(`\u2705 Schema persisted to layered storage (.dbcli/schemas/${connectionName || ""})`);
80599
- await writeSchema(options.config, updatedConfig, connectionName);
80917
+ await writeSchema(storagePath, updatedConfig, connectionName);
80600
80918
  console.log(`\u2705 Schema updated in .dbcli`);
80601
80919
  }
80602
- async function handleSchemaReset(adapter, config, options, connectionName, existingCount) {
80920
+ async function handleSchemaReset(adapter, config, options, connectionName, existingCount, storagePath) {
80603
80921
  if (existingCount > 0 && !options.force) {
80604
80922
  const { SchemaLayeredLoader: SchemaLayeredLoader3 } = await Promise.resolve().then(() => (init_schema_loader(), exports_schema_loader));
80605
- const loader = new SchemaLayeredLoader3(options.config, { connectionName });
80923
+ const loader = new SchemaLayeredLoader3(storagePath, { connectionName });
80606
80924
  const { index } = await loader.initialize();
80607
80925
  if (!index || Object.keys(index.tables).length === 0) {
80608
80926
  console.log(`\u26A0 This will clear ${existingCount} existing table schemas and re-fetch from database.`);
@@ -80621,8 +80939,8 @@ async function handleSchemaReset(adapter, config, options, connectionName, exist
80621
80939
  schema: {},
80622
80940
  metadata: { ...config.metadata, ...emptyMeta }
80623
80941
  };
80624
- await writeSchema(options.config, configWithoutSchema, connectionName);
80625
- const writer = new SchemaWriter(options.config);
80942
+ await writeSchema(storagePath, configWithoutSchema, connectionName);
80943
+ const writer = new SchemaWriter(storagePath);
80626
80944
  await writer.clear(connectionName);
80627
80945
  console.log(t("schema.scanning_database"));
80628
80946
  const tables = await adapter.listTables();
@@ -80658,7 +80976,7 @@ async function handleSchemaReset(adapter, config, options, connectionName, exist
80658
80976
  };
80659
80977
  await writer.save(schemaData, connectionName);
80660
80978
  console.log(`\u2705 Schema persisted to layered storage (.dbcli/schemas/${connectionName || ""})`);
80661
- await writeSchema(options.config, updatedConfig, connectionName);
80979
+ await writeSchema(storagePath, updatedConfig, connectionName);
80662
80980
  if (existingCount > 0) {
80663
80981
  console.log(`
80664
80982
  \u2705 Schema reset complete \u2014 cleared ${existingCount} old tables, fetched ${tables.length} tables from database`);
@@ -80667,7 +80985,7 @@ async function handleSchemaReset(adapter, config, options, connectionName, exist
80667
80985
  \u2705 Schema fetched \u2014 ${tables.length} tables from database`);
80668
80986
  }
80669
80987
  }
80670
- async function handleFullDatabaseScan(adapter, config, options, connectionName, existingSchemaCount) {
80988
+ async function handleFullDatabaseScan(adapter, config, options, connectionName, existingSchemaCount, storagePath) {
80671
80989
  console.log(t("schema.scanning_database"));
80672
80990
  const tables = await adapter.listTables();
80673
80991
  console.log(t_vars("schema.tables_found", { count: tables.length }));
@@ -80693,7 +81011,7 @@ async function handleFullDatabaseScan(adapter, config, options, connectionName,
80693
81011
  }
80694
81012
  if (existingSchemaCount > 0 && !options.force) {
80695
81013
  const { SchemaLayeredLoader: SchemaLayeredLoader3 } = await Promise.resolve().then(() => (init_schema_loader(), exports_schema_loader));
80696
- const loader = new SchemaLayeredLoader3(options.config, { connectionName });
81014
+ const loader = new SchemaLayeredLoader3(storagePath, { connectionName });
80697
81015
  const { index } = await loader.initialize();
80698
81016
  if (!index || Object.keys(index.tables).length === 0) {
80699
81017
  console.log(`
@@ -80717,10 +81035,10 @@ async function handleFullDatabaseScan(adapter, config, options, connectionName,
80717
81035
  schemaTableCount: tables.length
80718
81036
  }
80719
81037
  };
80720
- const writer = new SchemaWriter(options.config);
81038
+ const writer = new SchemaWriter(storagePath);
80721
81039
  await writer.save(schemaData, connectionName);
80722
81040
  console.log(`\u2705 Schema persisted to layered storage (.dbcli/schemas/${connectionName || ""})`);
80723
- await writeSchema(options.config, updatedConfig, connectionName);
81041
+ await writeSchema(storagePath, updatedConfig, connectionName);
80724
81042
  console.log(`
80725
81043
  \u2705 Schema updated in .dbcli`);
80726
81044
  console.log(` ${tables.length} tables with full column details and relationships`);
@@ -80919,12 +81237,7 @@ function determineConfidence(type, keyword, sql) {
80919
81237
  if (highConfidenceTypes.includes(type)) {
80920
81238
  return "HIGH";
80921
81239
  }
80922
- const mediumConfidenceTypes = [
80923
- "CREATE",
80924
- "ALTER",
80925
- "DROP",
80926
- "TRUNCATE"
80927
- ];
81240
+ const mediumConfidenceTypes = ["CREATE", "ALTER", "DROP", "TRUNCATE"];
80928
81241
  if (mediumConfidenceTypes.includes(type)) {
80929
81242
  return "MEDIUM";
80930
81243
  }
@@ -80958,15 +81271,7 @@ function checkPermission(sql, permission) {
80958
81271
  };
80959
81272
  }
80960
81273
  if (permission === "data-admin") {
80961
- const allowedTypes = [
80962
- "SELECT",
80963
- "INSERT",
80964
- "UPDATE",
80965
- "DELETE",
80966
- "SHOW",
80967
- "DESCRIBE",
80968
- "EXPLAIN"
80969
- ];
81274
+ const allowedTypes = ["SELECT", "INSERT", "UPDATE", "DELETE", "SHOW", "DESCRIBE", "EXPLAIN"];
80970
81275
  if (allowedTypes.includes(classification.type)) {
80971
81276
  return {
80972
81277
  allowed: true,
@@ -80981,14 +81286,7 @@ function checkPermission(sql, permission) {
80981
81286
  };
80982
81287
  }
80983
81288
  if (permission === "read-write") {
80984
- const allowedTypes = [
80985
- "SELECT",
80986
- "INSERT",
80987
- "UPDATE",
80988
- "SHOW",
80989
- "DESCRIBE",
80990
- "EXPLAIN"
80991
- ];
81289
+ const allowedTypes = ["SELECT", "INSERT", "UPDATE", "SHOW", "DESCRIBE", "EXPLAIN"];
80992
81290
  if (allowedTypes.includes(classification.type)) {
80993
81291
  return {
80994
81292
  allowed: true,
@@ -81279,7 +81577,7 @@ async function queryCommand(sql, options, command) {
81279
81577
  throw new Error('Run "dbcli init" first');
81280
81578
  }
81281
81579
  if (config.connection.system === "mongodb") {
81282
- return mongoQueryBranch(sql, options.collection, config, options.format ?? "table");
81580
+ return mongoQueryBranch(sql, options, config);
81283
81581
  }
81284
81582
  const mainTable = extractMainTable(sql);
81285
81583
  if (mainTable && config.schema && !options.noLimit) {
@@ -81333,10 +81631,12 @@ async function queryCommand(sql, options, command) {
81333
81631
  }
81334
81632
  function extractMainTable(sql) {
81335
81633
  const match = sql.match(/\bFROM\s+[`"']?(\w+)[`"']?/i);
81336
- return match ? match[1] : null;
81634
+ return match?.[1] ?? null;
81337
81635
  }
81338
81636
  var SQL_PATTERN = /^\s*(SELECT|INSERT|UPDATE|DELETE|CREATE|DROP|ALTER|SHOW|DESCRIBE)\b/i;
81339
- async function mongoQueryBranch(queryStr, collection, config, format) {
81637
+ async function mongoQueryBranch(queryStr, options, config) {
81638
+ const collection = options.collection;
81639
+ const format = options.format ?? "table";
81340
81640
  if (SQL_PATTERN.test(queryStr)) {
81341
81641
  console.error("\u9019\u662F MongoDB \u9023\u7DDA\uFF0C\u8ACB\u4F7F\u7528 JSON filter \u8A9E\u6CD5\u3002");
81342
81642
  console.error(`\u7BC4\u4F8B\uFF1Adbcli query '{"field": "value"}' --collection <name>`);
@@ -81352,19 +81652,50 @@ async function mongoQueryBranch(queryStr, collection, config, format) {
81352
81652
  console.error("MongoDB \u67E5\u8A62\u5FC5\u9808\u662F\u6709\u6548\u7684 JSON\uFF08object filter \u6216 array pipeline\uFF09");
81353
81653
  process.exit(1);
81354
81654
  }
81655
+ const blacklistManager = new BlacklistManager(config);
81656
+ const blacklistValidator = new BlacklistValidator(blacklistManager);
81657
+ try {
81658
+ blacklistValidator.checkTableBlacklist("SELECT", collection, []);
81659
+ } catch (error) {
81660
+ if (error instanceof BlacklistError) {
81661
+ console.error(error.message);
81662
+ process.exit(1);
81663
+ }
81664
+ throw error;
81665
+ }
81666
+ if (config.schema && !options.noLimit) {
81667
+ const tableSchema = config.schema[collection];
81668
+ if (tableSchema) {
81669
+ const { shouldBlockQuery: shouldBlockQuery2 } = await Promise.resolve().then(() => (init_query_size_guard(), exports_query_size_guard));
81670
+ const isFiltered = queryStr.length > 2;
81671
+ const hasLimit = options.limit !== undefined;
81672
+ const dummySql = `SELECT * FROM ${collection}${isFiltered ? " WHERE" : ""}${hasLimit ? " LIMIT" : ""}`;
81673
+ const guard = shouldBlockQuery2(dummySql, tableSchema);
81674
+ if (guard.blocked) {
81675
+ console.error(`\u26A0 ${guard.reason}`);
81676
+ process.exit(1);
81677
+ }
81678
+ }
81679
+ }
81355
81680
  const mongoAdapter = AdapterFactory.createMongoDBAdapter(config.connection);
81356
81681
  await mongoAdapter.connect();
81357
81682
  try {
81358
81683
  const result = await mongoAdapter.execute(queryStr, [collection]);
81359
- const columnNames = result.rows.length > 0 ? Object.keys(result.rows[0]) : [];
81684
+ const columnNames = result.rows[0] ? Object.keys(result.rows[0]) : [];
81685
+ const filterResult = blacklistValidator.filterColumns(collection, result.rows, columnNames);
81360
81686
  const queryResult = {
81361
- rows: result.rows,
81362
- rowCount: result.rows.length,
81363
- columnNames
81687
+ rows: filterResult.filteredRows,
81688
+ rowCount: filterResult.filteredRows.length,
81689
+ columnNames: columnNames.filter((col) => !filterResult.omittedColumns.includes(col))
81364
81690
  };
81365
81691
  const formatter = new QueryResultFormatter;
81366
81692
  const output = formatter.format(queryResult, { format });
81693
+ const securityNote = blacklistValidator.buildSecurityNotification(collection, filterResult.omittedColumns);
81367
81694
  console.log(output);
81695
+ if (securityNote) {
81696
+ console.log(`
81697
+ \u2139 ${securityNote}`);
81698
+ }
81368
81699
  } finally {
81369
81700
  await mongoAdapter.disconnect();
81370
81701
  }
@@ -81702,8 +82033,23 @@ async function insertCommand(table, options, command) {
81702
82033
  throw new Error('Run "dbcli init" to configure database connection');
81703
82034
  }
81704
82035
  if (config.connection.system === "mongodb") {
81705
- console.error("\u6B64\u547D\u4EE4\u76EE\u524D\u4E0D\u652F\u63F4 MongoDB");
81706
- process.exit(1);
82036
+ enforcePermission("INSERT INTO dummy", config.permission);
82037
+ const adapter2 = AdapterFactory.createMongoDBAdapter(config.connection);
82038
+ await adapter2.connect();
82039
+ try {
82040
+ const result = await adapter2.insert(table, data);
82041
+ const output = {
82042
+ status: "success",
82043
+ operation: "insert",
82044
+ rows_affected: result.affectedRows,
82045
+ timestamp: new Date().toISOString(),
82046
+ lastInsertId: result.lastInsertId
82047
+ };
82048
+ console.log(JSON.stringify(output, null, 2));
82049
+ return;
82050
+ } finally {
82051
+ await adapter2.disconnect();
82052
+ }
81707
82053
  }
81708
82054
  const adapter = AdapterFactory.createAdapter(config.connection);
81709
82055
  await adapter.connect();
@@ -81776,7 +82122,11 @@ function parseWhereClause(whereClause) {
81776
82122
  if (!match) {
81777
82123
  throw new Error(`Cannot parse WHERE clause: "${part}". Use format "column=value" or "col1=val1 AND col2=val2"`);
81778
82124
  }
81779
- const [_, column, valueStr] = match;
82125
+ const column = match[1];
82126
+ const valueStr = match[2];
82127
+ if (valueStr === undefined || column === undefined) {
82128
+ throw new Error(`Cannot parse WHERE clause: "${part}". Use format "column=value" or "col1=val1 AND col2=val2"`);
82129
+ }
81780
82130
  let value = valueStr.trim();
81781
82131
  if (value.startsWith("'") && value.endsWith("'") || value.startsWith('"') && value.endsWith('"')) {
81782
82132
  value = value.slice(1, -1);
@@ -81806,11 +82156,10 @@ async function updateCommand(table, options, command) {
81806
82156
  if (!options.set || options.set.trim() === "") {
81807
82157
  throw new Error(`UPDATE requires --set flag with JSON data (e.g. --set '{"name":"Bob"}')`);
81808
82158
  }
81809
- let whereConditions;
81810
- try {
81811
- whereConditions = parseWhereClause(options.where);
81812
- } catch (error) {
81813
- throw new Error(`WHERE clause parsing failed: ${error.message}`);
82159
+ const configPath = resolveConfigPath(command, options);
82160
+ const config = await configModule.read(configPath);
82161
+ if (!config.connection) {
82162
+ throw new Error('Run "dbcli init" to configure database connection');
81814
82163
  }
81815
82164
  let setData;
81816
82165
  try {
@@ -81821,14 +82170,36 @@ async function updateCommand(table, options, command) {
81821
82170
  if (!setData || typeof setData !== "object" || Array.isArray(setData)) {
81822
82171
  throw new Error('JSON in --set must be an object (e.g. {"name":"Bob","email":"b@example.com"})');
81823
82172
  }
81824
- const configPath = resolveConfigPath(command, options);
81825
- const config = await configModule.read(configPath);
81826
- if (!config.connection) {
81827
- throw new Error('Run "dbcli init" to configure database connection');
81828
- }
81829
82173
  if (config.connection?.system === "mongodb") {
81830
- console.error("\u6B64\u547D\u4EE4\u76EE\u524D\u4E0D\u652F\u63F4 MongoDB");
81831
- process.exit(1);
82174
+ enforcePermission("UPDATE dummy", config.permission);
82175
+ const adapter2 = AdapterFactory.createMongoDBAdapter(config.connection);
82176
+ await adapter2.connect();
82177
+ try {
82178
+ let filter;
82179
+ try {
82180
+ filter = JSON.parse(options.where);
82181
+ } catch {
82182
+ filter = parseWhereClause(options.where);
82183
+ }
82184
+ const updateDoc = Object.keys(setData).some((key2) => key2.startsWith("$")) ? setData : { $set: setData };
82185
+ const result = await adapter2.update(table, filter, updateDoc);
82186
+ const output = {
82187
+ status: "success",
82188
+ operation: "update",
82189
+ rows_affected: result.affectedRows,
82190
+ timestamp: new Date().toISOString()
82191
+ };
82192
+ console.log(JSON.stringify(output, null, 2));
82193
+ return;
82194
+ } finally {
82195
+ await adapter2.disconnect();
82196
+ }
82197
+ }
82198
+ let whereConditions;
82199
+ try {
82200
+ whereConditions = parseWhereClause(options.where);
82201
+ } catch (error) {
82202
+ throw new Error(`WHERE clause parsing failed: ${error.message}`);
81832
82203
  }
81833
82204
  const adapter = AdapterFactory.createAdapter(config.connection);
81834
82205
  await adapter.connect();
@@ -81929,23 +82300,48 @@ async function deleteCommand(table, options, command) {
81929
82300
  if (!options.where || options.where.trim() === "") {
81930
82301
  throw new Error('DELETE requires --where clause (e.g. --where "id=1")');
81931
82302
  }
81932
- let whereConditions;
81933
- try {
81934
- whereConditions = parseWhereClause2(options.where);
81935
- } catch (error) {
81936
- throw new Error(`WHERE clause parsing failed: ${error.message}`);
81937
- }
81938
82303
  const configPath = resolveConfigPath(command, options);
81939
82304
  const config = await configModule.read(configPath);
81940
82305
  if (!config.connection) {
81941
82306
  throw new Error('Run "dbcli init" to configure database connection');
81942
82307
  }
82308
+ if (config.permission !== "data-admin" && config.permission !== "admin") {
82309
+ throw new PermissionError(t("delete.admin_only"), {
82310
+ type: "DELETE",
82311
+ isDangerous: true,
82312
+ keywords: ["DELETE"],
82313
+ isComposite: false,
82314
+ confidence: "HIGH"
82315
+ }, config.permission);
82316
+ }
81943
82317
  if (config.connection?.system === "mongodb") {
81944
- console.error("\u6B64\u547D\u4EE4\u76EE\u524D\u4E0D\u652F\u63F4 MongoDB");
81945
- process.exit(1);
82318
+ const adapter2 = AdapterFactory.createMongoDBAdapter(config.connection);
82319
+ await adapter2.connect();
82320
+ try {
82321
+ let filter;
82322
+ try {
82323
+ filter = JSON.parse(options.where);
82324
+ } catch {
82325
+ filter = parseWhereClause2(options.where);
82326
+ }
82327
+ const result = await adapter2.delete(table, filter);
82328
+ const output = {
82329
+ status: "success",
82330
+ operation: "delete",
82331
+ rows_affected: result.affectedRows,
82332
+ timestamp: new Date().toISOString()
82333
+ };
82334
+ console.log(JSON.stringify(output, null, 2));
82335
+ return;
82336
+ } finally {
82337
+ await adapter2.disconnect();
82338
+ }
81946
82339
  }
81947
- if (config.permission !== "data-admin" && config.permission !== "admin") {
81948
- throw new PermissionError(t("delete.admin_only"), { type: "DELETE", isDangerous: true, keywords: ["DELETE"], isComposite: false, confidence: "HIGH" }, config.permission);
82340
+ let whereConditions;
82341
+ try {
82342
+ whereConditions = parseWhereClause2(options.where);
82343
+ } catch (error) {
82344
+ throw new Error(`WHERE clause parsing failed: ${error.message}`);
81949
82345
  }
81950
82346
  const adapter = AdapterFactory.createAdapter(config.connection);
81951
82347
  await adapter.connect();
@@ -82073,7 +82469,7 @@ async function exportCommand(sql, options, command) {
82073
82469
  // src/commands/skill.ts
82074
82470
  var {$ } = globalThis.Bun;
82075
82471
  import * as path from "path";
82076
- import { homedir } from "os";
82472
+ import { homedir as homedir2 } from "os";
82077
82473
  function findPackageRoot() {
82078
82474
  let dir = import.meta.dir;
82079
82475
  for (let i = 0;i < 5; i++) {
@@ -82085,6 +82481,7 @@ function findPackageRoot() {
82085
82481
  return path.resolve(import.meta.dir, "../..");
82086
82482
  }
82087
82483
  var SKILL_SOURCE_PATH = path.join(findPackageRoot(), "assets", "SKILL.md");
82484
+ var REFERENCE_SOURCE_PATH = path.join(findPackageRoot(), "assets", "reference.md");
82088
82485
  var SUPPORTED_PLATFORMS = ["claude", "gemini", "copilot", "cursor"];
82089
82486
  async function skillCommand(_program, options) {
82090
82487
  try {
@@ -82092,7 +82489,12 @@ async function skillCommand(_program, options) {
82092
82489
  if (!await skillFile.exists()) {
82093
82490
  throw new Error(`Skill source not found: ${SKILL_SOURCE_PATH}`);
82094
82491
  }
82492
+ const refFile = Bun.file(REFERENCE_SOURCE_PATH);
82493
+ if (!await refFile.exists()) {
82494
+ throw new Error(`Skill reference not found: ${REFERENCE_SOURCE_PATH}`);
82495
+ }
82095
82496
  const skillMarkdown = await skillFile.text();
82497
+ const referenceMarkdown = await refFile.text();
82096
82498
  if (options.output) {
82097
82499
  await Bun.file(options.output).write(skillMarkdown);
82098
82500
  console.error(`Skill written to ${options.output}`);
@@ -82100,9 +82502,8 @@ async function skillCommand(_program, options) {
82100
82502
  }
82101
82503
  if (options.install) {
82102
82504
  const installPath = getInstallPath(options.install);
82103
- await ensureDir(path.dirname(installPath));
82104
- await Bun.file(installPath).write(skillMarkdown);
82105
- console.error(t_vars("skill.installed", { path: installPath }));
82505
+ const { referencePath } = await writeSkillInstall(options.install, installPath, skillMarkdown, referenceMarkdown);
82506
+ console.error(t_vars("skill.installed", { path: installPath, referencePath: referencePath ?? "" }));
82106
82507
  return;
82107
82508
  }
82108
82509
  console.log(skillMarkdown);
@@ -82135,7 +82536,7 @@ async function checkSkillUpdates() {
82135
82536
  return outdated;
82136
82537
  }
82137
82538
  function getInstallPath(platform) {
82138
- const home = process.env.HOME || homedir();
82539
+ const home = process.env.HOME || homedir2();
82139
82540
  const platformLower = platform.toLowerCase();
82140
82541
  switch (platformLower) {
82141
82542
  case "claude":
@@ -82150,6 +82551,20 @@ function getInstallPath(platform) {
82150
82551
  throw new Error(`Unknown platform: ${platform}. Supported platforms: ${SUPPORTED_PLATFORMS.join(", ")}`);
82151
82552
  }
82152
82553
  }
82554
+ async function writeSkillInstall(platform, installPath, skillMarkdown, referenceMarkdown) {
82555
+ const platformLower = platform.toLowerCase();
82556
+ await ensureDir(path.dirname(installPath));
82557
+ await Bun.file(installPath).write(skillMarkdown);
82558
+ if (platformLower === "cursor") {
82559
+ const refPath2 = path.join(process.cwd(), ".cursor", "skills", "dbcli", "reference.md");
82560
+ await ensureDir(path.dirname(refPath2));
82561
+ await Bun.file(refPath2).write(referenceMarkdown);
82562
+ return { referencePath: refPath2 };
82563
+ }
82564
+ const refPath = path.join(path.dirname(installPath), "reference.md");
82565
+ await Bun.file(refPath).write(referenceMarkdown);
82566
+ return { referencePath: refPath };
82567
+ }
82153
82568
  async function ensureDir(dirPath) {
82154
82569
  try {
82155
82570
  await $`mkdir -p ${dirPath}`.quiet();
@@ -82242,7 +82657,7 @@ async function blacklistTableRemove(tableName, configPath) {
82242
82657
  }
82243
82658
  const newBlacklist = {
82244
82659
  ...blacklist,
82245
- tables: blacklist.tables.filter((t7) => t7 !== tableName)
82660
+ tables: blacklist.tables.filter((t6) => t6 !== tableName)
82246
82661
  };
82247
82662
  await configModule.write(configPath, { ...config, blacklist: newBlacklist });
82248
82663
  console.log(t_vars("blacklist.table_removed", { table: tableName }));
@@ -82377,21 +82792,21 @@ async function checkAction(table, options) {
82377
82792
  const tables = await adapter.listTables();
82378
82793
  const reports = [];
82379
82794
  const skipped = [];
82380
- for (const t7 of tables) {
82381
- if (blacklistedTables.has(t7.name.toLowerCase())) {
82382
- skipped.push(`${t7.name} (blacklisted)`);
82795
+ for (const t6 of tables) {
82796
+ if (blacklistedTables.has(t6.name.toLowerCase())) {
82797
+ skipped.push(`${t6.name} (blacklisted)`);
82383
82798
  continue;
82384
82799
  }
82385
- if (t7.tableType === "view") {
82386
- skipped.push(`${t7.name} (view)`);
82800
+ if (t6.tableType === "view") {
82801
+ skipped.push(`${t6.name} (view)`);
82387
82802
  continue;
82388
82803
  }
82389
- const category = getSizeCategory(t7.estimatedRowCount);
82804
+ const category = getSizeCategory(t6.estimatedRowCount);
82390
82805
  if (category === "huge" && !options.includeLarge) {
82391
- skipped.push(`${t7.name} (~${(t7.estimatedRowCount || 0).toLocaleString()} rows, huge)`);
82806
+ skipped.push(`${t6.name} (~${(t6.estimatedRowCount || 0).toLocaleString()} rows, huge)`);
82392
82807
  continue;
82393
82808
  }
82394
- const schema = await adapter.getTableSchema(t7.name);
82809
+ const schema = await adapter.getTableSchema(t6.name);
82395
82810
  const report = await checker.check(schema, {
82396
82811
  checks: checkTypes,
82397
82812
  sample: sampleSize,
@@ -82475,31 +82890,49 @@ var ALLOWED_FORMATS5 = ["json", "table"];
82475
82890
  function compareSnapshots(before, after) {
82476
82891
  const beforeTables = new Set(Object.keys(before.tables));
82477
82892
  const afterTables = new Set(Object.keys(after.tables));
82478
- const addedTables = Array.from(afterTables).filter((t7) => !beforeTables.has(t7));
82479
- const removedTables = Array.from(beforeTables).filter((t7) => !afterTables.has(t7));
82893
+ const addedTables = Array.from(afterTables).filter((t6) => !beforeTables.has(t6));
82894
+ const removedTables = Array.from(beforeTables).filter((t6) => !afterTables.has(t6));
82480
82895
  const addedColumns = [];
82481
82896
  const removedColumns = [];
82482
82897
  const modifiedColumns = [];
82483
82898
  const indexChanges = [];
82484
82899
  for (const tableName of addedTables) {
82485
- for (const col of after.tables[tableName].columns) {
82486
- addedColumns.push({ table: tableName, column: col.name, type: col.type, nullable: col.nullable });
82900
+ const added = after.tables[tableName];
82901
+ if (!added)
82902
+ continue;
82903
+ for (const col of added.columns) {
82904
+ addedColumns.push({
82905
+ table: tableName,
82906
+ column: col.name,
82907
+ type: col.type,
82908
+ nullable: col.nullable
82909
+ });
82487
82910
  }
82488
82911
  }
82489
82912
  for (const tableName of removedTables) {
82490
- for (const col of before.tables[tableName].columns) {
82913
+ const removed = before.tables[tableName];
82914
+ if (!removed)
82915
+ continue;
82916
+ for (const col of removed.columns) {
82491
82917
  removedColumns.push({ table: tableName, column: col.name, type: col.type });
82492
82918
  }
82493
82919
  }
82494
- const commonTables = Array.from(afterTables).filter((t7) => beforeTables.has(t7));
82920
+ const commonTables = Array.from(afterTables).filter((t6) => beforeTables.has(t6));
82495
82921
  for (const tableName of commonTables) {
82496
82922
  const beforeTable = before.tables[tableName];
82497
82923
  const afterTable = after.tables[tableName];
82924
+ if (!beforeTable || !afterTable)
82925
+ continue;
82498
82926
  const beforeColMap = new Map(beforeTable.columns.map((c) => [c.name, c]));
82499
82927
  const afterColMap = new Map(afterTable.columns.map((c) => [c.name, c]));
82500
82928
  for (const [name, col] of afterColMap) {
82501
82929
  if (!beforeColMap.has(name)) {
82502
- addedColumns.push({ table: tableName, column: name, type: col.type, nullable: col.nullable });
82930
+ addedColumns.push({
82931
+ table: tableName,
82932
+ column: name,
82933
+ type: col.type,
82934
+ nullable: col.nullable
82935
+ });
82503
82936
  }
82504
82937
  }
82505
82938
  for (const [name, col] of beforeColMap) {
@@ -82569,11 +83002,11 @@ async function diffAction(options) {
82569
83002
  tables: {},
82570
83003
  createdAt: new Date().toISOString()
82571
83004
  };
82572
- for (const t7 of tables) {
82573
- if (t7.tableType === "view")
83005
+ for (const t6 of tables) {
83006
+ if (t6.tableType === "view")
82574
83007
  continue;
82575
- const schema = await adapter.getTableSchema(t7.name);
82576
- currentSnapshot.tables[t7.name] = {
83008
+ const schema = await adapter.getTableSchema(t6.name);
83009
+ currentSnapshot.tables[t6.name] = {
82577
83010
  name: schema.name,
82578
83011
  columns: schema.columns,
82579
83012
  indexes: schema.indexes || []
@@ -82686,7 +83119,8 @@ var statusCommand = new Command("status").description("Show current configuratio
82686
83119
  // src/commands/doctor.ts
82687
83120
  init_validation();
82688
83121
  init_schema_path();
82689
- import { join as join10 } from "path";
83122
+ import { join as join11 } from "path";
83123
+ import { resolveSrv as resolveSrv2 } from "dns/promises";
82690
83124
  var ALLOWED_FORMATS7 = ["text", "json"];
82691
83125
  var SENSITIVE_PATTERNS = [
82692
83126
  "password",
@@ -82735,7 +83169,9 @@ var runDoctorChecks = {
82735
83169
  },
82736
83170
  async checkLatestVersion(currentVersion) {
82737
83171
  try {
82738
- const response = await fetch("https://registry.npmjs.org/@carllee1983/dbcli/latest", { signal: AbortSignal.timeout(5000) });
83172
+ const response = await fetch("https://registry.npmjs.org/@carllee1983/dbcli/latest", {
83173
+ signal: AbortSignal.timeout(5000)
83174
+ });
82739
83175
  if (!response.ok)
82740
83176
  throw new Error(`HTTP ${response.status}`);
82741
83177
  const data = await response.json();
@@ -82757,7 +83193,7 @@ var runDoctorChecks = {
82757
83193
  }
82758
83194
  },
82759
83195
  async checkConfigExists(configPath, existsFn) {
82760
- const exists = existsFn ? await existsFn(configPath) : await Bun.file(configPath).exists() || await Bun.file(join10(configPath, "config.json")).exists();
83196
+ const exists = existsFn ? await existsFn(configPath) : await Bun.file(configPath).exists() || await Bun.file(join11(configPath, "config.json")).exists();
82761
83197
  return {
82762
83198
  group: "Configuration",
82763
83199
  label: "Config exists",
@@ -82831,8 +83267,70 @@ var runDoctorChecks = {
82831
83267
  message: versionResult.supported ? t_vars("version.doctor_pass", vars) : t_vars("version.doctor_warn", vars)
82832
83268
  };
82833
83269
  },
83270
+ async checkMongoSrvConnectivity(uri, deps = {}) {
83271
+ if (!uri || !uri.startsWith("mongodb+srv://")) {
83272
+ return null;
83273
+ }
83274
+ const url = new URL(uri);
83275
+ const srvName = `_mongodb._tcp.${url.hostname}`;
83276
+ const resolveSrvFn = deps.resolveSrvFn ?? resolveSrv2;
83277
+ const fetchFn = deps.fetchFn ?? fetch;
83278
+ try {
83279
+ const records = await resolveSrvFn(srvName);
83280
+ if (!records.length) {
83281
+ return {
83282
+ group: "Environment",
83283
+ label: "MongoDB SRV lookup",
83284
+ status: "error",
83285
+ message: `No SRV records found for ${url.hostname}`
83286
+ };
83287
+ }
83288
+ return {
83289
+ group: "Environment",
83290
+ label: "MongoDB SRV lookup",
83291
+ status: "pass",
83292
+ message: `MongoDB SRV lookup reachable for ${url.hostname} (${records.length} record(s))`
83293
+ };
83294
+ } catch (error) {
83295
+ const message = error instanceof Error ? error.message : String(error);
83296
+ const code = error?.code;
83297
+ const isExecutionEnvIssue = code === "ECONNREFUSED" || code === "ETIMEDOUT" || message.includes("Unable to connect. Is the computer able to access the url?") || message.includes("ConnectionRefused");
83298
+ if (!isExecutionEnvIssue) {
83299
+ return {
83300
+ group: "Environment",
83301
+ label: "MongoDB SRV lookup",
83302
+ status: "error",
83303
+ message: `MongoDB SRV lookup failed for ${url.hostname}: ${message}`
83304
+ };
83305
+ }
83306
+ try {
83307
+ const response = await fetchFn(`https://dns.google/resolve?name=${encodeURIComponent(srvName)}&type=SRV`, { signal: AbortSignal.timeout(5000) });
83308
+ if (!response.ok) {
83309
+ throw new Error(`HTTP ${response.status}`);
83310
+ }
83311
+ const payload = await response.json();
83312
+ if (payload.Status !== 0 || !payload.Answer?.length) {
83313
+ throw new Error(payload.Comment || `No SRV records found for ${url.hostname}`);
83314
+ }
83315
+ return {
83316
+ group: "Environment",
83317
+ label: "MongoDB SRV lookup",
83318
+ status: "warn",
83319
+ message: `Direct SRV DNS lookup failed in this shell, but DNS-over-HTTPS fallback resolved ` + `${url.hostname}. dbcli can still connect here, but this runtime environment cannot perform direct SRV lookups.`
83320
+ };
83321
+ } catch (fallbackError) {
83322
+ const fallbackMessage = fallbackError instanceof Error ? fallbackError.message : String(fallbackError);
83323
+ return {
83324
+ group: "Environment",
83325
+ label: "MongoDB SRV lookup",
83326
+ status: "error",
83327
+ message: `MongoDB SRV lookup failed in this environment (${code || "unknown"}); ` + `DNS-over-HTTPS fallback also failed: ${fallbackMessage}`
83328
+ };
83329
+ }
83330
+ }
83331
+ },
82834
83332
  checkLargeTables(tables) {
82835
- const large = tables.filter((t7) => (t7.estimatedRowCount ?? 0) > 1e6);
83333
+ const large = tables.filter((t6) => (t6.estimatedRowCount ?? 0) > 1e6);
82836
83334
  if (large.length === 0) {
82837
83335
  return {
82838
83336
  group: "Connection & Data",
@@ -82841,7 +83339,7 @@ var runDoctorChecks = {
82841
83339
  message: "No tables exceed 1M rows"
82842
83340
  };
82843
83341
  }
82844
- const list = large.map((t7) => `${t7.name} (${((t7.estimatedRowCount ?? 0) / 1e6).toFixed(1)}M rows)`).join(", ");
83342
+ const list = large.map((t6) => `${t6.name} (${((t6.estimatedRowCount ?? 0) / 1e6).toFixed(1)}M rows)`).join(", ");
82845
83343
  return {
82846
83344
  group: "Connection & Data",
82847
83345
  label: "Large tables",
@@ -82851,7 +83349,8 @@ var runDoctorChecks = {
82851
83349
  },
82852
83350
  async checkV2Config(configPath) {
82853
83351
  const results = [];
82854
- const configFile = Bun.file(join10(configPath, "config.json"));
83352
+ const storagePath = await resolveConfigStoragePath(configPath);
83353
+ const configFile = Bun.file(join11(storagePath, "config.json"));
82855
83354
  if (!await configFile.exists())
82856
83355
  return results;
82857
83356
  let raw;
@@ -82891,7 +83390,7 @@ var runDoctorChecks = {
82891
83390
  }
82892
83391
  for (const [name, conn] of Object.entries(config.connections)) {
82893
83392
  if (conn.envFile) {
82894
- const envPath = join10(configPath, "..", conn.envFile);
83393
+ const envPath = join11(storagePath, conn.envFile);
82895
83394
  const exists = await Bun.file(envPath).exists();
82896
83395
  results.push({
82897
83396
  group: "Configuration",
@@ -82927,9 +83426,18 @@ var runDoctorChecks = {
82927
83426
  };
82928
83427
  async function collectMongoDoctorResults(config) {
82929
83428
  const results = [];
83429
+ const mongoConn = config.connection.system === "mongodb" ? config.connection : null;
83430
+ const mongoUriString = mongoConn && typeof mongoConn.uri === "string" ? mongoConn.uri : undefined;
83431
+ const srvCheck = await runDoctorChecks.checkMongoSrvConnectivity(mongoUriString);
83432
+ if (srvCheck) {
83433
+ results.push(srvCheck);
83434
+ if (srvCheck.status === "error") {
83435
+ return results;
83436
+ }
83437
+ }
82930
83438
  const adapter = AdapterFactory.createMongoDBAdapter(config.connection);
82931
- await adapter.connect();
82932
83439
  try {
83440
+ await adapter.connect();
82933
83441
  results.push({
82934
83442
  group: "Connection & Data",
82935
83443
  label: "Connection",
@@ -82945,10 +83453,20 @@ async function collectMongoDoctorResults(config) {
82945
83453
  message: `MongoDB ${version}`
82946
83454
  });
82947
83455
  } catch {}
82948
- const collections = await adapter.listCollections();
82949
- results.push(runDoctorChecks.checkLargeTables(collections.map((collection) => ({
82950
- name: collection.name,
82951
- estimatedRowCount: collection.documentCount
83456
+ const collections = await adapter.listTables();
83457
+ const tableColumns = new Map;
83458
+ for (const coll of collections) {
83459
+ try {
83460
+ const schema = await adapter.getTableSchema(coll.name);
83461
+ tableColumns.set(coll.name, schema.columns.map((c) => c.name));
83462
+ } catch {}
83463
+ }
83464
+ if (config.blacklistedColumns) {
83465
+ results.push(runDoctorChecks.checkBlacklistCompleteness(tableColumns, config.blacklistedColumns));
83466
+ }
83467
+ results.push(runDoctorChecks.checkLargeTables(collections.map((coll) => ({
83468
+ name: coll.name,
83469
+ estimatedRowCount: coll.estimatedRowCount
82952
83470
  }))));
82953
83471
  results.push({
82954
83472
  group: "Connection & Data",
@@ -82956,11 +83474,18 @@ async function collectMongoDoctorResults(config) {
82956
83474
  status: "pass",
82957
83475
  message: collections.length === 0 ? "No collections found" : `Found ${collections.length} collection(s)`
82958
83476
  });
83477
+ const lastUpdated = config.metadata?.schemaLastUpdated ?? null;
83478
+ const freshness = runDoctorChecks.checkSchemaCacheFreshness(lastUpdated);
83479
+ if (!lastUpdated) {
83480
+ freshness.message = 'Schema cache is not tracked for MongoDB \u2014 run "dbcli schema --refresh" to scan collections';
83481
+ }
83482
+ results.push(freshness);
83483
+ } catch (error) {
82959
83484
  results.push({
82960
83485
  group: "Connection & Data",
82961
- label: "Schema cache",
82962
- status: "warn",
82963
- message: config.metadata?.schemaLastUpdated ? `Schema cache timestamp present: ${config.metadata.schemaLastUpdated}` : "Schema cache is not tracked for MongoDB \u2014 run collection inspections instead"
83486
+ label: "Connection",
83487
+ status: "error",
83488
+ message: `Connection failed: ${error.message}`
82964
83489
  });
82965
83490
  } finally {
82966
83491
  await adapter.disconnect();
@@ -82972,11 +83497,12 @@ var doctorCommand = new Command("doctor").description("Run diagnostic checks on
82972
83497
  const logger = getLogger();
82973
83498
  const results = [];
82974
83499
  const configPath = resolveConfigPath(doctorCommand);
83500
+ const storagePath = await resolveConfigStoragePath(configPath);
82975
83501
  const bunVersion = process.versions.bun ?? "unknown";
82976
83502
  const requiredBun = package_default.engines?.bun?.replace(">=", "") ?? "1.3.3";
82977
83503
  results.push(runDoctorChecks.checkBunVersion(bunVersion, requiredBun));
82978
83504
  results.push(await runDoctorChecks.checkLatestVersion(package_default.version));
82979
- const configExists = await runDoctorChecks.checkConfigExists(configPath);
83505
+ const configExists = await runDoctorChecks.checkConfigExists(storagePath);
82980
83506
  results.push(configExists);
82981
83507
  if (configExists.status !== "error") {
82982
83508
  try {
@@ -83003,7 +83529,10 @@ var doctorCommand = new Command("doctor").description("Run diagnostic checks on
83003
83529
  }
83004
83530
  try {
83005
83531
  if (config.connection.system === "mongodb") {
83006
- results.push(...await collectMongoDoctorResults(config));
83532
+ results.push(...await collectMongoDoctorResults({
83533
+ ...config,
83534
+ blacklistedColumns
83535
+ }));
83007
83536
  } else {
83008
83537
  const adapter = AdapterFactory.createAdapter(config.connection);
83009
83538
  await adapter.connect();
@@ -83023,8 +83552,8 @@ var doctorCommand = new Command("doctor").description("Run diagnostic checks on
83023
83552
  try {
83024
83553
  const tables = await adapter.listTables();
83025
83554
  const tableColumns = new Map;
83026
- for (const t7 of tables) {
83027
- tableColumns.set(t7.name, t7.columns.map((c) => c.name));
83555
+ for (const t6 of tables) {
83556
+ tableColumns.set(t6.name, t6.columns.map((c) => c.name));
83028
83557
  }
83029
83558
  results.push(runDoctorChecks.checkBlacklistCompleteness(tableColumns, blacklistedColumns));
83030
83559
  results.push(runDoctorChecks.checkLargeTables(tables));
@@ -83033,7 +83562,7 @@ var doctorCommand = new Command("doctor").description("Run diagnostic checks on
83033
83562
  }
83034
83563
  try {
83035
83564
  const schemaConnName = await getSchemaIsolationConnectionName(configPath);
83036
- const indexPath = join10(resolveSchemaPath(configPath, schemaConnName), "index.json");
83565
+ const indexPath = join11(resolveSchemaPath(storagePath, schemaConnName), "index.json");
83037
83566
  const indexFile = Bun.file(indexPath);
83038
83567
  let indexParsed = null;
83039
83568
  if (await indexFile.exists()) {
@@ -83075,8 +83604,8 @@ var doctorCommand = new Command("doctor").description("Run diagnostic checks on
83075
83604
  });
83076
83605
 
83077
83606
  // src/commands/completion.ts
83078
- import { join as join11 } from "path";
83079
- import { homedir as homedir2 } from "os";
83607
+ import { join as join12 } from "path";
83608
+ import { homedir as homedir3 } from "os";
83080
83609
  function extractCommands(program2) {
83081
83610
  return program2.commands.map((cmd) => ({
83082
83611
  name: cmd.name(),
@@ -83155,10 +83684,7 @@ _dbcli
83155
83684
  `;
83156
83685
  }
83157
83686
  function generateFishCompletion(commands, globalOptions) {
83158
- const lines2 = [
83159
- "# dbcli fish completion \u2014 auto-generated, do not edit",
83160
- ""
83161
- ];
83687
+ const lines2 = ["# dbcli fish completion \u2014 auto-generated, do not edit", ""];
83162
83688
  for (const opt of globalOptions) {
83163
83689
  const longName = opt.replace(/^--/, "");
83164
83690
  lines2.push(`complete -c dbcli -n '__fish_use_subcommand' -l ${longName} -d '${opt}'`);
@@ -83177,14 +83703,14 @@ function generateFishCompletion(commands, globalOptions) {
83177
83703
  `;
83178
83704
  }
83179
83705
  function getInstallPath2(shell) {
83180
- const home = homedir2();
83706
+ const home = homedir3();
83181
83707
  switch (shell) {
83182
83708
  case "bash":
83183
- return join11(home, ".bashrc");
83709
+ return join12(home, ".bashrc");
83184
83710
  case "zsh":
83185
- return join11(home, ".zshrc");
83711
+ return join12(home, ".zshrc");
83186
83712
  case "fish":
83187
- return join11(home, ".config", "fish", "completions", "dbcli.fish");
83713
+ return join12(home, ".config", "fish", "completions", "dbcli.fish");
83188
83714
  default:
83189
83715
  throw new Error(`Unsupported shell: ${shell}. Supported: bash, zsh, fish`);
83190
83716
  }
@@ -83204,7 +83730,7 @@ var MARKER_END = "# <<< dbcli completion <<<";
83204
83730
  async function installCompletion(shell, script) {
83205
83731
  const targetPath = getInstallPath2(shell);
83206
83732
  if (shell === "fish") {
83207
- const dir = join11(homedir2(), ".config", "fish", "completions");
83733
+ const dir = join12(homedir3(), ".config", "fish", "completions");
83208
83734
  await Bun.$`mkdir -p ${dir}`.quiet();
83209
83735
  await Bun.file(targetPath).write(script);
83210
83736
  console.log(colors.success(`\u2713 Fish completion installed to ${targetPath}`));
@@ -83431,8 +83957,8 @@ ${t("upgrade.failed")}`));
83431
83957
 
83432
83958
  // src/commands/shell.ts
83433
83959
  import { createInterface as createInterface2 } from "readline";
83434
- import { join as join12 } from "path";
83435
- import { homedir as homedir3 } from "os";
83960
+ import { join as join13 } from "path";
83961
+ import { homedir as homedir4 } from "os";
83436
83962
 
83437
83963
  // src/core/repl/types.ts
83438
83964
  var SQL_KEYWORDS_FOR_DETECTION = [
@@ -83952,7 +84478,7 @@ class ReplEngine {
83952
84478
  const tableName = this.extractTableName(sql);
83953
84479
  if (tableName) {
83954
84480
  const blacklistedTables = this.config.blacklist.tables ?? [];
83955
- const isBlacklisted = blacklistedTables.some((t7) => t7.toLowerCase() === tableName.toLowerCase());
84481
+ const isBlacklisted = blacklistedTables.some((t6) => t6.toLowerCase() === tableName.toLowerCase());
83956
84482
  if (isBlacklisted) {
83957
84483
  return {
83958
84484
  action: "continue",
@@ -84027,13 +84553,7 @@ var TABLE_POSITION_KEYWORDS = new Set([
84027
84553
  "UPDATE",
84028
84554
  "TABLE"
84029
84555
  ]);
84030
- var COMMANDS_TAKING_TABLE_ARG = new Set([
84031
- "schema",
84032
- "insert",
84033
- "update",
84034
- "delete",
84035
- "check"
84036
- ]);
84556
+ var COMMANDS_TAKING_TABLE_ARG = new Set(["schema", "insert", "update", "delete", "check"]);
84037
84557
  function createCompleter(ctx) {
84038
84558
  const allTableNames = ctx.tableNames;
84039
84559
  const allColumns = Object.values(ctx.columnsByTable).flat();
@@ -84107,7 +84627,7 @@ function extractTableFromLine(line, tableNames) {
84107
84627
  if (fromIdx >= 0) {
84108
84628
  const afterFrom = line.slice(fromIdx + 5).trim().split(/\s+/)[0];
84109
84629
  const candidate = afterFrom.replace(/[;,]/g, "").toLowerCase();
84110
- return tableNames.find((t7) => t7.toLowerCase() === candidate);
84630
+ return tableNames.find((t6) => t6.toLowerCase() === candidate);
84111
84631
  }
84112
84632
  return;
84113
84633
  }
@@ -84157,7 +84677,7 @@ class MongoShellAdapter {
84157
84677
  }
84158
84678
 
84159
84679
  // src/commands/shell.ts
84160
- var HISTORY_PATH = join12(homedir3(), ".dbcli_history");
84680
+ var HISTORY_PATH = join13(homedir4(), ".dbcli_history");
84161
84681
  var shellCommand = new Command("shell").description("Interactive database shell with auto-completion and syntax highlighting").option("--sql", "SQL-only mode (skip dbcli command parsing)").action(async (options, command) => {
84162
84682
  const configPath = resolveConfigPath(command);
84163
84683
  await runShell(options, configPath);
@@ -84171,7 +84691,8 @@ async function runShell(options, configPath) {
84171
84691
  process.exit(1);
84172
84692
  }
84173
84693
  const isMongoDB = config.connection.system === "mongodb";
84174
- const adapter = isMongoDB ? new MongoShellAdapter(AdapterFactory.createMongoDBAdapter(config.connection)) : AdapterFactory.createAdapter(config.connection);
84694
+ const connectionOpts = config.connection;
84695
+ const adapter = isMongoDB ? new MongoShellAdapter(AdapterFactory.createMongoDBAdapter(connectionOpts)) : AdapterFactory.createAdapter(connectionOpts);
84175
84696
  try {
84176
84697
  await adapter.connect();
84177
84698
  } catch (error) {
@@ -84179,7 +84700,7 @@ async function runShell(options, configPath) {
84179
84700
  process.exit(1);
84180
84701
  }
84181
84702
  let tableNames = [];
84182
- let columnsByTable = {};
84703
+ const columnsByTable = {};
84183
84704
  if (isMongoDB) {
84184
84705
  const collections = await adapter.listTables();
84185
84706
  tableNames = collections.map((collection) => collection.name);
@@ -84349,25 +84870,25 @@ class PostgreSQLDDLGenerator {
84349
84870
  alterColumn(options) {
84350
84871
  const statements = [];
84351
84872
  const warnings = [];
84352
- const t7 = q(options.table);
84873
+ const t6 = q(options.table);
84353
84874
  const c = q(options.column);
84354
84875
  if (options.type) {
84355
- statements.push(`ALTER TABLE ${t7} ALTER COLUMN ${c} TYPE ${options.type.toUpperCase()};`);
84876
+ statements.push(`ALTER TABLE ${t6} ALTER COLUMN ${c} TYPE ${options.type.toUpperCase()};`);
84356
84877
  }
84357
84878
  if (options.rename) {
84358
- statements.push(`ALTER TABLE ${t7} RENAME COLUMN ${c} TO ${q(options.rename)};`);
84879
+ statements.push(`ALTER TABLE ${t6} RENAME COLUMN ${c} TO ${q(options.rename)};`);
84359
84880
  }
84360
84881
  if (options.setDefault !== undefined) {
84361
- statements.push(`ALTER TABLE ${t7} ALTER COLUMN ${c} SET DEFAULT ${options.setDefault};`);
84882
+ statements.push(`ALTER TABLE ${t6} ALTER COLUMN ${c} SET DEFAULT ${options.setDefault};`);
84362
84883
  }
84363
84884
  if (options.dropDefault) {
84364
- statements.push(`ALTER TABLE ${t7} ALTER COLUMN ${c} DROP DEFAULT;`);
84885
+ statements.push(`ALTER TABLE ${t6} ALTER COLUMN ${c} DROP DEFAULT;`);
84365
84886
  }
84366
84887
  if (options.setNullable) {
84367
- statements.push(`ALTER TABLE ${t7} ALTER COLUMN ${c} DROP NOT NULL;`);
84888
+ statements.push(`ALTER TABLE ${t6} ALTER COLUMN ${c} DROP NOT NULL;`);
84368
84889
  }
84369
84890
  if (options.dropNullable) {
84370
- statements.push(`ALTER TABLE ${t7} ALTER COLUMN ${c} SET NOT NULL;`);
84891
+ statements.push(`ALTER TABLE ${t6} ALTER COLUMN ${c} SET NOT NULL;`);
84371
84892
  }
84372
84893
  if (statements.length === 0) {
84373
84894
  warnings.push("No alter operations specified");
@@ -84389,14 +84910,14 @@ class PostgreSQLDDLGenerator {
84389
84910
  return { sql: `DROP INDEX ${q(indexName)};`, warnings: [] };
84390
84911
  }
84391
84912
  addConstraint(constraint) {
84392
- const t7 = q(constraint.table);
84913
+ const t6 = q(constraint.table);
84393
84914
  const warnings = [];
84394
84915
  switch (constraint.type) {
84395
84916
  case "foreign_key": {
84396
84917
  const name = constraint.name || `fk_${constraint.table}_${constraint.column}`;
84397
84918
  const onDelete = constraint.onDelete ? ` ON DELETE ${constraint.onDelete.toUpperCase().replace("_", " ")}` : "";
84398
84919
  return {
84399
- sql: `ALTER TABLE ${t7} ADD CONSTRAINT ${q(name)} FOREIGN KEY (${q(constraint.column)}) REFERENCES ${q(constraint.references.table)}(${q(constraint.references.column)})${onDelete};`,
84920
+ sql: `ALTER TABLE ${t6} ADD CONSTRAINT ${q(name)} FOREIGN KEY (${q(constraint.column)}) REFERENCES ${q(constraint.references.table)}(${q(constraint.references.column)})${onDelete};`,
84400
84921
  warnings
84401
84922
  };
84402
84923
  }
@@ -84404,14 +84925,14 @@ class PostgreSQLDDLGenerator {
84404
84925
  const name = constraint.name || `uq_${constraint.table}_${constraint.columns.join("_")}`;
84405
84926
  const cols = constraint.columns.map(q).join(", ");
84406
84927
  return {
84407
- sql: `ALTER TABLE ${t7} ADD CONSTRAINT ${q(name)} UNIQUE (${cols});`,
84928
+ sql: `ALTER TABLE ${t6} ADD CONSTRAINT ${q(name)} UNIQUE (${cols});`,
84408
84929
  warnings
84409
84930
  };
84410
84931
  }
84411
84932
  case "check": {
84412
84933
  const name = constraint.name || `ck_${constraint.table}`;
84413
84934
  return {
84414
- sql: `ALTER TABLE ${t7} ADD CONSTRAINT ${q(name)} CHECK (${constraint.expression});`,
84935
+ sql: `ALTER TABLE ${t6} ADD CONSTRAINT ${q(name)} CHECK (${constraint.expression});`,
84415
84936
  warnings
84416
84937
  };
84417
84938
  }
@@ -84514,19 +85035,19 @@ class MySQLDDLGenerator {
84514
85035
  alterColumn(options) {
84515
85036
  const statements = [];
84516
85037
  const warnings = [];
84517
- const t7 = q2(options.table);
85038
+ const t6 = q2(options.table);
84518
85039
  const c = q2(options.column);
84519
85040
  if (options.type) {
84520
85041
  const nullable = options.dropNullable ? " NOT NULL" : "";
84521
85042
  const def = options.setDefault !== undefined ? ` DEFAULT ${options.setDefault}` : "";
84522
- statements.push(`ALTER TABLE ${t7} MODIFY COLUMN ${c} ${options.type.toUpperCase()}${nullable}${def};`);
85043
+ statements.push(`ALTER TABLE ${t6} MODIFY COLUMN ${c} ${options.type.toUpperCase()}${nullable}${def};`);
84523
85044
  warnings.push("MySQL MODIFY COLUMN resets column attributes not explicitly specified");
84524
85045
  } else {
84525
85046
  if (options.setDefault !== undefined) {
84526
- statements.push(`ALTER TABLE ${t7} ALTER COLUMN ${c} SET DEFAULT ${options.setDefault};`);
85047
+ statements.push(`ALTER TABLE ${t6} ALTER COLUMN ${c} SET DEFAULT ${options.setDefault};`);
84527
85048
  }
84528
85049
  if (options.dropDefault) {
84529
- statements.push(`ALTER TABLE ${t7} ALTER COLUMN ${c} DROP DEFAULT;`);
85050
+ statements.push(`ALTER TABLE ${t6} ALTER COLUMN ${c} DROP DEFAULT;`);
84530
85051
  }
84531
85052
  if (options.setNullable) {
84532
85053
  warnings.push("MySQL requires MODIFY COLUMN with full type to change nullability \u2014 use --type to specify");
@@ -84536,7 +85057,7 @@ class MySQLDDLGenerator {
84536
85057
  }
84537
85058
  }
84538
85059
  if (options.rename) {
84539
- statements.push(`ALTER TABLE ${t7} RENAME COLUMN ${c} TO ${q2(options.rename)};`);
85060
+ statements.push(`ALTER TABLE ${t6} RENAME COLUMN ${c} TO ${q2(options.rename)};`);
84540
85061
  }
84541
85062
  if (statements.length === 0 && warnings.length === 0) {
84542
85063
  warnings.push("No alter operations specified");
@@ -84562,14 +85083,14 @@ class MySQLDDLGenerator {
84562
85083
  };
84563
85084
  }
84564
85085
  addConstraint(constraint) {
84565
- const t7 = q2(constraint.table);
85086
+ const t6 = q2(constraint.table);
84566
85087
  const warnings = [];
84567
85088
  switch (constraint.type) {
84568
85089
  case "foreign_key": {
84569
85090
  const name = constraint.name || `fk_${constraint.table}_${constraint.column}`;
84570
85091
  const onDelete = constraint.onDelete ? ` ON DELETE ${constraint.onDelete.toUpperCase().replace("_", " ")}` : "";
84571
85092
  return {
84572
- sql: `ALTER TABLE ${t7} ADD CONSTRAINT ${q2(name)} FOREIGN KEY (${q2(constraint.column)}) REFERENCES ${q2(constraint.references.table)}(${q2(constraint.references.column)})${onDelete};`,
85093
+ sql: `ALTER TABLE ${t6} ADD CONSTRAINT ${q2(name)} FOREIGN KEY (${q2(constraint.column)}) REFERENCES ${q2(constraint.references.table)}(${q2(constraint.references.column)})${onDelete};`,
84573
85094
  warnings
84574
85095
  };
84575
85096
  }
@@ -84577,14 +85098,14 @@ class MySQLDDLGenerator {
84577
85098
  const name = constraint.name || `uq_${constraint.table}_${constraint.columns.join("_")}`;
84578
85099
  const cols = constraint.columns.map(q2).join(", ");
84579
85100
  return {
84580
- sql: `ALTER TABLE ${t7} ADD CONSTRAINT ${q2(name)} UNIQUE (${cols});`,
85101
+ sql: `ALTER TABLE ${t6} ADD CONSTRAINT ${q2(name)} UNIQUE (${cols});`,
84581
85102
  warnings
84582
85103
  };
84583
85104
  }
84584
85105
  case "check": {
84585
85106
  const name = constraint.name || `ck_${constraint.table}`;
84586
85107
  return {
84587
- sql: `ALTER TABLE ${t7} ADD CONSTRAINT ${q2(name)} CHECK (${constraint.expression});`,
85108
+ sql: `ALTER TABLE ${t6} ADD CONSTRAINT ${q2(name)} CHECK (${constraint.expression});`,
84588
85109
  warnings: ["CHECK constraints enforced in MySQL 8.0.16+ and MariaDB 10.2.1+ only"]
84589
85110
  };
84590
85111
  }
@@ -84599,13 +85120,17 @@ class MySQLDDLGenerator {
84599
85120
  addEnum(_definition) {
84600
85121
  return {
84601
85122
  sql: "",
84602
- warnings: [`MySQL has no standalone ENUM type \u2014 use ENUM in column definition instead (e.g., "status:enum('a','b'):not-null")`]
85123
+ warnings: [
85124
+ `MySQL has no standalone ENUM type \u2014 use ENUM in column definition instead (e.g., "status:enum('a','b'):not-null")`
85125
+ ]
84603
85126
  };
84604
85127
  }
84605
85128
  alterEnum(_name, _addValue) {
84606
85129
  return {
84607
85130
  sql: "",
84608
- warnings: ["MySQL has no standalone ENUM type \u2014 use ALTER TABLE MODIFY COLUMN to change enum values"]
85131
+ warnings: [
85132
+ "MySQL has no standalone ENUM type \u2014 use ALTER TABLE MODIFY COLUMN to change enum values"
85133
+ ]
84609
85134
  };
84610
85135
  }
84611
85136
  dropEnum(_name) {
@@ -85093,7 +85618,7 @@ addExecOpts(migrateCommand.command("drop-enum <name>").description(t("migrate.dr
85093
85618
  });
85094
85619
 
85095
85620
  // src/commands/use.ts
85096
- import { join as join13 } from "path";
85621
+ import { join as join14 } from "path";
85097
85622
  async function switchDefault(configPath, name, config) {
85098
85623
  if (!config.connections[name]) {
85099
85624
  const available = Object.keys(config.connections).join(", ");
@@ -85115,15 +85640,41 @@ function listConnectionsForDisplay(config) {
85115
85640
  });
85116
85641
  }
85117
85642
  async function ensureV2Config(configPath) {
85118
- const configFile = Bun.file(join13(configPath, "config.json"));
85119
- if (!await configFile.exists()) {
85643
+ const storagePath = await resolveConfigStoragePath(configPath);
85644
+ const configFile = Bun.file(join14(storagePath, "config.json"));
85645
+ const legacyFile = Bun.file(configPath);
85646
+ if (!await configFile.exists() && !await legacyFile.exists()) {
85120
85647
  throw new ConfigError(t("init.config_not_found"));
85121
85648
  }
85122
- const raw = JSON.parse(await configFile.text());
85123
- if (!raw.version || raw.version !== 2 || !raw.connections) {
85649
+ try {
85650
+ const raw = await (async () => {
85651
+ if (await configFile.exists())
85652
+ return JSON.parse(await configFile.text());
85653
+ return JSON.parse(await legacyFile.text());
85654
+ })();
85655
+ if (!raw.version || raw.version !== 2 || !raw.connections) {
85656
+ const v1Config = await configModule.read(configPath);
85657
+ return {
85658
+ version: 2,
85659
+ default: "default",
85660
+ connections: {
85661
+ default: {
85662
+ ...v1Config.connection,
85663
+ permission: v1Config.permission
85664
+ }
85665
+ },
85666
+ schema: v1Config.schema || {},
85667
+ schemas: { default: v1Config.schema || {} },
85668
+ metadata: v1Config.metadata || { version: "1.0" },
85669
+ blacklist: v1Config.blacklist || { tables: [], columns: {} }
85670
+ };
85671
+ }
85672
+ return readV2Config(storagePath);
85673
+ } catch (error) {
85674
+ if (error instanceof ConfigError)
85675
+ throw error;
85124
85676
  throw new ConfigError(t("use.requires_v2"));
85125
85677
  }
85126
- return readV2Config(configPath);
85127
85678
  }
85128
85679
  var useCommand = new Command("use").description("Switch or display the default database connection (v2 config)").argument("[name]", "Connection name to switch to").option("--list", "List all connections").action(async (name, options) => {
85129
85680
  try {
@@ -85152,7 +85703,7 @@ var useCommand = new Command("use").description("Switch or display the default d
85152
85703
  });
85153
85704
 
85154
85705
  // src/cli.ts
85155
- import { join as join14 } from "path";
85706
+ import { join as join15 } from "path";
85156
85707
  var _bgVersionCheckResult;
85157
85708
  var program2 = new Command().name("dbcli").description("Database CLI for AI agents").version(package_default.version).option("--no-color", "Disable colored output").option("-v, --verbose", "Increase verbosity (-v verbose, -vv debug)", (_, prev) => prev + 1, 0).option("-q, --quiet", "Suppress non-essential output").option("--config <path>", "Path to .dbcli config file", ".dbcli").option("--use <connection>", "Use a specific named connection (v2 config)");
85158
85709
  program2.hook("preAction", (thisCommand, actionCommand) => {
@@ -85178,7 +85729,7 @@ program2.hook("preAction", (thisCommand, actionCommand) => {
85178
85729
  try {
85179
85730
  let cache = null;
85180
85731
  try {
85181
- const cacheFile = Bun.file(join14(configPath, "version-check.json"));
85732
+ const cacheFile = Bun.file(join15(configPath, "version-check.json"));
85182
85733
  if (await cacheFile.exists()) {
85183
85734
  cache = await cacheFile.json();
85184
85735
  }