@carllee1983/dbcli 1.5.2 → 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
  }
@@ -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.2",
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,
@@ -79145,6 +79263,40 @@ class MongoDBAdapter {
79145
79263
  }));
79146
79264
  return results;
79147
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
+ }
79148
79300
  async testConnection() {
79149
79301
  if (!this.client)
79150
79302
  return false;
@@ -79155,6 +79307,31 @@ class MongoDBAdapter {
79155
79307
  const info = await this.getDatabase().admin().serverInfo();
79156
79308
  return info.version ?? "unknown";
79157
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
+ }
79158
79335
  }
79159
79336
 
79160
79337
  // src/adapters/factory.ts
@@ -79166,6 +79343,8 @@ class AdapterFactory {
79166
79343
  case "mysql":
79167
79344
  case "mariadb":
79168
79345
  return new MySQLAdapter(options);
79346
+ case "mongodb":
79347
+ return new MongoDBAdapter(options);
79169
79348
  default:
79170
79349
  throw new Error(`Unsupported database system: ${options.system}`);
79171
79350
  }
@@ -79197,9 +79376,11 @@ function resolveConfigPath(command, options, fallback = ".dbcli") {
79197
79376
  // src/commands/init.ts
79198
79377
  var VALID_PERMISSIONS = ["query-only", "read-write", "data-admin", "admin"];
79199
79378
  async function checkOverwrite(configPath, shouldPrompt, force) {
79379
+ const storagePath = await resolveConfigStoragePath(configPath);
79200
79380
  const fileExists = await Bun.file(configPath).exists();
79201
- const dirConfigExists = await Bun.file(join7(configPath, "config.json")).exists();
79202
- 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)
79203
79384
  return true;
79204
79385
  if (shouldPrompt) {
79205
79386
  const overwrite = await promptUser.confirm(t("init.config_exists_overwrite"));
@@ -79212,7 +79393,8 @@ async function checkOverwrite(configPath, shouldPrompt, force) {
79212
79393
  throw new Error(t("init.config_exists_use_force"));
79213
79394
  }
79214
79395
  async function handleRemove(configPath, name) {
79215
- const configFile = Bun.file(join7(configPath, "config.json"));
79396
+ const storagePath = await resolveConfigStoragePath(configPath);
79397
+ const configFile = Bun.file(join8(storagePath, "config.json"));
79216
79398
  if (!await configFile.exists()) {
79217
79399
  throw new Error(t("init.config_not_found"));
79218
79400
  }
@@ -79220,7 +79402,7 @@ async function handleRemove(configPath, name) {
79220
79402
  if (detectConfigVersion(raw) !== 2) {
79221
79403
  throw new Error(t("init.requires_v2_remove"));
79222
79404
  }
79223
- const config = await readV2Config(configPath);
79405
+ const config = await readV2Config(storagePath);
79224
79406
  if (!config.connections[name]) {
79225
79407
  throw new Error(t_vars("init.connection_not_found", { name }));
79226
79408
  }
@@ -79228,14 +79410,14 @@ async function handleRemove(configPath, name) {
79228
79410
  if (connectionCount <= 1) {
79229
79411
  throw new Error(t("init.cannot_remove_last"));
79230
79412
  }
79231
- const { [name]: _removed, ...remaining } = config.connections;
79413
+ const remaining = Object.fromEntries(Object.entries(config.connections).filter(([connectionName]) => connectionName !== name));
79232
79414
  const newDefault = config.default === name ? Object.keys(remaining)[0] : config.default;
79233
79415
  const updated = {
79234
79416
  ...config,
79235
79417
  default: newDefault,
79236
79418
  connections: remaining
79237
79419
  };
79238
- await writeV2Config(configPath, updated);
79420
+ await writeV2Config(storagePath, updated);
79239
79421
  if (config.default === name) {
79240
79422
  console.log(t_vars("init.connection_removed_switched", { name, newDefault }));
79241
79423
  } else {
@@ -79247,7 +79429,8 @@ async function handleRename(configPath, renameArg) {
79247
79429
  if (!oldName || !newName) {
79248
79430
  throw new Error(t("init.rename_invalid_format"));
79249
79431
  }
79250
- const configFile = Bun.file(join7(configPath, "config.json"));
79432
+ const storagePath = await resolveConfigStoragePath(configPath);
79433
+ const configFile = Bun.file(join8(storagePath, "config.json"));
79251
79434
  if (!await configFile.exists()) {
79252
79435
  throw new Error(t("init.config_not_found"));
79253
79436
  }
@@ -79255,7 +79438,7 @@ async function handleRename(configPath, renameArg) {
79255
79438
  if (detectConfigVersion(raw) !== 2) {
79256
79439
  throw new Error(t("init.requires_v2_rename"));
79257
79440
  }
79258
- const config = await readV2Config(configPath);
79441
+ const config = await readV2Config(storagePath);
79259
79442
  if (!config.connections[oldName]) {
79260
79443
  throw new Error(t_vars("init.connection_not_found", { name: oldName }));
79261
79444
  }
@@ -79268,17 +79451,54 @@ async function handleRename(configPath, renameArg) {
79268
79451
  default: config.default === oldName ? newName : config.default,
79269
79452
  connections: Object.fromEntries(entries)
79270
79453
  };
79271
- await writeV2Config(configPath, updated);
79454
+ await writeV2Config(storagePath, updated);
79272
79455
  console.log(t_vars("init.connection_renamed", { oldName, newName }));
79273
79456
  }
79274
79457
  async function writeV2InitConfig(configPath, connectionName, connection, permission, envFile) {
79275
- const configJsonPath = join7(configPath, "config.json");
79458
+ const storagePath = getProjectStoragePath(configPath);
79459
+ const configJsonPath = join8(storagePath, "config.json");
79276
79460
  const configFile = Bun.file(configJsonPath);
79461
+ const projectConfigFile = Bun.file(join8(configPath, "config.json"));
79277
79462
  let existingV2 = null;
79278
79463
  if (await configFile.exists()) {
79279
79464
  const raw = JSON.parse(await configFile.text());
79280
79465
  if (detectConfigVersion(raw) === 2) {
79281
- 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
+ };
79282
79502
  } else {
79283
79503
  const v1Config = await configModule.read(configPath);
79284
79504
  existingV2 = {
@@ -79291,16 +79511,17 @@ async function writeV2InitConfig(configPath, connectionName, connection, permiss
79291
79511
  }
79292
79512
  },
79293
79513
  schema: v1Config.schema || {},
79514
+ schemas: { default: v1Config.schema || {} },
79294
79515
  metadata: v1Config.metadata || { version: "1.0" },
79295
79516
  blacklist: v1Config.blacklist || { tables: [], columns: {} }
79296
79517
  };
79297
79518
  }
79298
79519
  } else {
79299
- const legacyFile = Bun.file(configPath);
79520
+ const legacyFile = Bun.file(storagePath);
79300
79521
  if (await legacyFile.exists()) {
79301
79522
  const raw = JSON.parse(await legacyFile.text());
79302
79523
  if (detectConfigVersion(raw) !== 2) {
79303
- const v1Config = await configModule.read(configPath);
79524
+ const v1Config = await configModule.read(storagePath);
79304
79525
  existingV2 = {
79305
79526
  version: 2,
79306
79527
  default: "default",
@@ -79311,6 +79532,7 @@ async function writeV2InitConfig(configPath, connectionName, connection, permiss
79311
79532
  }
79312
79533
  },
79313
79534
  schema: v1Config.schema || {},
79535
+ schemas: { default: v1Config.schema || {} },
79314
79536
  metadata: v1Config.metadata || { version: "1.0" },
79315
79537
  blacklist: v1Config.blacklist || { tables: [], columns: {} }
79316
79538
  };
@@ -79337,11 +79559,13 @@ async function writeV2InitConfig(configPath, connectionName, connection, permiss
79337
79559
  [connectionName]: connEntry
79338
79560
  },
79339
79561
  schema: {},
79562
+ schemas: {},
79340
79563
  metadata: { version: "1.0", createdAt: new Date().toISOString() },
79341
79564
  blacklist: { tables: [], columns: {} }
79342
79565
  };
79343
- await Bun.$`mkdir -p ${configPath}`;
79344
- await writeV2Config(configPath, v2Config);
79566
+ await writeV2Config(storagePath, v2Config);
79567
+ await migrateLegacyProjectEnvLocal(configPath, storagePath);
79568
+ await writeProjectBinding(configPath, storagePath);
79345
79569
  console.log(t("init.config_saved"));
79346
79570
  }
79347
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) => {
@@ -79380,7 +79604,8 @@ async function initCommandHandler(options, command) {
79380
79604
  console.log(t("init.env_parse_note"));
79381
79605
  }
79382
79606
  }
79383
- let system = options.system || envConfig?.system || "postgresql";
79607
+ const systemFromCli = typeof options.system === "string" ? options.system : undefined;
79608
+ let system = systemFromCli ?? envConfig?.system ?? "postgresql";
79384
79609
  if (shouldPrompt && !options.system && !envConfig?.system) {
79385
79610
  system = await promptUser.select(t("init.select_system"), [
79386
79611
  "postgresql",
@@ -79409,11 +79634,11 @@ async function initCommandHandler(options, command) {
79409
79634
  };
79410
79635
  let configForWrite;
79411
79636
  if (options.useEnvRefs && shouldPrompt) {
79412
- let envHost = options.envHost || await promptUser.text(t("init.prompt_host"), "DB_HOST");
79413
- let envPort = options.envPort || await promptUser.text(t("init.prompt_port"), "DB_PORT");
79414
- let envUser = options.envUser || await promptUser.text(t("init.prompt_user"), "DB_USER");
79415
- let envPassword = options.envPassword || await promptUser.text(t("init.prompt_password"), "DB_PASSWORD");
79416
- 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");
79417
79642
  configForWrite = {
79418
79643
  system: connection.system,
79419
79644
  host: { $env: envHost },
@@ -79422,7 +79647,8 @@ async function initCommandHandler(options, command) {
79422
79647
  password: { $env: envPassword },
79423
79648
  database: { $env: envDatabase }
79424
79649
  };
79425
- let permission2 = options.permission || "query-only";
79650
+ const permissionFromCli2 = typeof options.permission === "string" ? options.permission : undefined;
79651
+ let permission2 = permissionFromCli2 ?? "query-only";
79426
79652
  if (!options.permission) {
79427
79653
  permission2 = await promptUser.select(t("init.prompt_permission"), [
79428
79654
  "query-only",
@@ -79446,27 +79672,36 @@ async function initCommandHandler(options, command) {
79446
79672
  await writeV2InitConfig(configPath, connectionName, configForWrite, permission2, options.envFile);
79447
79673
  return;
79448
79674
  }
79449
- 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);
79450
79680
  console.log(t("init.config_saved"));
79451
79681
  return;
79452
79682
  }
79453
- connection.host = options.host || envConfig?.host || (shouldPrompt ? await promptUser.text(t("init.prompt_host"), defaults2.host || "localhost") : defaults2.host || "localhost");
79454
- 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));
79455
79689
  const port = parseInt(portStr, 10);
79456
79690
  if (isNaN(port) || port < 1 || port > 65535) {
79457
79691
  throw new Error(t_vars("errors.invalid_port", { port: portStr }));
79458
79692
  }
79459
79693
  connection.port = port;
79460
- 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")) : "");
79461
79695
  if (!connection.user && !shouldPrompt && !options.useEnvRefs) {
79462
79696
  throw new Error(t("errors.require_user"));
79463
79697
  }
79464
- connection.password = options.password || envConfig?.password || (shouldPrompt ? await promptUser.text(t("init.prompt_password")) : "");
79465
- 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")) : "");
79466
79700
  if (!connection.database && !shouldPrompt && !options.useEnvRefs) {
79467
79701
  throw new Error(t("errors.require_name"));
79468
79702
  }
79469
- let permission = options.permission || "query-only";
79703
+ const permissionFromCli = typeof options.permission === "string" ? options.permission : undefined;
79704
+ let permission = permissionFromCli ?? "query-only";
79470
79705
  if (shouldPrompt && !options.permission) {
79471
79706
  permission = await promptUser.select(t("init.prompt_permission"), [
79472
79707
  "query-only",
@@ -79551,7 +79786,11 @@ async function initCommandHandler(options, command) {
79551
79786
  await writeV2InitConfig(configPath, connectionName, configForWrite, permission, options.envFile);
79552
79787
  return;
79553
79788
  }
79554
- 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);
79555
79794
  console.log(t("init.config_saved"));
79556
79795
  }
79557
79796
  async function handleMongoDBInit(ctx) {
@@ -79632,7 +79871,11 @@ async function handleMongoDBInit(ctx) {
79632
79871
  connection: mongoConfig,
79633
79872
  permission
79634
79873
  });
79635
- 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);
79636
79879
  console.log(t("init.config_saved"));
79637
79880
  }
79638
79881
 
@@ -79653,13 +79896,7 @@ class TableFormatter {
79653
79896
  } else if (col.foreignKey) {
79654
79897
  keyType = `FK \u2192 ${col.foreignKey.table}.${col.foreignKey.column}`;
79655
79898
  }
79656
- table.push([
79657
- col.name,
79658
- col.type,
79659
- col.nullable ? "YES" : "NO",
79660
- col.default || "NULL",
79661
- keyType
79662
- ]);
79899
+ table.push([col.name, col.type, col.nullable ? "YES" : "NO", col.default || "NULL", keyType]);
79663
79900
  });
79664
79901
  return table.toString();
79665
79902
  }
@@ -79975,7 +80212,7 @@ init_schema_cache();
79975
80212
 
79976
80213
  // src/core/schema-writer.ts
79977
80214
  init_schema_index();
79978
- import { join as join8 } from "path";
80215
+ import { join as join9 } from "path";
79979
80216
 
79980
80217
  // src/core/atomic-writer.ts
79981
80218
  class AtomicFileWriter {
@@ -80108,7 +80345,7 @@ class SchemaWriter {
80108
80345
  for (const item of mapping.hot) {
80109
80346
  hotSchemas[item.table] = schema[item.table];
80110
80347
  }
80111
- await this.writer.writeJSON(join8(schemaRoot, "hot-schemas.json"), hotSchemas);
80348
+ await this.writer.writeJSON(join9(schemaRoot, "hot-schemas.json"), hotSchemas);
80112
80349
  const coldGroups = {};
80113
80350
  for (const item of mapping.cold) {
80114
80351
  if (!coldGroups[item.file]) {
@@ -80116,10 +80353,10 @@ class SchemaWriter {
80116
80353
  }
80117
80354
  coldGroups[item.file][item.table] = schema[item.table];
80118
80355
  }
80119
- const coldDir = join8(schemaRoot, "cold");
80356
+ const coldDir = join9(schemaRoot, "cold");
80120
80357
  await this.ensureDir(coldDir);
80121
80358
  for (const [fileName, tables] of Object.entries(coldGroups)) {
80122
- const filePath = join8(schemaRoot, fileName);
80359
+ const filePath = join9(schemaRoot, fileName);
80123
80360
  await this.writer.writeJSON(filePath, tables);
80124
80361
  }
80125
80362
  }
@@ -80551,20 +80788,17 @@ var schemaCommand = new Command().name("schema").description("Display table sche
80551
80788
  async function schemaAction(table, options) {
80552
80789
  try {
80553
80790
  validateFormat(options.format, ALLOWED_FORMATS2, "schema");
80791
+ const storagePath = await resolveConfigStoragePath(options.config);
80554
80792
  const config = await configModule.read(options.config);
80555
80793
  if (!config.connection) {
80556
80794
  console.error("Database not configured. Run: dbcli init");
80557
80795
  process.exit(1);
80558
80796
  }
80559
- if (config.connection?.system === "mongodb") {
80560
- console.error("\u6B64\u547D\u4EE4\u76EE\u524D\u4E0D\u652F\u63F4 MongoDB");
80561
- process.exit(1);
80562
- }
80563
80797
  const connectionName = await getSchemaIsolationConnectionName(options.config);
80564
80798
  let existingSchemaCount;
80565
80799
  if (connectionName !== undefined) {
80566
80800
  try {
80567
- const v2Raw = await readV2Config(options.config);
80801
+ const v2Raw = await readV2Config(storagePath);
80568
80802
  existingSchemaCount = Object.keys(v2Raw.schemas?.[connectionName] ?? {}).length;
80569
80803
  } catch {
80570
80804
  existingSchemaCount = 0;
@@ -80576,13 +80810,13 @@ async function schemaAction(table, options) {
80576
80810
  await adapter.connect();
80577
80811
  try {
80578
80812
  if (options.reset) {
80579
- await handleSchemaReset(adapter, config, options, connectionName, existingSchemaCount);
80813
+ await handleSchemaReset(adapter, config, options, connectionName, existingSchemaCount, storagePath);
80580
80814
  } else if (options.refresh) {
80581
- await handleSchemaRefresh(adapter, config, options, connectionName);
80815
+ await handleSchemaRefresh(adapter, config, options, connectionName, storagePath);
80582
80816
  } else if (table) {
80583
80817
  await handleSingleTableSchema(adapter, table, options.format);
80584
80818
  } else {
80585
- await handleFullDatabaseScan(adapter, config, options, connectionName, existingSchemaCount);
80819
+ await handleFullDatabaseScan(adapter, config, options, connectionName, existingSchemaCount, storagePath);
80586
80820
  }
80587
80821
  } finally {
80588
80822
  await adapter.disconnect();
@@ -80642,7 +80876,7 @@ Indexes:`);
80642
80876
  }
80643
80877
  }
80644
80878
  }
80645
- async function handleSchemaRefresh(adapter, config, options, connectionName) {
80879
+ async function handleSchemaRefresh(adapter, config, options, connectionName, storagePath) {
80646
80880
  const diffEngine = new SchemaDiffEngine(adapter, config);
80647
80881
  const report = await diffEngine.diff();
80648
80882
  if (report.tablesAdded.length === 0 && report.tablesRemoved.length === 0 && Object.keys(report.tablesModified).length === 0) {
@@ -80653,7 +80887,7 @@ async function handleSchemaRefresh(adapter, config, options, connectionName) {
80653
80887
  schemaTableCount: Object.keys(config.schema || {}).length
80654
80888
  }
80655
80889
  });
80656
- await writeSchema(options.config, updatedConfig2, connectionName);
80890
+ await writeSchema(storagePath, updatedConfig2, connectionName);
80657
80891
  console.log("\u2705 Schema is up-to-date (no changes detected)");
80658
80892
  return;
80659
80893
  }
@@ -80677,16 +80911,16 @@ async function handleSchemaRefresh(adapter, config, options, connectionName) {
80677
80911
  schemaTableCount: Object.keys(newSchema).length
80678
80912
  }
80679
80913
  });
80680
- const writer = new SchemaWriter(options.config);
80914
+ const writer = new SchemaWriter(storagePath);
80681
80915
  await writer.save(newSchema, connectionName);
80682
80916
  console.log(`\u2705 Schema persisted to layered storage (.dbcli/schemas/${connectionName || ""})`);
80683
- await writeSchema(options.config, updatedConfig, connectionName);
80917
+ await writeSchema(storagePath, updatedConfig, connectionName);
80684
80918
  console.log(`\u2705 Schema updated in .dbcli`);
80685
80919
  }
80686
- async function handleSchemaReset(adapter, config, options, connectionName, existingCount) {
80920
+ async function handleSchemaReset(adapter, config, options, connectionName, existingCount, storagePath) {
80687
80921
  if (existingCount > 0 && !options.force) {
80688
80922
  const { SchemaLayeredLoader: SchemaLayeredLoader3 } = await Promise.resolve().then(() => (init_schema_loader(), exports_schema_loader));
80689
- const loader = new SchemaLayeredLoader3(options.config, { connectionName });
80923
+ const loader = new SchemaLayeredLoader3(storagePath, { connectionName });
80690
80924
  const { index } = await loader.initialize();
80691
80925
  if (!index || Object.keys(index.tables).length === 0) {
80692
80926
  console.log(`\u26A0 This will clear ${existingCount} existing table schemas and re-fetch from database.`);
@@ -80705,8 +80939,8 @@ async function handleSchemaReset(adapter, config, options, connectionName, exist
80705
80939
  schema: {},
80706
80940
  metadata: { ...config.metadata, ...emptyMeta }
80707
80941
  };
80708
- await writeSchema(options.config, configWithoutSchema, connectionName);
80709
- const writer = new SchemaWriter(options.config);
80942
+ await writeSchema(storagePath, configWithoutSchema, connectionName);
80943
+ const writer = new SchemaWriter(storagePath);
80710
80944
  await writer.clear(connectionName);
80711
80945
  console.log(t("schema.scanning_database"));
80712
80946
  const tables = await adapter.listTables();
@@ -80742,7 +80976,7 @@ async function handleSchemaReset(adapter, config, options, connectionName, exist
80742
80976
  };
80743
80977
  await writer.save(schemaData, connectionName);
80744
80978
  console.log(`\u2705 Schema persisted to layered storage (.dbcli/schemas/${connectionName || ""})`);
80745
- await writeSchema(options.config, updatedConfig, connectionName);
80979
+ await writeSchema(storagePath, updatedConfig, connectionName);
80746
80980
  if (existingCount > 0) {
80747
80981
  console.log(`
80748
80982
  \u2705 Schema reset complete \u2014 cleared ${existingCount} old tables, fetched ${tables.length} tables from database`);
@@ -80751,7 +80985,7 @@ async function handleSchemaReset(adapter, config, options, connectionName, exist
80751
80985
  \u2705 Schema fetched \u2014 ${tables.length} tables from database`);
80752
80986
  }
80753
80987
  }
80754
- async function handleFullDatabaseScan(adapter, config, options, connectionName, existingSchemaCount) {
80988
+ async function handleFullDatabaseScan(adapter, config, options, connectionName, existingSchemaCount, storagePath) {
80755
80989
  console.log(t("schema.scanning_database"));
80756
80990
  const tables = await adapter.listTables();
80757
80991
  console.log(t_vars("schema.tables_found", { count: tables.length }));
@@ -80777,7 +81011,7 @@ async function handleFullDatabaseScan(adapter, config, options, connectionName,
80777
81011
  }
80778
81012
  if (existingSchemaCount > 0 && !options.force) {
80779
81013
  const { SchemaLayeredLoader: SchemaLayeredLoader3 } = await Promise.resolve().then(() => (init_schema_loader(), exports_schema_loader));
80780
- const loader = new SchemaLayeredLoader3(options.config, { connectionName });
81014
+ const loader = new SchemaLayeredLoader3(storagePath, { connectionName });
80781
81015
  const { index } = await loader.initialize();
80782
81016
  if (!index || Object.keys(index.tables).length === 0) {
80783
81017
  console.log(`
@@ -80801,10 +81035,10 @@ async function handleFullDatabaseScan(adapter, config, options, connectionName,
80801
81035
  schemaTableCount: tables.length
80802
81036
  }
80803
81037
  };
80804
- const writer = new SchemaWriter(options.config);
81038
+ const writer = new SchemaWriter(storagePath);
80805
81039
  await writer.save(schemaData, connectionName);
80806
81040
  console.log(`\u2705 Schema persisted to layered storage (.dbcli/schemas/${connectionName || ""})`);
80807
- await writeSchema(options.config, updatedConfig, connectionName);
81041
+ await writeSchema(storagePath, updatedConfig, connectionName);
80808
81042
  console.log(`
80809
81043
  \u2705 Schema updated in .dbcli`);
80810
81044
  console.log(` ${tables.length} tables with full column details and relationships`);
@@ -81003,12 +81237,7 @@ function determineConfidence(type, keyword, sql) {
81003
81237
  if (highConfidenceTypes.includes(type)) {
81004
81238
  return "HIGH";
81005
81239
  }
81006
- const mediumConfidenceTypes = [
81007
- "CREATE",
81008
- "ALTER",
81009
- "DROP",
81010
- "TRUNCATE"
81011
- ];
81240
+ const mediumConfidenceTypes = ["CREATE", "ALTER", "DROP", "TRUNCATE"];
81012
81241
  if (mediumConfidenceTypes.includes(type)) {
81013
81242
  return "MEDIUM";
81014
81243
  }
@@ -81042,15 +81271,7 @@ function checkPermission(sql, permission) {
81042
81271
  };
81043
81272
  }
81044
81273
  if (permission === "data-admin") {
81045
- const allowedTypes = [
81046
- "SELECT",
81047
- "INSERT",
81048
- "UPDATE",
81049
- "DELETE",
81050
- "SHOW",
81051
- "DESCRIBE",
81052
- "EXPLAIN"
81053
- ];
81274
+ const allowedTypes = ["SELECT", "INSERT", "UPDATE", "DELETE", "SHOW", "DESCRIBE", "EXPLAIN"];
81054
81275
  if (allowedTypes.includes(classification.type)) {
81055
81276
  return {
81056
81277
  allowed: true,
@@ -81065,14 +81286,7 @@ function checkPermission(sql, permission) {
81065
81286
  };
81066
81287
  }
81067
81288
  if (permission === "read-write") {
81068
- const allowedTypes = [
81069
- "SELECT",
81070
- "INSERT",
81071
- "UPDATE",
81072
- "SHOW",
81073
- "DESCRIBE",
81074
- "EXPLAIN"
81075
- ];
81289
+ const allowedTypes = ["SELECT", "INSERT", "UPDATE", "SHOW", "DESCRIBE", "EXPLAIN"];
81076
81290
  if (allowedTypes.includes(classification.type)) {
81077
81291
  return {
81078
81292
  allowed: true,
@@ -81363,7 +81577,7 @@ async function queryCommand(sql, options, command) {
81363
81577
  throw new Error('Run "dbcli init" first');
81364
81578
  }
81365
81579
  if (config.connection.system === "mongodb") {
81366
- return mongoQueryBranch(sql, options.collection, config, options.format ?? "table");
81580
+ return mongoQueryBranch(sql, options, config);
81367
81581
  }
81368
81582
  const mainTable = extractMainTable(sql);
81369
81583
  if (mainTable && config.schema && !options.noLimit) {
@@ -81417,10 +81631,12 @@ async function queryCommand(sql, options, command) {
81417
81631
  }
81418
81632
  function extractMainTable(sql) {
81419
81633
  const match = sql.match(/\bFROM\s+[`"']?(\w+)[`"']?/i);
81420
- return match ? match[1] : null;
81634
+ return match?.[1] ?? null;
81421
81635
  }
81422
81636
  var SQL_PATTERN = /^\s*(SELECT|INSERT|UPDATE|DELETE|CREATE|DROP|ALTER|SHOW|DESCRIBE)\b/i;
81423
- 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";
81424
81640
  if (SQL_PATTERN.test(queryStr)) {
81425
81641
  console.error("\u9019\u662F MongoDB \u9023\u7DDA\uFF0C\u8ACB\u4F7F\u7528 JSON filter \u8A9E\u6CD5\u3002");
81426
81642
  console.error(`\u7BC4\u4F8B\uFF1Adbcli query '{"field": "value"}' --collection <name>`);
@@ -81436,19 +81652,50 @@ async function mongoQueryBranch(queryStr, collection, config, format) {
81436
81652
  console.error("MongoDB \u67E5\u8A62\u5FC5\u9808\u662F\u6709\u6548\u7684 JSON\uFF08object filter \u6216 array pipeline\uFF09");
81437
81653
  process.exit(1);
81438
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
+ }
81439
81680
  const mongoAdapter = AdapterFactory.createMongoDBAdapter(config.connection);
81440
81681
  await mongoAdapter.connect();
81441
81682
  try {
81442
81683
  const result = await mongoAdapter.execute(queryStr, [collection]);
81443
- 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);
81444
81686
  const queryResult = {
81445
- rows: result.rows,
81446
- rowCount: result.rows.length,
81447
- columnNames
81687
+ rows: filterResult.filteredRows,
81688
+ rowCount: filterResult.filteredRows.length,
81689
+ columnNames: columnNames.filter((col) => !filterResult.omittedColumns.includes(col))
81448
81690
  };
81449
81691
  const formatter = new QueryResultFormatter;
81450
81692
  const output = formatter.format(queryResult, { format });
81693
+ const securityNote = blacklistValidator.buildSecurityNotification(collection, filterResult.omittedColumns);
81451
81694
  console.log(output);
81695
+ if (securityNote) {
81696
+ console.log(`
81697
+ \u2139 ${securityNote}`);
81698
+ }
81452
81699
  } finally {
81453
81700
  await mongoAdapter.disconnect();
81454
81701
  }
@@ -81786,8 +82033,23 @@ async function insertCommand(table, options, command) {
81786
82033
  throw new Error('Run "dbcli init" to configure database connection');
81787
82034
  }
81788
82035
  if (config.connection.system === "mongodb") {
81789
- console.error("\u6B64\u547D\u4EE4\u76EE\u524D\u4E0D\u652F\u63F4 MongoDB");
81790
- 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
+ }
81791
82053
  }
81792
82054
  const adapter = AdapterFactory.createAdapter(config.connection);
81793
82055
  await adapter.connect();
@@ -81860,7 +82122,11 @@ function parseWhereClause(whereClause) {
81860
82122
  if (!match) {
81861
82123
  throw new Error(`Cannot parse WHERE clause: "${part}". Use format "column=value" or "col1=val1 AND col2=val2"`);
81862
82124
  }
81863
- 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
+ }
81864
82130
  let value = valueStr.trim();
81865
82131
  if (value.startsWith("'") && value.endsWith("'") || value.startsWith('"') && value.endsWith('"')) {
81866
82132
  value = value.slice(1, -1);
@@ -81890,11 +82156,10 @@ async function updateCommand(table, options, command) {
81890
82156
  if (!options.set || options.set.trim() === "") {
81891
82157
  throw new Error(`UPDATE requires --set flag with JSON data (e.g. --set '{"name":"Bob"}')`);
81892
82158
  }
81893
- let whereConditions;
81894
- try {
81895
- whereConditions = parseWhereClause(options.where);
81896
- } catch (error) {
81897
- 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');
81898
82163
  }
81899
82164
  let setData;
81900
82165
  try {
@@ -81905,14 +82170,36 @@ async function updateCommand(table, options, command) {
81905
82170
  if (!setData || typeof setData !== "object" || Array.isArray(setData)) {
81906
82171
  throw new Error('JSON in --set must be an object (e.g. {"name":"Bob","email":"b@example.com"})');
81907
82172
  }
81908
- const configPath = resolveConfigPath(command, options);
81909
- const config = await configModule.read(configPath);
81910
- if (!config.connection) {
81911
- throw new Error('Run "dbcli init" to configure database connection');
81912
- }
81913
82173
  if (config.connection?.system === "mongodb") {
81914
- console.error("\u6B64\u547D\u4EE4\u76EE\u524D\u4E0D\u652F\u63F4 MongoDB");
81915
- 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}`);
81916
82203
  }
81917
82204
  const adapter = AdapterFactory.createAdapter(config.connection);
81918
82205
  await adapter.connect();
@@ -82013,23 +82300,48 @@ async function deleteCommand(table, options, command) {
82013
82300
  if (!options.where || options.where.trim() === "") {
82014
82301
  throw new Error('DELETE requires --where clause (e.g. --where "id=1")');
82015
82302
  }
82016
- let whereConditions;
82017
- try {
82018
- whereConditions = parseWhereClause2(options.where);
82019
- } catch (error) {
82020
- throw new Error(`WHERE clause parsing failed: ${error.message}`);
82021
- }
82022
82303
  const configPath = resolveConfigPath(command, options);
82023
82304
  const config = await configModule.read(configPath);
82024
82305
  if (!config.connection) {
82025
82306
  throw new Error('Run "dbcli init" to configure database connection');
82026
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
+ }
82027
82317
  if (config.connection?.system === "mongodb") {
82028
- console.error("\u6B64\u547D\u4EE4\u76EE\u524D\u4E0D\u652F\u63F4 MongoDB");
82029
- 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
+ }
82030
82339
  }
82031
- if (config.permission !== "data-admin" && config.permission !== "admin") {
82032
- 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}`);
82033
82345
  }
82034
82346
  const adapter = AdapterFactory.createAdapter(config.connection);
82035
82347
  await adapter.connect();
@@ -82157,7 +82469,7 @@ async function exportCommand(sql, options, command) {
82157
82469
  // src/commands/skill.ts
82158
82470
  var {$ } = globalThis.Bun;
82159
82471
  import * as path from "path";
82160
- import { homedir } from "os";
82472
+ import { homedir as homedir2 } from "os";
82161
82473
  function findPackageRoot() {
82162
82474
  let dir = import.meta.dir;
82163
82475
  for (let i = 0;i < 5; i++) {
@@ -82169,6 +82481,7 @@ function findPackageRoot() {
82169
82481
  return path.resolve(import.meta.dir, "../..");
82170
82482
  }
82171
82483
  var SKILL_SOURCE_PATH = path.join(findPackageRoot(), "assets", "SKILL.md");
82484
+ var REFERENCE_SOURCE_PATH = path.join(findPackageRoot(), "assets", "reference.md");
82172
82485
  var SUPPORTED_PLATFORMS = ["claude", "gemini", "copilot", "cursor"];
82173
82486
  async function skillCommand(_program, options) {
82174
82487
  try {
@@ -82176,7 +82489,12 @@ async function skillCommand(_program, options) {
82176
82489
  if (!await skillFile.exists()) {
82177
82490
  throw new Error(`Skill source not found: ${SKILL_SOURCE_PATH}`);
82178
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
+ }
82179
82496
  const skillMarkdown = await skillFile.text();
82497
+ const referenceMarkdown = await refFile.text();
82180
82498
  if (options.output) {
82181
82499
  await Bun.file(options.output).write(skillMarkdown);
82182
82500
  console.error(`Skill written to ${options.output}`);
@@ -82184,9 +82502,8 @@ async function skillCommand(_program, options) {
82184
82502
  }
82185
82503
  if (options.install) {
82186
82504
  const installPath = getInstallPath(options.install);
82187
- await ensureDir(path.dirname(installPath));
82188
- await Bun.file(installPath).write(skillMarkdown);
82189
- 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 ?? "" }));
82190
82507
  return;
82191
82508
  }
82192
82509
  console.log(skillMarkdown);
@@ -82219,7 +82536,7 @@ async function checkSkillUpdates() {
82219
82536
  return outdated;
82220
82537
  }
82221
82538
  function getInstallPath(platform) {
82222
- const home = process.env.HOME || homedir();
82539
+ const home = process.env.HOME || homedir2();
82223
82540
  const platformLower = platform.toLowerCase();
82224
82541
  switch (platformLower) {
82225
82542
  case "claude":
@@ -82234,6 +82551,20 @@ function getInstallPath(platform) {
82234
82551
  throw new Error(`Unknown platform: ${platform}. Supported platforms: ${SUPPORTED_PLATFORMS.join(", ")}`);
82235
82552
  }
82236
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
+ }
82237
82568
  async function ensureDir(dirPath) {
82238
82569
  try {
82239
82570
  await $`mkdir -p ${dirPath}`.quiet();
@@ -82326,7 +82657,7 @@ async function blacklistTableRemove(tableName, configPath) {
82326
82657
  }
82327
82658
  const newBlacklist = {
82328
82659
  ...blacklist,
82329
- tables: blacklist.tables.filter((t7) => t7 !== tableName)
82660
+ tables: blacklist.tables.filter((t6) => t6 !== tableName)
82330
82661
  };
82331
82662
  await configModule.write(configPath, { ...config, blacklist: newBlacklist });
82332
82663
  console.log(t_vars("blacklist.table_removed", { table: tableName }));
@@ -82461,21 +82792,21 @@ async function checkAction(table, options) {
82461
82792
  const tables = await adapter.listTables();
82462
82793
  const reports = [];
82463
82794
  const skipped = [];
82464
- for (const t7 of tables) {
82465
- if (blacklistedTables.has(t7.name.toLowerCase())) {
82466
- skipped.push(`${t7.name} (blacklisted)`);
82795
+ for (const t6 of tables) {
82796
+ if (blacklistedTables.has(t6.name.toLowerCase())) {
82797
+ skipped.push(`${t6.name} (blacklisted)`);
82467
82798
  continue;
82468
82799
  }
82469
- if (t7.tableType === "view") {
82470
- skipped.push(`${t7.name} (view)`);
82800
+ if (t6.tableType === "view") {
82801
+ skipped.push(`${t6.name} (view)`);
82471
82802
  continue;
82472
82803
  }
82473
- const category = getSizeCategory(t7.estimatedRowCount);
82804
+ const category = getSizeCategory(t6.estimatedRowCount);
82474
82805
  if (category === "huge" && !options.includeLarge) {
82475
- skipped.push(`${t7.name} (~${(t7.estimatedRowCount || 0).toLocaleString()} rows, huge)`);
82806
+ skipped.push(`${t6.name} (~${(t6.estimatedRowCount || 0).toLocaleString()} rows, huge)`);
82476
82807
  continue;
82477
82808
  }
82478
- const schema = await adapter.getTableSchema(t7.name);
82809
+ const schema = await adapter.getTableSchema(t6.name);
82479
82810
  const report = await checker.check(schema, {
82480
82811
  checks: checkTypes,
82481
82812
  sample: sampleSize,
@@ -82559,31 +82890,49 @@ var ALLOWED_FORMATS5 = ["json", "table"];
82559
82890
  function compareSnapshots(before, after) {
82560
82891
  const beforeTables = new Set(Object.keys(before.tables));
82561
82892
  const afterTables = new Set(Object.keys(after.tables));
82562
- const addedTables = Array.from(afterTables).filter((t7) => !beforeTables.has(t7));
82563
- 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));
82564
82895
  const addedColumns = [];
82565
82896
  const removedColumns = [];
82566
82897
  const modifiedColumns = [];
82567
82898
  const indexChanges = [];
82568
82899
  for (const tableName of addedTables) {
82569
- for (const col of after.tables[tableName].columns) {
82570
- 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
+ });
82571
82910
  }
82572
82911
  }
82573
82912
  for (const tableName of removedTables) {
82574
- 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) {
82575
82917
  removedColumns.push({ table: tableName, column: col.name, type: col.type });
82576
82918
  }
82577
82919
  }
82578
- const commonTables = Array.from(afterTables).filter((t7) => beforeTables.has(t7));
82920
+ const commonTables = Array.from(afterTables).filter((t6) => beforeTables.has(t6));
82579
82921
  for (const tableName of commonTables) {
82580
82922
  const beforeTable = before.tables[tableName];
82581
82923
  const afterTable = after.tables[tableName];
82924
+ if (!beforeTable || !afterTable)
82925
+ continue;
82582
82926
  const beforeColMap = new Map(beforeTable.columns.map((c) => [c.name, c]));
82583
82927
  const afterColMap = new Map(afterTable.columns.map((c) => [c.name, c]));
82584
82928
  for (const [name, col] of afterColMap) {
82585
82929
  if (!beforeColMap.has(name)) {
82586
- 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
+ });
82587
82936
  }
82588
82937
  }
82589
82938
  for (const [name, col] of beforeColMap) {
@@ -82653,11 +83002,11 @@ async function diffAction(options) {
82653
83002
  tables: {},
82654
83003
  createdAt: new Date().toISOString()
82655
83004
  };
82656
- for (const t7 of tables) {
82657
- if (t7.tableType === "view")
83005
+ for (const t6 of tables) {
83006
+ if (t6.tableType === "view")
82658
83007
  continue;
82659
- const schema = await adapter.getTableSchema(t7.name);
82660
- currentSnapshot.tables[t7.name] = {
83008
+ const schema = await adapter.getTableSchema(t6.name);
83009
+ currentSnapshot.tables[t6.name] = {
82661
83010
  name: schema.name,
82662
83011
  columns: schema.columns,
82663
83012
  indexes: schema.indexes || []
@@ -82770,7 +83119,7 @@ var statusCommand = new Command("status").description("Show current configuratio
82770
83119
  // src/commands/doctor.ts
82771
83120
  init_validation();
82772
83121
  init_schema_path();
82773
- import { join as join10 } from "path";
83122
+ import { join as join11 } from "path";
82774
83123
  import { resolveSrv as resolveSrv2 } from "dns/promises";
82775
83124
  var ALLOWED_FORMATS7 = ["text", "json"];
82776
83125
  var SENSITIVE_PATTERNS = [
@@ -82820,7 +83169,9 @@ var runDoctorChecks = {
82820
83169
  },
82821
83170
  async checkLatestVersion(currentVersion) {
82822
83171
  try {
82823
- 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
+ });
82824
83175
  if (!response.ok)
82825
83176
  throw new Error(`HTTP ${response.status}`);
82826
83177
  const data = await response.json();
@@ -82842,7 +83193,7 @@ var runDoctorChecks = {
82842
83193
  }
82843
83194
  },
82844
83195
  async checkConfigExists(configPath, existsFn) {
82845
- 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();
82846
83197
  return {
82847
83198
  group: "Configuration",
82848
83199
  label: "Config exists",
@@ -82979,7 +83330,7 @@ var runDoctorChecks = {
82979
83330
  }
82980
83331
  },
82981
83332
  checkLargeTables(tables) {
82982
- const large = tables.filter((t7) => (t7.estimatedRowCount ?? 0) > 1e6);
83333
+ const large = tables.filter((t6) => (t6.estimatedRowCount ?? 0) > 1e6);
82983
83334
  if (large.length === 0) {
82984
83335
  return {
82985
83336
  group: "Connection & Data",
@@ -82988,7 +83339,7 @@ var runDoctorChecks = {
82988
83339
  message: "No tables exceed 1M rows"
82989
83340
  };
82990
83341
  }
82991
- 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(", ");
82992
83343
  return {
82993
83344
  group: "Connection & Data",
82994
83345
  label: "Large tables",
@@ -82998,7 +83349,8 @@ var runDoctorChecks = {
82998
83349
  },
82999
83350
  async checkV2Config(configPath) {
83000
83351
  const results = [];
83001
- const configFile = Bun.file(join10(configPath, "config.json"));
83352
+ const storagePath = await resolveConfigStoragePath(configPath);
83353
+ const configFile = Bun.file(join11(storagePath, "config.json"));
83002
83354
  if (!await configFile.exists())
83003
83355
  return results;
83004
83356
  let raw;
@@ -83038,7 +83390,7 @@ var runDoctorChecks = {
83038
83390
  }
83039
83391
  for (const [name, conn] of Object.entries(config.connections)) {
83040
83392
  if (conn.envFile) {
83041
- const envPath = join10(configPath, "..", conn.envFile);
83393
+ const envPath = join11(storagePath, conn.envFile);
83042
83394
  const exists = await Bun.file(envPath).exists();
83043
83395
  results.push({
83044
83396
  group: "Configuration",
@@ -83074,7 +83426,9 @@ var runDoctorChecks = {
83074
83426
  };
83075
83427
  async function collectMongoDoctorResults(config) {
83076
83428
  const results = [];
83077
- const srvCheck = await runDoctorChecks.checkMongoSrvConnectivity(config.connection?.uri);
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);
83078
83432
  if (srvCheck) {
83079
83433
  results.push(srvCheck);
83080
83434
  if (srvCheck.status === "error") {
@@ -83082,8 +83436,8 @@ async function collectMongoDoctorResults(config) {
83082
83436
  }
83083
83437
  }
83084
83438
  const adapter = AdapterFactory.createMongoDBAdapter(config.connection);
83085
- await adapter.connect();
83086
83439
  try {
83440
+ await adapter.connect();
83087
83441
  results.push({
83088
83442
  group: "Connection & Data",
83089
83443
  label: "Connection",
@@ -83099,10 +83453,20 @@ async function collectMongoDoctorResults(config) {
83099
83453
  message: `MongoDB ${version}`
83100
83454
  });
83101
83455
  } catch {}
83102
- const collections = await adapter.listCollections();
83103
- results.push(runDoctorChecks.checkLargeTables(collections.map((collection) => ({
83104
- name: collection.name,
83105
- 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
83106
83470
  }))));
83107
83471
  results.push({
83108
83472
  group: "Connection & Data",
@@ -83110,11 +83474,18 @@ async function collectMongoDoctorResults(config) {
83110
83474
  status: "pass",
83111
83475
  message: collections.length === 0 ? "No collections found" : `Found ${collections.length} collection(s)`
83112
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) {
83113
83484
  results.push({
83114
83485
  group: "Connection & Data",
83115
- label: "Schema cache",
83116
- status: "warn",
83117
- 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}`
83118
83489
  });
83119
83490
  } finally {
83120
83491
  await adapter.disconnect();
@@ -83126,11 +83497,12 @@ var doctorCommand = new Command("doctor").description("Run diagnostic checks on
83126
83497
  const logger = getLogger();
83127
83498
  const results = [];
83128
83499
  const configPath = resolveConfigPath(doctorCommand);
83500
+ const storagePath = await resolveConfigStoragePath(configPath);
83129
83501
  const bunVersion = process.versions.bun ?? "unknown";
83130
83502
  const requiredBun = package_default.engines?.bun?.replace(">=", "") ?? "1.3.3";
83131
83503
  results.push(runDoctorChecks.checkBunVersion(bunVersion, requiredBun));
83132
83504
  results.push(await runDoctorChecks.checkLatestVersion(package_default.version));
83133
- const configExists = await runDoctorChecks.checkConfigExists(configPath);
83505
+ const configExists = await runDoctorChecks.checkConfigExists(storagePath);
83134
83506
  results.push(configExists);
83135
83507
  if (configExists.status !== "error") {
83136
83508
  try {
@@ -83157,7 +83529,10 @@ var doctorCommand = new Command("doctor").description("Run diagnostic checks on
83157
83529
  }
83158
83530
  try {
83159
83531
  if (config.connection.system === "mongodb") {
83160
- results.push(...await collectMongoDoctorResults(config));
83532
+ results.push(...await collectMongoDoctorResults({
83533
+ ...config,
83534
+ blacklistedColumns
83535
+ }));
83161
83536
  } else {
83162
83537
  const adapter = AdapterFactory.createAdapter(config.connection);
83163
83538
  await adapter.connect();
@@ -83177,8 +83552,8 @@ var doctorCommand = new Command("doctor").description("Run diagnostic checks on
83177
83552
  try {
83178
83553
  const tables = await adapter.listTables();
83179
83554
  const tableColumns = new Map;
83180
- for (const t7 of tables) {
83181
- 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));
83182
83557
  }
83183
83558
  results.push(runDoctorChecks.checkBlacklistCompleteness(tableColumns, blacklistedColumns));
83184
83559
  results.push(runDoctorChecks.checkLargeTables(tables));
@@ -83187,7 +83562,7 @@ var doctorCommand = new Command("doctor").description("Run diagnostic checks on
83187
83562
  }
83188
83563
  try {
83189
83564
  const schemaConnName = await getSchemaIsolationConnectionName(configPath);
83190
- const indexPath = join10(resolveSchemaPath(configPath, schemaConnName), "index.json");
83565
+ const indexPath = join11(resolveSchemaPath(storagePath, schemaConnName), "index.json");
83191
83566
  const indexFile = Bun.file(indexPath);
83192
83567
  let indexParsed = null;
83193
83568
  if (await indexFile.exists()) {
@@ -83229,8 +83604,8 @@ var doctorCommand = new Command("doctor").description("Run diagnostic checks on
83229
83604
  });
83230
83605
 
83231
83606
  // src/commands/completion.ts
83232
- import { join as join11 } from "path";
83233
- import { homedir as homedir2 } from "os";
83607
+ import { join as join12 } from "path";
83608
+ import { homedir as homedir3 } from "os";
83234
83609
  function extractCommands(program2) {
83235
83610
  return program2.commands.map((cmd) => ({
83236
83611
  name: cmd.name(),
@@ -83309,10 +83684,7 @@ _dbcli
83309
83684
  `;
83310
83685
  }
83311
83686
  function generateFishCompletion(commands, globalOptions) {
83312
- const lines2 = [
83313
- "# dbcli fish completion \u2014 auto-generated, do not edit",
83314
- ""
83315
- ];
83687
+ const lines2 = ["# dbcli fish completion \u2014 auto-generated, do not edit", ""];
83316
83688
  for (const opt of globalOptions) {
83317
83689
  const longName = opt.replace(/^--/, "");
83318
83690
  lines2.push(`complete -c dbcli -n '__fish_use_subcommand' -l ${longName} -d '${opt}'`);
@@ -83331,14 +83703,14 @@ function generateFishCompletion(commands, globalOptions) {
83331
83703
  `;
83332
83704
  }
83333
83705
  function getInstallPath2(shell) {
83334
- const home = homedir2();
83706
+ const home = homedir3();
83335
83707
  switch (shell) {
83336
83708
  case "bash":
83337
- return join11(home, ".bashrc");
83709
+ return join12(home, ".bashrc");
83338
83710
  case "zsh":
83339
- return join11(home, ".zshrc");
83711
+ return join12(home, ".zshrc");
83340
83712
  case "fish":
83341
- return join11(home, ".config", "fish", "completions", "dbcli.fish");
83713
+ return join12(home, ".config", "fish", "completions", "dbcli.fish");
83342
83714
  default:
83343
83715
  throw new Error(`Unsupported shell: ${shell}. Supported: bash, zsh, fish`);
83344
83716
  }
@@ -83358,7 +83730,7 @@ var MARKER_END = "# <<< dbcli completion <<<";
83358
83730
  async function installCompletion(shell, script) {
83359
83731
  const targetPath = getInstallPath2(shell);
83360
83732
  if (shell === "fish") {
83361
- const dir = join11(homedir2(), ".config", "fish", "completions");
83733
+ const dir = join12(homedir3(), ".config", "fish", "completions");
83362
83734
  await Bun.$`mkdir -p ${dir}`.quiet();
83363
83735
  await Bun.file(targetPath).write(script);
83364
83736
  console.log(colors.success(`\u2713 Fish completion installed to ${targetPath}`));
@@ -83585,8 +83957,8 @@ ${t("upgrade.failed")}`));
83585
83957
 
83586
83958
  // src/commands/shell.ts
83587
83959
  import { createInterface as createInterface2 } from "readline";
83588
- import { join as join12 } from "path";
83589
- import { homedir as homedir3 } from "os";
83960
+ import { join as join13 } from "path";
83961
+ import { homedir as homedir4 } from "os";
83590
83962
 
83591
83963
  // src/core/repl/types.ts
83592
83964
  var SQL_KEYWORDS_FOR_DETECTION = [
@@ -84106,7 +84478,7 @@ class ReplEngine {
84106
84478
  const tableName = this.extractTableName(sql);
84107
84479
  if (tableName) {
84108
84480
  const blacklistedTables = this.config.blacklist.tables ?? [];
84109
- const isBlacklisted = blacklistedTables.some((t7) => t7.toLowerCase() === tableName.toLowerCase());
84481
+ const isBlacklisted = blacklistedTables.some((t6) => t6.toLowerCase() === tableName.toLowerCase());
84110
84482
  if (isBlacklisted) {
84111
84483
  return {
84112
84484
  action: "continue",
@@ -84181,13 +84553,7 @@ var TABLE_POSITION_KEYWORDS = new Set([
84181
84553
  "UPDATE",
84182
84554
  "TABLE"
84183
84555
  ]);
84184
- var COMMANDS_TAKING_TABLE_ARG = new Set([
84185
- "schema",
84186
- "insert",
84187
- "update",
84188
- "delete",
84189
- "check"
84190
- ]);
84556
+ var COMMANDS_TAKING_TABLE_ARG = new Set(["schema", "insert", "update", "delete", "check"]);
84191
84557
  function createCompleter(ctx) {
84192
84558
  const allTableNames = ctx.tableNames;
84193
84559
  const allColumns = Object.values(ctx.columnsByTable).flat();
@@ -84261,7 +84627,7 @@ function extractTableFromLine(line, tableNames) {
84261
84627
  if (fromIdx >= 0) {
84262
84628
  const afterFrom = line.slice(fromIdx + 5).trim().split(/\s+/)[0];
84263
84629
  const candidate = afterFrom.replace(/[;,]/g, "").toLowerCase();
84264
- return tableNames.find((t7) => t7.toLowerCase() === candidate);
84630
+ return tableNames.find((t6) => t6.toLowerCase() === candidate);
84265
84631
  }
84266
84632
  return;
84267
84633
  }
@@ -84311,7 +84677,7 @@ class MongoShellAdapter {
84311
84677
  }
84312
84678
 
84313
84679
  // src/commands/shell.ts
84314
- var HISTORY_PATH = join12(homedir3(), ".dbcli_history");
84680
+ var HISTORY_PATH = join13(homedir4(), ".dbcli_history");
84315
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) => {
84316
84682
  const configPath = resolveConfigPath(command);
84317
84683
  await runShell(options, configPath);
@@ -84325,7 +84691,8 @@ async function runShell(options, configPath) {
84325
84691
  process.exit(1);
84326
84692
  }
84327
84693
  const isMongoDB = config.connection.system === "mongodb";
84328
- 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);
84329
84696
  try {
84330
84697
  await adapter.connect();
84331
84698
  } catch (error) {
@@ -84333,7 +84700,7 @@ async function runShell(options, configPath) {
84333
84700
  process.exit(1);
84334
84701
  }
84335
84702
  let tableNames = [];
84336
- let columnsByTable = {};
84703
+ const columnsByTable = {};
84337
84704
  if (isMongoDB) {
84338
84705
  const collections = await adapter.listTables();
84339
84706
  tableNames = collections.map((collection) => collection.name);
@@ -84503,25 +84870,25 @@ class PostgreSQLDDLGenerator {
84503
84870
  alterColumn(options) {
84504
84871
  const statements = [];
84505
84872
  const warnings = [];
84506
- const t7 = q(options.table);
84873
+ const t6 = q(options.table);
84507
84874
  const c = q(options.column);
84508
84875
  if (options.type) {
84509
- 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()};`);
84510
84877
  }
84511
84878
  if (options.rename) {
84512
- 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)};`);
84513
84880
  }
84514
84881
  if (options.setDefault !== undefined) {
84515
- 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};`);
84516
84883
  }
84517
84884
  if (options.dropDefault) {
84518
- statements.push(`ALTER TABLE ${t7} ALTER COLUMN ${c} DROP DEFAULT;`);
84885
+ statements.push(`ALTER TABLE ${t6} ALTER COLUMN ${c} DROP DEFAULT;`);
84519
84886
  }
84520
84887
  if (options.setNullable) {
84521
- statements.push(`ALTER TABLE ${t7} ALTER COLUMN ${c} DROP NOT NULL;`);
84888
+ statements.push(`ALTER TABLE ${t6} ALTER COLUMN ${c} DROP NOT NULL;`);
84522
84889
  }
84523
84890
  if (options.dropNullable) {
84524
- statements.push(`ALTER TABLE ${t7} ALTER COLUMN ${c} SET NOT NULL;`);
84891
+ statements.push(`ALTER TABLE ${t6} ALTER COLUMN ${c} SET NOT NULL;`);
84525
84892
  }
84526
84893
  if (statements.length === 0) {
84527
84894
  warnings.push("No alter operations specified");
@@ -84543,14 +84910,14 @@ class PostgreSQLDDLGenerator {
84543
84910
  return { sql: `DROP INDEX ${q(indexName)};`, warnings: [] };
84544
84911
  }
84545
84912
  addConstraint(constraint) {
84546
- const t7 = q(constraint.table);
84913
+ const t6 = q(constraint.table);
84547
84914
  const warnings = [];
84548
84915
  switch (constraint.type) {
84549
84916
  case "foreign_key": {
84550
84917
  const name = constraint.name || `fk_${constraint.table}_${constraint.column}`;
84551
84918
  const onDelete = constraint.onDelete ? ` ON DELETE ${constraint.onDelete.toUpperCase().replace("_", " ")}` : "";
84552
84919
  return {
84553
- 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};`,
84554
84921
  warnings
84555
84922
  };
84556
84923
  }
@@ -84558,14 +84925,14 @@ class PostgreSQLDDLGenerator {
84558
84925
  const name = constraint.name || `uq_${constraint.table}_${constraint.columns.join("_")}`;
84559
84926
  const cols = constraint.columns.map(q).join(", ");
84560
84927
  return {
84561
- sql: `ALTER TABLE ${t7} ADD CONSTRAINT ${q(name)} UNIQUE (${cols});`,
84928
+ sql: `ALTER TABLE ${t6} ADD CONSTRAINT ${q(name)} UNIQUE (${cols});`,
84562
84929
  warnings
84563
84930
  };
84564
84931
  }
84565
84932
  case "check": {
84566
84933
  const name = constraint.name || `ck_${constraint.table}`;
84567
84934
  return {
84568
- sql: `ALTER TABLE ${t7} ADD CONSTRAINT ${q(name)} CHECK (${constraint.expression});`,
84935
+ sql: `ALTER TABLE ${t6} ADD CONSTRAINT ${q(name)} CHECK (${constraint.expression});`,
84569
84936
  warnings
84570
84937
  };
84571
84938
  }
@@ -84668,19 +85035,19 @@ class MySQLDDLGenerator {
84668
85035
  alterColumn(options) {
84669
85036
  const statements = [];
84670
85037
  const warnings = [];
84671
- const t7 = q2(options.table);
85038
+ const t6 = q2(options.table);
84672
85039
  const c = q2(options.column);
84673
85040
  if (options.type) {
84674
85041
  const nullable = options.dropNullable ? " NOT NULL" : "";
84675
85042
  const def = options.setDefault !== undefined ? ` DEFAULT ${options.setDefault}` : "";
84676
- 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};`);
84677
85044
  warnings.push("MySQL MODIFY COLUMN resets column attributes not explicitly specified");
84678
85045
  } else {
84679
85046
  if (options.setDefault !== undefined) {
84680
- 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};`);
84681
85048
  }
84682
85049
  if (options.dropDefault) {
84683
- statements.push(`ALTER TABLE ${t7} ALTER COLUMN ${c} DROP DEFAULT;`);
85050
+ statements.push(`ALTER TABLE ${t6} ALTER COLUMN ${c} DROP DEFAULT;`);
84684
85051
  }
84685
85052
  if (options.setNullable) {
84686
85053
  warnings.push("MySQL requires MODIFY COLUMN with full type to change nullability \u2014 use --type to specify");
@@ -84690,7 +85057,7 @@ class MySQLDDLGenerator {
84690
85057
  }
84691
85058
  }
84692
85059
  if (options.rename) {
84693
- 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)};`);
84694
85061
  }
84695
85062
  if (statements.length === 0 && warnings.length === 0) {
84696
85063
  warnings.push("No alter operations specified");
@@ -84716,14 +85083,14 @@ class MySQLDDLGenerator {
84716
85083
  };
84717
85084
  }
84718
85085
  addConstraint(constraint) {
84719
- const t7 = q2(constraint.table);
85086
+ const t6 = q2(constraint.table);
84720
85087
  const warnings = [];
84721
85088
  switch (constraint.type) {
84722
85089
  case "foreign_key": {
84723
85090
  const name = constraint.name || `fk_${constraint.table}_${constraint.column}`;
84724
85091
  const onDelete = constraint.onDelete ? ` ON DELETE ${constraint.onDelete.toUpperCase().replace("_", " ")}` : "";
84725
85092
  return {
84726
- 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};`,
84727
85094
  warnings
84728
85095
  };
84729
85096
  }
@@ -84731,14 +85098,14 @@ class MySQLDDLGenerator {
84731
85098
  const name = constraint.name || `uq_${constraint.table}_${constraint.columns.join("_")}`;
84732
85099
  const cols = constraint.columns.map(q2).join(", ");
84733
85100
  return {
84734
- sql: `ALTER TABLE ${t7} ADD CONSTRAINT ${q2(name)} UNIQUE (${cols});`,
85101
+ sql: `ALTER TABLE ${t6} ADD CONSTRAINT ${q2(name)} UNIQUE (${cols});`,
84735
85102
  warnings
84736
85103
  };
84737
85104
  }
84738
85105
  case "check": {
84739
85106
  const name = constraint.name || `ck_${constraint.table}`;
84740
85107
  return {
84741
- sql: `ALTER TABLE ${t7} ADD CONSTRAINT ${q2(name)} CHECK (${constraint.expression});`,
85108
+ sql: `ALTER TABLE ${t6} ADD CONSTRAINT ${q2(name)} CHECK (${constraint.expression});`,
84742
85109
  warnings: ["CHECK constraints enforced in MySQL 8.0.16+ and MariaDB 10.2.1+ only"]
84743
85110
  };
84744
85111
  }
@@ -84753,13 +85120,17 @@ class MySQLDDLGenerator {
84753
85120
  addEnum(_definition) {
84754
85121
  return {
84755
85122
  sql: "",
84756
- 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
+ ]
84757
85126
  };
84758
85127
  }
84759
85128
  alterEnum(_name, _addValue) {
84760
85129
  return {
84761
85130
  sql: "",
84762
- 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
+ ]
84763
85134
  };
84764
85135
  }
84765
85136
  dropEnum(_name) {
@@ -85247,7 +85618,7 @@ addExecOpts(migrateCommand.command("drop-enum <name>").description(t("migrate.dr
85247
85618
  });
85248
85619
 
85249
85620
  // src/commands/use.ts
85250
- import { join as join13 } from "path";
85621
+ import { join as join14 } from "path";
85251
85622
  async function switchDefault(configPath, name, config) {
85252
85623
  if (!config.connections[name]) {
85253
85624
  const available = Object.keys(config.connections).join(", ");
@@ -85269,15 +85640,41 @@ function listConnectionsForDisplay(config) {
85269
85640
  });
85270
85641
  }
85271
85642
  async function ensureV2Config(configPath) {
85272
- const configFile = Bun.file(join13(configPath, "config.json"));
85273
- 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()) {
85274
85647
  throw new ConfigError(t("init.config_not_found"));
85275
85648
  }
85276
- const raw = JSON.parse(await configFile.text());
85277
- 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;
85278
85676
  throw new ConfigError(t("use.requires_v2"));
85279
85677
  }
85280
- return readV2Config(configPath);
85281
85678
  }
85282
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) => {
85283
85680
  try {
@@ -85306,7 +85703,7 @@ var useCommand = new Command("use").description("Switch or display the default d
85306
85703
  });
85307
85704
 
85308
85705
  // src/cli.ts
85309
- import { join as join14 } from "path";
85706
+ import { join as join15 } from "path";
85310
85707
  var _bgVersionCheckResult;
85311
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)");
85312
85709
  program2.hook("preAction", (thisCommand, actionCommand) => {
@@ -85332,7 +85729,7 @@ program2.hook("preAction", (thisCommand, actionCommand) => {
85332
85729
  try {
85333
85730
  let cache = null;
85334
85731
  try {
85335
- const cacheFile = Bun.file(join14(configPath, "version-check.json"));
85732
+ const cacheFile = Bun.file(join15(configPath, "version-check.json"));
85336
85733
  if (await cacheFile.exists()) {
85337
85734
  cache = await cacheFile.json();
85338
85735
  }