@carllee1983/dbcli 1.57.0 → 2.0.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/core.mjs CHANGED
@@ -118,24 +118,24 @@ var require_picocolors = __commonJS((exports, module) => {
118
118
 
119
119
  // node_modules/lru-cache/dist/esm/node/index.min.js
120
120
  import { tracingChannel as j, channel as G } from "diagnostics_channel";
121
- var w, W, C, D = () => w.hasSubscribers || W.hasSubscribers, I, L, P = (u, e, t, i) => {
122
- typeof L.emitWarning == "function" ? L.emitWarning(u, e, t, i) : console.error(`[${t}] ${e}: ${u}`);
121
+ var w, W, C, D = () => w.hasSubscribers || W.hasSubscribers, I, L, P = (u, e, t2, i) => {
122
+ typeof L.emitWarning == "function" ? L.emitWarning(u, e, t2, i) : console.error(`[${t2}] ${e}: ${u}`);
123
123
  }, H = (u) => !I.has(u), T = (u) => !!u && u === Math.floor(u) && u > 0 && isFinite(u), U = (u) => T(u) ? u <= Math.pow(2, 8) ? Uint8Array : u <= Math.pow(2, 16) ? Uint16Array : u <= Math.pow(2, 32) ? Uint32Array : u <= Number.MAX_SAFE_INTEGER ? O : null : null, O, R = class u {
124
124
  heap;
125
125
  length;
126
126
  static #o = false;
127
127
  static create(e) {
128
- let t = U(e);
129
- if (!t)
128
+ let t2 = U(e);
129
+ if (!t2)
130
130
  return [];
131
131
  u.#o = true;
132
- let i = new u(e, t);
132
+ let i = new u(e, t2);
133
133
  return u.#o = false, i;
134
134
  }
135
- constructor(e, t) {
135
+ constructor(e, t2) {
136
136
  if (!u.#o)
137
137
  throw new TypeError("instantiate Stack using Stack.create(n)");
138
- this.heap = new t(e), this.length = 0;
138
+ this.heap = new t2(e), this.length = 0;
139
139
  }
140
140
  push(e) {
141
141
  this.heap[this.length++] = e;
@@ -206,7 +206,7 @@ var init_index_min = __esm(() => {
206
206
  return e.#a;
207
207
  }, get tail() {
208
208
  return e.#h;
209
- }, free: e.#y, isBackgroundFetch: (t) => e.#e(t), backgroundFetch: (t, i, s, n) => e.#P(t, i, s, n), moveToTail: (t) => e.#L(t), indexes: (t) => e.#A(t), rindexes: (t) => e.#z(t), isStale: (t) => e.#p(t) };
209
+ }, free: e.#y, isBackgroundFetch: (t2) => e.#e(t2), backgroundFetch: (t2, i, s, n) => e.#P(t2, i, s, n), moveToTail: (t2) => e.#L(t2), indexes: (t2) => e.#A(t2), rindexes: (t2) => e.#z(t2), isStale: (t2) => e.#p(t2) };
210
210
  }
211
211
  get max() {
212
212
  return this.#o;
@@ -236,15 +236,15 @@ var init_index_min = __esm(() => {
236
236
  return this.#S;
237
237
  }
238
238
  constructor(e) {
239
- let { max: t = 0, ttl: i, ttlResolution: s = 1, ttlAutopurge: n, updateAgeOnGet: r, updateAgeOnHas: h, allowStale: a, dispose: o, onInsert: p, disposeAfter: m, noDisposeOnSet: _, noUpdateTTL: c, maxSize: d = 0, maxEntrySize: f = 0, sizeCalculation: y, fetchMethod: l, memoMethod: S, noDeleteOnFetchRejection: F, noDeleteOnStaleGet: b, allowStaleOnFetchRejection: g, allowStaleOnFetchAbort: A, ignoreFetchAbort: z, perf: x } = e;
239
+ let { max: t2 = 0, ttl: i, ttlResolution: s = 1, ttlAutopurge: n, updateAgeOnGet: r, updateAgeOnHas: h, allowStale: a, dispose: o, onInsert: p, disposeAfter: m, noDisposeOnSet: _, noUpdateTTL: c, maxSize: d = 0, maxEntrySize: f = 0, sizeCalculation: y, fetchMethod: l, memoMethod: S, noDeleteOnFetchRejection: F, noDeleteOnStaleGet: b, allowStaleOnFetchRejection: g, allowStaleOnFetchAbort: A, ignoreFetchAbort: z, perf: x } = e;
240
240
  if (x !== undefined && typeof x?.now != "function")
241
241
  throw new TypeError("perf option must have a now() method if specified");
242
- if (this.#m = x ?? C, t !== 0 && !T(t))
242
+ if (this.#m = x ?? C, t2 !== 0 && !T(t2))
243
243
  throw new TypeError("max option must be a nonnegative integer");
244
- let E = t ? U(t) : Array;
244
+ let E = t2 ? U(t2) : Array;
245
245
  if (!E)
246
- throw new Error("invalid max value: " + t);
247
- if (this.#o = t, this.#c = d, this.maxEntrySize = f || this.#c, this.sizeCalculation = y, this.sizeCalculation) {
246
+ throw new Error("invalid max value: " + t2);
247
+ if (this.#o = t2, this.#c = d, this.maxEntrySize = f || this.#c, this.sizeCalculation = y, this.sizeCalculation) {
248
248
  if (!this.#c && !this.maxEntrySize)
249
249
  throw new TypeError("cannot set sizeCalculation without setting maxSize or maxEntrySize");
250
250
  if (typeof this.sizeCalculation != "function")
@@ -254,7 +254,7 @@ var init_index_min = __esm(() => {
254
254
  throw new TypeError("memoMethod must be a function if defined");
255
255
  if (this.#I = S, l !== undefined && typeof l != "function")
256
256
  throw new TypeError("fetchMethod must be a function if specified");
257
- if (this.#M = l, this.#U = !!l, this.#s = new Map, this.#i = Array.from({ length: t }).fill(undefined), this.#t = Array.from({ length: t }).fill(undefined), this.#l = new E(t), this.#u = new E(t), this.#a = 0, this.#h = 0, this.#y = R.create(t), this.#n = 0, this.#b = 0, typeof o == "function" && (this.#w = o), typeof p == "function" && (this.#O = p), typeof m == "function" ? (this.#S = m, this.#r = []) : (this.#S = undefined, this.#r = undefined), this.#T = !!this.#w, this.#x = !!this.#O, this.#f = !!this.#S, this.noDisposeOnSet = !!_, this.noUpdateTTL = !!c, this.noDeleteOnFetchRejection = !!F, this.allowStaleOnFetchRejection = !!g, this.allowStaleOnFetchAbort = !!A, this.ignoreFetchAbort = !!z, this.maxEntrySize !== 0) {
257
+ if (this.#M = l, this.#U = !!l, this.#s = new Map, this.#i = Array.from({ length: t2 }).fill(undefined), this.#t = Array.from({ length: t2 }).fill(undefined), this.#l = new E(t2), this.#u = new E(t2), this.#a = 0, this.#h = 0, this.#y = R.create(t2), this.#n = 0, this.#b = 0, typeof o == "function" && (this.#w = o), typeof p == "function" && (this.#O = p), typeof m == "function" ? (this.#S = m, this.#r = []) : (this.#S = undefined, this.#r = undefined), this.#T = !!this.#w, this.#x = !!this.#O, this.#f = !!this.#S, this.noDisposeOnSet = !!_, this.noUpdateTTL = !!c, this.noDeleteOnFetchRejection = !!F, this.allowStaleOnFetchRejection = !!g, this.allowStaleOnFetchAbort = !!A, this.ignoreFetchAbort = !!z, this.maxEntrySize !== 0) {
258
258
  if (this.#c !== 0 && !T(this.#c))
259
259
  throw new TypeError("maxSize must be a positive integer if specified");
260
260
  if (!T(this.maxEntrySize))
@@ -277,13 +277,13 @@ var init_index_min = __esm(() => {
277
277
  return this.#s.has(e) ? 1 / 0 : 0;
278
278
  }
279
279
  #H() {
280
- let e = new O(this.#o), t = new O(this.#o);
281
- this.#d = e, this.#F = t;
280
+ let e = new O(this.#o), t2 = new O(this.#o);
281
+ this.#d = e, this.#F = t2;
282
282
  let i = this.ttlAutopurge ? Array.from({ length: this.#o }) : undefined;
283
283
  this.#g = i, this.#N = (h, a, o = this.#m.now()) => {
284
- t[h] = a !== 0 ? o : 0, e[h] = a, s(h, a);
284
+ t2[h] = a !== 0 ? o : 0, e[h] = a, s(h, a);
285
285
  }, this.#D = (h) => {
286
- t[h] = e[h] !== 0 ? this.#m.now() : 0, s(h, e[h]);
286
+ t2[h] = e[h] !== 0 ? this.#m.now() : 0, s(h, e[h]);
287
287
  };
288
288
  let s = this.ttlAutopurge ? (h, a) => {
289
289
  if (i?.[h] && (clearTimeout(i[h]), i[h] = undefined), a && a !== 0 && i) {
@@ -295,7 +295,7 @@ var init_index_min = __esm(() => {
295
295
  } : () => {};
296
296
  this.#v = (h, a) => {
297
297
  if (e[a]) {
298
- let o = e[a], p = t[a];
298
+ let o = e[a], p = t2[a];
299
299
  if (!o || !p)
300
300
  return;
301
301
  h.ttl = o, h.start = p, h.now = n || r();
@@ -316,13 +316,13 @@ var init_index_min = __esm(() => {
316
316
  let a = this.#s.get(h);
317
317
  if (a === undefined)
318
318
  return 0;
319
- let o = e[a], p = t[a];
319
+ let o = e[a], p = t2[a];
320
320
  if (!o || !p)
321
321
  return 1 / 0;
322
322
  let m = (n || r()) - p;
323
323
  return o - m;
324
324
  }, this.#p = (h) => {
325
- let a = t[h], o = e[h];
325
+ let a = t2[h], o = e[h];
326
326
  return !!o && !!a && (n || r()) - a > o;
327
327
  };
328
328
  }
@@ -332,45 +332,45 @@ var init_index_min = __esm(() => {
332
332
  #p = () => false;
333
333
  #X() {
334
334
  let e = new O(this.#o);
335
- this.#b = 0, this.#_ = e, this.#R = (t) => {
336
- this.#b -= e[t], e[t] = 0;
337
- }, this.#V = (t, i, s, n) => {
335
+ this.#b = 0, this.#_ = e, this.#R = (t2) => {
336
+ this.#b -= e[t2], e[t2] = 0;
337
+ }, this.#V = (t2, i, s, n) => {
338
338
  if (this.#e(i))
339
339
  return 0;
340
340
  if (!T(s))
341
341
  if (n) {
342
342
  if (typeof n != "function")
343
343
  throw new TypeError("sizeCalculation must be a function");
344
- if (s = n(i, t), !T(s))
344
+ if (s = n(i, t2), !T(s))
345
345
  throw new TypeError("sizeCalculation return invalid (expect positive integer)");
346
346
  } else
347
347
  throw new TypeError("invalid size value (must be positive integer). When maxSize or maxEntrySize is used, sizeCalculation or size must be set.");
348
348
  return s;
349
- }, this.#j = (t, i, s) => {
350
- if (e[t] = i, this.#c) {
351
- let n = this.#c - e[t];
349
+ }, this.#j = (t2, i, s) => {
350
+ if (e[t2] = i, this.#c) {
351
+ let n = this.#c - e[t2];
352
352
  for (;this.#b > n; )
353
353
  this.#G(true);
354
354
  }
355
- this.#b += e[t], s && (s.entrySize = i, s.totalCalculatedSize = this.#b);
355
+ this.#b += e[t2], s && (s.entrySize = i, s.totalCalculatedSize = this.#b);
356
356
  };
357
357
  }
358
358
  #R = (e) => {};
359
- #j = (e, t, i) => {};
360
- #V = (e, t, i, s) => {
359
+ #j = (e, t2, i) => {};
360
+ #V = (e, t2, i, s) => {
361
361
  if (i || s)
362
362
  throw new TypeError("cannot set size without setting maxSize or maxEntrySize on cache");
363
363
  return 0;
364
364
  };
365
365
  *#A({ allowStale: e = this.allowStale } = {}) {
366
366
  if (this.#n)
367
- for (let t = this.#h;this.#B(t) && ((e || !this.#p(t)) && (yield t), t !== this.#a); )
368
- t = this.#u[t];
367
+ for (let t2 = this.#h;this.#B(t2) && ((e || !this.#p(t2)) && (yield t2), t2 !== this.#a); )
368
+ t2 = this.#u[t2];
369
369
  }
370
370
  *#z({ allowStale: e = this.allowStale } = {}) {
371
371
  if (this.#n)
372
- for (let t = this.#a;this.#B(t) && ((e || !this.#p(t)) && (yield t), t !== this.#h); )
373
- t = this.#l[t];
372
+ for (let t2 = this.#a;this.#B(t2) && ((e || !this.#p(t2)) && (yield t2), t2 !== this.#h); )
373
+ t2 = this.#l[t2];
374
374
  }
375
375
  #B(e) {
376
376
  return e !== undefined && this.#s.get(this.#i[e]) === e;
@@ -385,14 +385,14 @@ var init_index_min = __esm(() => {
385
385
  }
386
386
  *keys() {
387
387
  for (let e of this.#A()) {
388
- let t = this.#i[e];
389
- t !== undefined && !this.#e(this.#t[e]) && (yield t);
388
+ let t2 = this.#i[e];
389
+ t2 !== undefined && !this.#e(this.#t[e]) && (yield t2);
390
390
  }
391
391
  }
392
392
  *rkeys() {
393
393
  for (let e of this.#z()) {
394
- let t = this.#i[e];
395
- t !== undefined && !this.#e(this.#t[e]) && (yield t);
394
+ let t2 = this.#i[e];
395
+ t2 !== undefined && !this.#e(this.#t[e]) && (yield t2);
396
396
  }
397
397
  }
398
398
  *values() {
@@ -407,109 +407,109 @@ var init_index_min = __esm(() => {
407
407
  return this.entries();
408
408
  }
409
409
  [Symbol.toStringTag] = "LRUCache";
410
- find(e, t = {}) {
410
+ find(e, t2 = {}) {
411
411
  for (let i of this.#A()) {
412
412
  let s = this.#t[i], n = this.#e(s) ? s.__staleWhileFetching : s;
413
413
  if (n !== undefined && e(n, this.#i[i], this))
414
- return this.#C(this.#i[i], t);
414
+ return this.#C(this.#i[i], t2);
415
415
  }
416
416
  }
417
- forEach(e, t = this) {
417
+ forEach(e, t2 = this) {
418
418
  for (let i of this.#A()) {
419
419
  let s = this.#t[i], n = this.#e(s) ? s.__staleWhileFetching : s;
420
- n !== undefined && e.call(t, n, this.#i[i], this);
420
+ n !== undefined && e.call(t2, n, this.#i[i], this);
421
421
  }
422
422
  }
423
- rforEach(e, t = this) {
423
+ rforEach(e, t2 = this) {
424
424
  for (let i of this.#z()) {
425
425
  let s = this.#t[i], n = this.#e(s) ? s.__staleWhileFetching : s;
426
- n !== undefined && e.call(t, n, this.#i[i], this);
426
+ n !== undefined && e.call(t2, n, this.#i[i], this);
427
427
  }
428
428
  }
429
429
  purgeStale() {
430
430
  let e = false;
431
- for (let t of this.#z({ allowStale: true }))
432
- this.#p(t) && (this.#E(this.#i[t], "expire"), e = true);
431
+ for (let t2 of this.#z({ allowStale: true }))
432
+ this.#p(t2) && (this.#E(this.#i[t2], "expire"), e = true);
433
433
  return e;
434
434
  }
435
435
  info(e) {
436
- let t = this.#s.get(e);
437
- if (t === undefined)
436
+ let t2 = this.#s.get(e);
437
+ if (t2 === undefined)
438
438
  return;
439
- let i = this.#t[t], s = this.#e(i) ? i.__staleWhileFetching : i;
439
+ let i = this.#t[t2], s = this.#e(i) ? i.__staleWhileFetching : i;
440
440
  if (s === undefined)
441
441
  return;
442
442
  let n = { value: s };
443
443
  if (this.#d && this.#F) {
444
- let r = this.#d[t], h = this.#F[t];
444
+ let r = this.#d[t2], h = this.#F[t2];
445
445
  if (r && h) {
446
446
  let a = r - (this.#m.now() - h);
447
447
  n.ttl = a, n.start = Date.now();
448
448
  }
449
449
  }
450
- return this.#_ && (n.size = this.#_[t]), n;
450
+ return this.#_ && (n.size = this.#_[t2]), n;
451
451
  }
452
452
  dump() {
453
453
  let e = [];
454
- for (let t of this.#A({ allowStale: true })) {
455
- let i = this.#i[t], s = this.#t[t], n = this.#e(s) ? s.__staleWhileFetching : s;
454
+ for (let t2 of this.#A({ allowStale: true })) {
455
+ let i = this.#i[t2], s = this.#t[t2], n = this.#e(s) ? s.__staleWhileFetching : s;
456
456
  if (n === undefined || i === undefined)
457
457
  continue;
458
458
  let r = { value: n };
459
459
  if (this.#d && this.#F) {
460
- r.ttl = this.#d[t];
461
- let h = this.#m.now() - this.#F[t];
460
+ r.ttl = this.#d[t2];
461
+ let h = this.#m.now() - this.#F[t2];
462
462
  r.start = Math.floor(Date.now() - h);
463
463
  }
464
- this.#_ && (r.size = this.#_[t]), e.unshift([i, r]);
464
+ this.#_ && (r.size = this.#_[t2]), e.unshift([i, r]);
465
465
  }
466
466
  return e;
467
467
  }
468
468
  load(e) {
469
469
  this.clear();
470
- for (let [t, i] of e) {
470
+ for (let [t2, i] of e) {
471
471
  if (i.start) {
472
472
  let s = Date.now() - i.start;
473
473
  i.start = this.#m.now() - s;
474
474
  }
475
- this.#W(t, i.value, i);
475
+ this.#W(t2, i.value, i);
476
476
  }
477
477
  }
478
- set(e, t, i = {}) {
478
+ set(e, t2, i = {}) {
479
479
  let { status: s = w.hasSubscribers ? {} : undefined } = i;
480
- i.status = s, s && (s.op = "set", s.key = e, t !== undefined && (s.value = t), s.cache = this);
481
- let n = this.#W(e, t, i);
480
+ i.status = s, s && (s.op = "set", s.key = e, t2 !== undefined && (s.value = t2), s.cache = this);
481
+ let n = this.#W(e, t2, i);
482
482
  return s && w.hasSubscribers && w.publish(s), n;
483
483
  }
484
- #W(e, t, i, s) {
484
+ #W(e, t2, i, s) {
485
485
  let { ttl: n = this.ttl, start: r, noDisposeOnSet: h = this.noDisposeOnSet, sizeCalculation: a = this.sizeCalculation, status: o } = i;
486
- if (t === undefined)
486
+ if (t2 === undefined)
487
487
  return o && (o.set = "deleted"), this.delete(e), this;
488
- let { noUpdateTTL: p = this.noUpdateTTL } = i, m = this.#e(t);
489
- o && !m && (o.value = t);
490
- let _ = this.#V(e, t, i.size || 0, a, o);
488
+ let { noUpdateTTL: p = this.noUpdateTTL } = i, m = this.#e(t2);
489
+ o && !m && (o.value = t2);
490
+ let _ = this.#V(e, t2, i.size || 0, a, o);
491
491
  if (this.maxEntrySize && _ > this.maxEntrySize)
492
492
  return this.#E(e, "set"), o && (o.set = "miss", o.maxEntrySizeExceeded = true), this;
493
493
  let c = this.#n === 0 ? undefined : this.#s.get(e);
494
494
  if (c === undefined)
495
- c = this.#n === 0 ? this.#h : this.#y.length !== 0 ? this.#y.pop() : this.#n === this.#o ? this.#G(false) : this.#n, this.#i[c] = e, this.#t[c] = t, this.#s.set(e, c), this.#l[this.#h] = c, this.#u[c] = this.#h, this.#h = c, this.#n++, this.#j(c, _, o), o && (o.set = "add"), p = false, this.#x && !m && this.#O?.(t, e, "add");
495
+ c = this.#n === 0 ? this.#h : this.#y.length !== 0 ? this.#y.pop() : this.#n === this.#o ? this.#G(false) : this.#n, this.#i[c] = e, this.#t[c] = t2, this.#s.set(e, c), this.#l[this.#h] = c, this.#u[c] = this.#h, this.#h = c, this.#n++, this.#j(c, _, o), o && (o.set = "add"), p = false, this.#x && !m && this.#O?.(t2, e, "add");
496
496
  else {
497
497
  this.#L(c);
498
498
  let d = this.#t[c];
499
- if (t !== d) {
499
+ if (t2 !== d) {
500
500
  if (!h)
501
501
  if (this.#e(d)) {
502
502
  d !== s && d.__abortController.abort(new Error("replaced"));
503
503
  let { __staleWhileFetching: f } = d;
504
- f !== undefined && f !== t && (this.#T && this.#w?.(f, e, "set"), this.#f && this.#r?.push([f, e, "set"]));
504
+ f !== undefined && f !== t2 && (this.#T && this.#w?.(f, e, "set"), this.#f && this.#r?.push([f, e, "set"]));
505
505
  } else
506
506
  this.#T && this.#w?.(d, e, "set"), this.#f && this.#r?.push([d, e, "set"]);
507
- if (this.#R(c), this.#j(c, _, o), this.#t[c] = t, !m) {
508
- let f = d && this.#e(d) ? d.__staleWhileFetching : d, y = f === undefined ? "add" : t !== f ? "replace" : "update";
509
- o && (o.set = y, f !== undefined && (o.oldValue = f)), this.#x && this.onInsert?.(t, e, y);
507
+ if (this.#R(c), this.#j(c, _, o), this.#t[c] = t2, !m) {
508
+ let f = d && this.#e(d) ? d.__staleWhileFetching : d, y = f === undefined ? "add" : t2 !== f ? "replace" : "update";
509
+ o && (o.set = y, f !== undefined && (o.oldValue = f)), this.#x && this.onInsert?.(t2, e, y);
510
510
  }
511
511
  } else
512
- m || (o && (o.set = "update"), this.#x && this.onInsert?.(t, e, "update"));
512
+ m || (o && (o.set = "update"), this.#x && this.onInsert?.(t2, e, "update"));
513
513
  }
514
514
  if (n !== 0 && !this.#d && this.#H(), this.#d && (p || this.#N(c, n, r), o && this.#v(o, c)), !h && this.#f && this.#r) {
515
515
  let d = this.#r, f;
@@ -530,26 +530,26 @@ var init_index_min = __esm(() => {
530
530
  }
531
531
  } finally {
532
532
  if (this.#f && this.#r) {
533
- let e = this.#r, t;
534
- for (;t = e?.shift(); )
535
- this.#S?.(...t);
533
+ let e = this.#r, t2;
534
+ for (;t2 = e?.shift(); )
535
+ this.#S?.(...t2);
536
536
  }
537
537
  }
538
538
  }
539
539
  #G(e) {
540
- let t = this.#a, i = this.#i[t], s = this.#t[t], n = this.#e(s);
540
+ let t2 = this.#a, i = this.#i[t2], s = this.#t[t2], n = this.#e(s);
541
541
  n && s.__abortController.abort(new Error("evicted"));
542
542
  let r = n ? s.__staleWhileFetching : s;
543
- return (this.#T || this.#f) && r !== undefined && (this.#T && this.#w?.(r, i, "evict"), this.#f && this.#r?.push([r, i, "evict"])), this.#R(t), this.#g?.[t] && (clearTimeout(this.#g[t]), this.#g[t] = undefined), e && (this.#i[t] = undefined, this.#t[t] = undefined, this.#y.push(t)), this.#n === 1 ? (this.#a = this.#h = 0, this.#y.length = 0) : this.#a = this.#l[t], this.#s.delete(i), this.#n--, t;
543
+ return (this.#T || this.#f) && r !== undefined && (this.#T && this.#w?.(r, i, "evict"), this.#f && this.#r?.push([r, i, "evict"])), this.#R(t2), this.#g?.[t2] && (clearTimeout(this.#g[t2]), this.#g[t2] = undefined), e && (this.#i[t2] = undefined, this.#t[t2] = undefined, this.#y.push(t2)), this.#n === 1 ? (this.#a = this.#h = 0, this.#y.length = 0) : this.#a = this.#l[t2], this.#s.delete(i), this.#n--, t2;
544
544
  }
545
- has(e, t = {}) {
546
- let { status: i = w.hasSubscribers ? {} : undefined } = t;
547
- t.status = i, i && (i.op = "has", i.key = e, i.cache = this);
548
- let s = this.#Y(e, t);
545
+ has(e, t2 = {}) {
546
+ let { status: i = w.hasSubscribers ? {} : undefined } = t2;
547
+ t2.status = i, i && (i.op = "has", i.key = e, i.cache = this);
548
+ let s = this.#Y(e, t2);
549
549
  return w.hasSubscribers && w.publish(i), s;
550
550
  }
551
- #Y(e, t = {}) {
552
- let { updateAgeOnHas: i = this.updateAgeOnHas, status: s } = t, n = this.#s.get(e);
551
+ #Y(e, t2 = {}) {
552
+ let { updateAgeOnHas: i = this.updateAgeOnHas, status: s } = t2, n = this.#s.get(e);
553
553
  if (n !== undefined) {
554
554
  let r = this.#t[n];
555
555
  if (this.#e(r) && r.__staleWhileFetching === undefined)
@@ -562,14 +562,14 @@ var init_index_min = __esm(() => {
562
562
  s && (s.has = "miss");
563
563
  return false;
564
564
  }
565
- peek(e, t = {}) {
566
- let { status: i = D() ? {} : undefined } = t;
567
- i && (i.op = "peek", i.key = e, i.cache = this), t.status = i;
568
- let s = this.#J(e, t);
565
+ peek(e, t2 = {}) {
566
+ let { status: i = D() ? {} : undefined } = t2;
567
+ i && (i.op = "peek", i.key = e, i.cache = this), t2.status = i;
568
+ let s = this.#J(e, t2);
569
569
  return w.hasSubscribers && w.publish(i), s;
570
570
  }
571
- #J(e, t) {
572
- let { status: i, allowStale: s = this.allowStale } = t, n = this.#s.get(e);
571
+ #J(e, t2) {
572
+ let { status: i, allowStale: s = this.allowStale } = t2, n = this.#s.get(e);
573
573
  if (n === undefined || !s && this.#p(n)) {
574
574
  i && (i.peek = n === undefined ? "miss" : "stale");
575
575
  return;
@@ -577,8 +577,8 @@ var init_index_min = __esm(() => {
577
577
  let r = this.#t[n], h = this.#e(r) ? r.__staleWhileFetching : r;
578
578
  return i && (h !== undefined ? (i.peek = "hit", i.value = h) : i.peek = "miss"), h;
579
579
  }
580
- #P(e, t, i, s) {
581
- let n = t === undefined ? undefined : this.#t[t];
580
+ #P(e, t2, i, s) {
581
+ let n = t2 === undefined ? undefined : this.#t[t2];
582
582
  if (this.#e(n))
583
583
  return n;
584
584
  let r = new AbortController, { signal: h } = i;
@@ -587,11 +587,11 @@ var init_index_min = __esm(() => {
587
587
  let { aborted: l } = r.signal, S = i.ignoreFetchAbort && f !== undefined, F = i.ignoreFetchAbort || !!(i.allowStaleOnFetchAbort && f !== undefined);
588
588
  if (i.status && (l && !y ? (i.status.fetchAborted = true, i.status.fetchError = r.signal.reason, S && (i.status.fetchAbortIgnored = true)) : i.status.fetchResolved = true), l && !S && !y)
589
589
  return m(r.signal.reason, F);
590
- let b = c, g = this.#t[t];
591
- return (g === c || g === undefined && S && y) && (f === undefined ? b.__staleWhileFetching !== undefined ? this.#t[t] = b.__staleWhileFetching : this.#E(e, "fetch") : (i.status && (i.status.fetchUpdated = true), this.#W(e, f, a.options, b))), f;
590
+ let b = c, g = this.#t[t2];
591
+ return (g === c || g === undefined && S && y) && (f === undefined ? b.__staleWhileFetching !== undefined ? this.#t[t2] = b.__staleWhileFetching : this.#E(e, "fetch") : (i.status && (i.status.fetchUpdated = true), this.#W(e, f, a.options, b))), f;
592
592
  }, p = (f) => (i.status && (i.status.fetchRejected = true, i.status.fetchError = f), m(f, false)), m = (f, y) => {
593
593
  let { aborted: l } = r.signal, S = l && i.allowStaleOnFetchAbort, F = S || i.allowStaleOnFetchRejection, b = F || i.noDeleteOnFetchRejection, g = c;
594
- if (this.#t[t] === c && (!b || !y && g.__staleWhileFetching === undefined ? this.#E(e, "fetch") : S || (this.#t[t] = g.__staleWhileFetching)), F)
594
+ if (this.#t[t2] === c && (!b || !y && g.__staleWhileFetching === undefined ? this.#E(e, "fetch") : S || (this.#t[t2] = g.__staleWhileFetching)), F)
595
595
  return i.status && g.__staleWhileFetching !== undefined && (i.status.returnedStale = true), g.__staleWhileFetching;
596
596
  if (g.__returned === g)
597
597
  throw f;
@@ -603,22 +603,22 @@ var init_index_min = __esm(() => {
603
603
  };
604
604
  i.status && (i.status.fetchDispatched = true);
605
605
  let c = new Promise(_).then(o, p), d = Object.assign(c, { __abortController: r, __staleWhileFetching: n, __returned: undefined });
606
- return t === undefined ? (this.#W(e, d, { ...a.options, status: undefined }), t = this.#s.get(e)) : this.#t[t] = d, d;
606
+ return t2 === undefined ? (this.#W(e, d, { ...a.options, status: undefined }), t2 = this.#s.get(e)) : this.#t[t2] = d, d;
607
607
  }
608
608
  #e(e) {
609
609
  if (!this.#U)
610
610
  return false;
611
- let t = e;
612
- return !!t && t instanceof Promise && t.hasOwnProperty("__staleWhileFetching") && t.__abortController instanceof AbortController;
611
+ let t2 = e;
612
+ return !!t2 && t2 instanceof Promise && t2.hasOwnProperty("__staleWhileFetching") && t2.__abortController instanceof AbortController;
613
613
  }
614
- fetch(e, t = {}) {
615
- let i = W.hasSubscribers, { status: s = D() ? {} : undefined } = t;
616
- t.status = s, s && t.context && (s.context = t.context);
617
- let n = this.#k(e, t);
614
+ fetch(e, t2 = {}) {
615
+ let i = W.hasSubscribers, { status: s = D() ? {} : undefined } = t2;
616
+ t2.status = s, s && t2.context && (s.context = t2.context);
617
+ let n = this.#k(e, t2);
618
618
  return s && i && (s.trace = true, W.tracePromise(() => n, s).catch(() => {})), n;
619
619
  }
620
- async#k(e, t = {}) {
621
- let { allowStale: i = this.allowStale, updateAgeOnGet: s = this.updateAgeOnGet, noDeleteOnStaleGet: n = this.noDeleteOnStaleGet, ttl: r = this.ttl, noDisposeOnSet: h = this.noDisposeOnSet, size: a = 0, sizeCalculation: o = this.sizeCalculation, noUpdateTTL: p = this.noUpdateTTL, noDeleteOnFetchRejection: m = this.noDeleteOnFetchRejection, allowStaleOnFetchRejection: _ = this.allowStaleOnFetchRejection, ignoreFetchAbort: c = this.ignoreFetchAbort, allowStaleOnFetchAbort: d = this.allowStaleOnFetchAbort, context: f, forceRefresh: y = false, status: l, signal: S } = t;
620
+ async#k(e, t2 = {}) {
621
+ let { allowStale: i = this.allowStale, updateAgeOnGet: s = this.updateAgeOnGet, noDeleteOnStaleGet: n = this.noDeleteOnStaleGet, ttl: r = this.ttl, noDisposeOnSet: h = this.noDisposeOnSet, size: a = 0, sizeCalculation: o = this.sizeCalculation, noUpdateTTL: p = this.noUpdateTTL, noDeleteOnFetchRejection: m = this.noDeleteOnFetchRejection, allowStaleOnFetchRejection: _ = this.allowStaleOnFetchRejection, ignoreFetchAbort: c = this.ignoreFetchAbort, allowStaleOnFetchAbort: d = this.allowStaleOnFetchAbort, context: f, forceRefresh: y = false, status: l, signal: S } = t2;
622
622
  if (l && (l.op = "fetch", l.key = e, y && (l.forceRefresh = true), l.cache = this), !this.#U)
623
623
  return l && (l.fetch = "get"), this.#C(e, { allowStale: i, updateAgeOnGet: s, noDeleteOnStaleGet: n, status: l });
624
624
  let F = { allowStale: i, updateAgeOnGet: s, noDeleteOnStaleGet: n, ttl: r, noDisposeOnSet: h, size: a, sizeCalculation: o, noUpdateTTL: p, noDeleteOnFetchRejection: m, allowStaleOnFetchRejection: _, allowStaleOnFetchAbort: d, ignoreFetchAbort: c, status: l, signal: S }, b = this.#s.get(e);
@@ -639,29 +639,29 @@ var init_index_min = __esm(() => {
639
639
  return l && (l.fetch = A ? "stale" : "refresh", E && A && (l.returnedStale = true)), E ? z.__staleWhileFetching : z.__returned = z;
640
640
  }
641
641
  }
642
- forceFetch(e, t = {}) {
643
- let i = W.hasSubscribers, { status: s = D() ? {} : undefined } = t;
644
- t.status = s, s && t.context && (s.context = t.context);
645
- let n = this.#K(e, t);
642
+ forceFetch(e, t2 = {}) {
643
+ let i = W.hasSubscribers, { status: s = D() ? {} : undefined } = t2;
644
+ t2.status = s, s && t2.context && (s.context = t2.context);
645
+ let n = this.#K(e, t2);
646
646
  return s && i && (s.trace = true, W.tracePromise(() => n, s).catch(() => {})), n;
647
647
  }
648
- async#K(e, t = {}) {
649
- let i = await this.#k(e, t);
648
+ async#K(e, t2 = {}) {
649
+ let i = await this.#k(e, t2);
650
650
  if (i === undefined)
651
651
  throw new Error("fetch() returned undefined");
652
652
  return i;
653
653
  }
654
- memo(e, t = {}) {
655
- let { status: i = w.hasSubscribers ? {} : undefined } = t;
656
- t.status = i, i && (i.op = "memo", i.key = e, t.context && (i.context = t.context), i.cache = this);
657
- let s = this.#Q(e, t);
654
+ memo(e, t2 = {}) {
655
+ let { status: i = w.hasSubscribers ? {} : undefined } = t2;
656
+ t2.status = i, i && (i.op = "memo", i.key = e, t2.context && (i.context = t2.context), i.cache = this);
657
+ let s = this.#Q(e, t2);
658
658
  return i && (i.value = s), w.hasSubscribers && w.publish(i), s;
659
659
  }
660
- #Q(e, t = {}) {
660
+ #Q(e, t2 = {}) {
661
661
  let i = this.#I;
662
662
  if (!i)
663
663
  throw new Error("no memoMethod provided to constructor");
664
- let { context: s, status: n, forceRefresh: r, ...h } = t;
664
+ let { context: s, status: n, forceRefresh: r, ...h } = t2;
665
665
  n && r && (n.forceRefresh = true);
666
666
  let a = this.#C(e, h), o = r || a === undefined;
667
667
  if (n && (n.memo = o ? "miss" : "hit", o || (n.value = a)), !o)
@@ -669,14 +669,14 @@ var init_index_min = __esm(() => {
669
669
  let p = i(e, a, { options: h, context: s });
670
670
  return n && (n.value = p), this.#W(e, p, h), p;
671
671
  }
672
- get(e, t = {}) {
673
- let { status: i = w.hasSubscribers ? {} : undefined } = t;
674
- t.status = i, i && (i.op = "get", i.key = e, i.cache = this);
675
- let s = this.#C(e, t);
672
+ get(e, t2 = {}) {
673
+ let { status: i = w.hasSubscribers ? {} : undefined } = t2;
674
+ t2.status = i, i && (i.op = "get", i.key = e, i.cache = this);
675
+ let s = this.#C(e, t2);
676
676
  return i && (s !== undefined && (i.value = s), w.hasSubscribers && w.publish(i)), s;
677
677
  }
678
- #C(e, t = {}) {
679
- let { allowStale: i = this.allowStale, updateAgeOnGet: s = this.updateAgeOnGet, noDeleteOnStaleGet: n = this.noDeleteOnStaleGet, status: r } = t, h = this.#s.get(e);
678
+ #C(e, t2 = {}) {
679
+ let { allowStale: i = this.allowStale, updateAgeOnGet: s = this.updateAgeOnGet, noDeleteOnStaleGet: n = this.noDeleteOnStaleGet, status: r } = t2, h = this.#s.get(e);
680
680
  if (h === undefined) {
681
681
  r && (r.get = "miss");
682
682
  return;
@@ -684,8 +684,8 @@ var init_index_min = __esm(() => {
684
684
  let a = this.#t[h], o = this.#e(a);
685
685
  return r && this.#v(r, h), this.#p(h) ? o ? (r && (r.get = "stale-fetching"), i && a.__staleWhileFetching !== undefined ? (r && (r.returnedStale = true), a.__staleWhileFetching) : undefined) : (n || this.#E(e, "expire"), r && (r.get = "stale"), i ? (r && (r.returnedStale = true), a) : undefined) : (r && (r.get = o ? "fetching" : "hit"), this.#L(h), s && this.#D(h), o ? a.__staleWhileFetching : a);
686
686
  }
687
- #$(e, t) {
688
- this.#u[t] = e, this.#l[e] = t;
687
+ #$(e, t2) {
688
+ this.#u[t2] = e, this.#l[e] = t2;
689
689
  }
690
690
  #L(e) {
691
691
  e !== this.#h && (e === this.#a ? this.#a = this.#l[e] : this.#$(this.#u[e], this.#l[e]), this.#$(this.#h, e), this.#h = e);
@@ -693,18 +693,18 @@ var init_index_min = __esm(() => {
693
693
  delete(e) {
694
694
  return this.#E(e, "delete");
695
695
  }
696
- #E(e, t) {
697
- w.hasSubscribers && w.publish({ op: "delete", delete: t, key: e, cache: this });
696
+ #E(e, t2) {
697
+ w.hasSubscribers && w.publish({ op: "delete", delete: t2, key: e, cache: this });
698
698
  let i = false;
699
699
  if (this.#n !== 0) {
700
700
  let s = this.#s.get(e);
701
701
  if (s !== undefined)
702
702
  if (this.#g?.[s] && (clearTimeout(this.#g?.[s]), this.#g[s] = undefined), i = true, this.#n === 1)
703
- this.#q(t);
703
+ this.#q(t2);
704
704
  else {
705
705
  this.#R(s);
706
706
  let n = this.#t[s];
707
- if (this.#e(n) ? n.__abortController.abort(new Error("deleted")) : (this.#T || this.#f) && (this.#T && this.#w?.(n, e, t), this.#f && this.#r?.push([n, e, t])), this.#s.delete(e), this.#i[s] = undefined, this.#t[s] = undefined, s === this.#h)
707
+ if (this.#e(n) ? n.__abortController.abort(new Error("deleted")) : (this.#T || this.#f) && (this.#T && this.#w?.(n, e, t2), this.#f && this.#r?.push([n, e, t2])), this.#s.delete(e), this.#i[s] = undefined, this.#t[s] = undefined, s === this.#h)
708
708
  this.#h = this.#u[s];
709
709
  else if (s === this.#a)
710
710
  this.#a = this.#l[s];
@@ -728,24 +728,24 @@ var init_index_min = __esm(() => {
728
728
  return this.#q("delete");
729
729
  }
730
730
  #q(e) {
731
- for (let t of this.#z({ allowStale: true })) {
732
- let i = this.#t[t];
731
+ for (let t2 of this.#z({ allowStale: true })) {
732
+ let i = this.#t[t2];
733
733
  if (this.#e(i))
734
734
  i.__abortController.abort(new Error("deleted"));
735
735
  else {
736
- let s = this.#i[t];
736
+ let s = this.#i[t2];
737
737
  this.#T && this.#w?.(i, s, e), this.#f && this.#r?.push([i, s, e]);
738
738
  }
739
739
  }
740
740
  if (this.#s.clear(), this.#t.fill(undefined), this.#i.fill(undefined), this.#d && this.#F) {
741
741
  this.#d.fill(0), this.#F.fill(0);
742
- for (let t of this.#g ?? [])
743
- t !== undefined && clearTimeout(t);
742
+ for (let t2 of this.#g ?? [])
743
+ t2 !== undefined && clearTimeout(t2);
744
744
  this.#g?.fill(undefined);
745
745
  }
746
746
  if (this.#_ && this.#_.fill(0), this.#a = 0, this.#h = 0, this.#y.length = 0, this.#b = 0, this.#n = 0, this.#f && this.#r) {
747
- let t = this.#r, i;
748
- for (;i = t?.shift(); )
747
+ let t2 = this.#r, i;
748
+ for (;i = t2?.shift(); )
749
749
  this.#S?.(...i);
750
750
  }
751
751
  }
@@ -1679,6 +1679,12 @@ var messages_default = {
1679
1679
  invalid_config: "Invalid configuration: {field}",
1680
1680
  connection_failed: "Failed to connect to database: {message}",
1681
1681
  permission_denied: "Permission denied (required: {required})",
1682
+ permission_requires_level: "{type} operation requires {minimum} permission or higher (current level: {permission})",
1683
+ elasticsearch_requires_level: "Elasticsearch {type} operation requires {minimum} permission or higher (current level: {permission})",
1684
+ escalated_write_requires_admin: "This statement opens as a read but contains an executable {keyword}. A write hidden inside a read statement requires admin permission (current level: {permission}).",
1685
+ multiple_statements_refused: "SQL containing multiple statements is refused below admin permission, because only the first statement determines the permission check. Run each statement separately.",
1686
+ unknown_statement_query_only: "Unrecognised SQL statement (current level: query-only). Security policy requires read-write+ for unknown statements. If this is a legitimate read-only statement, please open an issue at https://github.com/CarlLee1983/dbcli/issues.",
1687
+ permission_denied_reason: "Permission denied: {reason}",
1682
1688
  table_not_found: "Table not found: {table}",
1683
1689
  unsupported_lang: "Language '{lang}' not supported, using English",
1684
1690
  invalid_json: "Invalid JSON: {message}",
@@ -1700,7 +1706,8 @@ Provide options: --env-host, --env-port, --env-user, --env-password, --env-datab
1700
1706
  Or use interactive mode: run "dbcli init --use-env-refs" without --no-interactive`,
1701
1707
  env_var_not_defined: `Cannot test connection: environment variable {envKey} is not defined.
1702
1708
  Set {envKey} in .env or environment variables.
1703
- Hint: run 'export {envKey}=<value>' and retry`
1709
+ Hint: run 'export {envKey}=<value>' and retry`,
1710
+ invalid_output_format: "--format {format} is not supported here \u2014 use text or json"
1704
1711
  },
1705
1712
  success: {
1706
1713
  inserted: "Successfully inserted {count} row(s)",
@@ -1711,19 +1718,22 @@ Hint: run 'export {envKey}=<value>' and retry`
1711
1718
  insert: {
1712
1719
  description: "Insert data into a table",
1713
1720
  prompt_data: "Enter JSON data to insert: ",
1714
- confirm: "Insert {count} row(s) into {table}? (y/n): "
1721
+ confirm: "Insert {count} row(s) into {table}? (y/n): ",
1722
+ elasticsearch_unsupported: "Elasticsearch does not support the insert command; for now, use an external tool (e.g. curl or Kibana DevTools) to write documents"
1715
1723
  },
1716
1724
  update: {
1717
1725
  description: "Update data in a table",
1718
1726
  prompt_where: "Enter WHERE clause (e.g., id=1): ",
1719
1727
  prompt_set: 'Enter JSON updates (e.g., {"status": "active"}): ',
1720
- confirm: "Update rows in {table}? (y/n): "
1728
+ confirm: "Update rows in {table}? (y/n): ",
1729
+ elasticsearch_unsupported: "Elasticsearch does not support the update command; for now, use an external tool (e.g. curl or Kibana DevTools) to update documents"
1721
1730
  },
1722
1731
  delete: {
1723
1732
  description: "Delete data from a table",
1724
1733
  prompt_where: "Enter WHERE clause (e.g., id=1): ",
1725
1734
  confirm: "Delete rows from {table}? (y/n): ",
1726
- admin_only: "Delete command requires data-admin or admin permission"
1735
+ admin_only: "Delete command requires data-admin or admin permission",
1736
+ elasticsearch_unsupported: "Elasticsearch does not support the delete command; for now, use an external tool (e.g. curl or Kibana DevTools) to delete documents"
1727
1737
  },
1728
1738
  export: {
1729
1739
  description: "Export query results",
@@ -1973,6 +1983,12 @@ var messages_default2 = {
1973
1983
  invalid_config: "\u914D\u7F6E\u7121\u6548\uFF1A{field}",
1974
1984
  connection_failed: "\u7121\u6CD5\u9023\u63A5\u5230\u8CC7\u6599\u5EAB\uFF1A{message}",
1975
1985
  permission_denied: "\u6B0A\u9650\u88AB\u62D2\uFF08\u9700\u8981\uFF1A{required}\uFF09",
1986
+ permission_requires_level: "{type} \u64CD\u4F5C\u9700\u8981 {minimum} \u4EE5\u4E0A\u7684\u6B0A\u9650\uFF08\u76EE\u524D\u5C64\u7D1A\uFF1A{permission}\uFF09",
1987
+ elasticsearch_requires_level: "Elasticsearch {type} \u64CD\u4F5C\u9700\u8981 {minimum} \u4EE5\u4E0A\u7684\u6B0A\u9650\uFF08\u76EE\u524D\u5C64\u7D1A\uFF1A{permission}\uFF09",
1988
+ escalated_write_requires_admin: "\u6B64\u8A9E\u53E5\u8868\u9762\u4E0A\u662F\u8B80\u53D6\uFF0C\u4F46\u5BE6\u969B\u5305\u542B\u53EF\u57F7\u884C\u7684 {keyword}\u3002\u8B80\u53D6\u8A9E\u53E5\u4E2D\u96B1\u85CF\u5BEB\u5165\u64CD\u4F5C\u9700\u8981 admin \u6B0A\u9650\uFF08\u76EE\u524D\u5C64\u7D1A\uFF1A{permission}\uFF09\u3002",
1989
+ multiple_statements_refused: "\u4F4E\u65BC admin \u6B0A\u9650\u6642\u62D2\u7D55\u57F7\u884C\u5305\u542B\u591A\u500B\u8A9E\u53E5\u7684 SQL\uFF0C\u56E0\u70BA\u6B0A\u9650\u6AA2\u67E5\u53EA\u6703\u4F9D\u64DA\u7B2C\u4E00\u500B\u8A9E\u53E5\u5224\u65B7\u3002\u8ACB\u5C07\u5404\u8A9E\u53E5\u5206\u958B\u57F7\u884C\u3002",
1990
+ unknown_statement_query_only: "\u7121\u6CD5\u8FA8\u8B58\u7684 SQL \u8A9E\u53E5\uFF08\u76EE\u524D\u5C64\u7D1A\uFF1Aquery-only\uFF09\u3002\u5B89\u5168\u653F\u7B56\u8981\u6C42\u672A\u77E5\u8A9E\u53E5\u81F3\u5C11\u9700\u8981 read-write \u4EE5\u4E0A\u6B0A\u9650\u3002\u82E5\u9019\u5176\u5BE6\u662F\u5408\u6CD5\u7684\u552F\u8B80\u8A9E\u53E5\uFF0C\u8ACB\u81F3 https://github.com/CarlLee1983/dbcli/issues \u63D0\u51FA\u8B70\u984C\u3002",
1991
+ permission_denied_reason: "\u6B0A\u9650\u88AB\u62D2\uFF1A{reason}",
1976
1992
  table_not_found: "\u627E\u4E0D\u5230\u8868\u683C\uFF1A{table}",
1977
1993
  unsupported_lang: "\u4E0D\u652F\u63F4\u7684\u8A9E\u8A00 '{lang}'\uFF0C\u4F7F\u7528\u82F1\u6587",
1978
1994
  invalid_json: "\u7121\u6548\u7684 JSON\uFF1A{message}",
@@ -1994,7 +2010,8 @@ var messages_default2 = {
1994
2010
  \u6216\u4F7F\u7528\u4E92\u52D5\u6A21\u5F0F\uFF1A\u57F7\u884C "dbcli init --use-env-refs"\uFF08\u4E0D\u52A0 --no-interactive\uFF09`,
1995
2011
  env_var_not_defined: `\u7121\u6CD5\u6E2C\u8A66\u9023\u7DDA\uFF1A\u74B0\u5883\u8B8A\u6578 {envKey} \u672A\u5B9A\u7FA9\u3002
1996
2012
  \u8ACB\u5728 .env \u6216\u74B0\u5883\u8B8A\u6578\u4E2D\u8A2D\u5B9A {envKey}\u3002
1997
- \u63D0\u793A\uFF1A\u57F7\u884C 'export {envKey}=<value>' \u5F8C\u91CD\u8A66`
2013
+ \u63D0\u793A\uFF1A\u57F7\u884C 'export {envKey}=<value>' \u5F8C\u91CD\u8A66`,
2014
+ invalid_output_format: "\u7121\u6CD5\u4F7F\u7528 --format {format}\uFF0C\u8ACB\u4F7F\u7528 text \u6216 json"
1998
2015
  },
1999
2016
  success: {
2000
2017
  inserted: "\u6210\u529F\u63D2\u5165 {count} \u5217",
@@ -2005,19 +2022,22 @@ var messages_default2 = {
2005
2022
  insert: {
2006
2023
  description: "\u63D2\u5165\u8CC7\u6599\u5230\u8868\u683C",
2007
2024
  prompt_data: "\u8F38\u5165\u8981\u63D2\u5165\u7684 JSON \u8CC7\u6599\uFF1A",
2008
- confirm: "\u5C07 {count} \u5217\u63D2\u5165\u5230 {table}\uFF1F (y/n)\uFF1A"
2025
+ confirm: "\u5C07 {count} \u5217\u63D2\u5165\u5230 {table}\uFF1F (y/n)\uFF1A",
2026
+ elasticsearch_unsupported: "Elasticsearch \u4E0D\u652F\u63F4 insert \u6307\u4EE4\uFF1B\u76EE\u524D\u8ACB\u4F7F\u7528\u5916\u90E8\u5DE5\u5177\uFF08\u5982 curl \u6216 Kibana DevTools\uFF09\u9032\u884C\u6587\u4EF6\u5BEB\u5165"
2009
2027
  },
2010
2028
  update: {
2011
2029
  description: "\u66F4\u65B0\u8868\u683C\u4E2D\u7684\u8CC7\u6599",
2012
2030
  prompt_where: "\u8F38\u5165 WHERE \u5B50\u53E5 (\u4F8B\u5982\uFF1Aid=1)\uFF1A",
2013
2031
  prompt_set: '\u8F38\u5165 JSON \u66F4\u65B0 (\u4F8B\u5982\uFF1A{"status": "active"})\uFF1A',
2014
- confirm: "\u66F4\u65B0 {table} \u4E2D\u7684\u5217\uFF1F (y/n)\uFF1A"
2032
+ confirm: "\u66F4\u65B0 {table} \u4E2D\u7684\u5217\uFF1F (y/n)\uFF1A",
2033
+ elasticsearch_unsupported: "Elasticsearch \u4E0D\u652F\u63F4 update \u6307\u4EE4\uFF1B\u76EE\u524D\u8ACB\u4F7F\u7528\u5916\u90E8\u5DE5\u5177\uFF08\u5982 curl \u6216 Kibana DevTools\uFF09\u9032\u884C\u6587\u4EF6\u66F4\u65B0"
2015
2034
  },
2016
2035
  delete: {
2017
2036
  description: "\u522A\u9664\u8868\u683C\u4E2D\u7684\u8CC7\u6599",
2018
2037
  prompt_where: "\u8F38\u5165 WHERE \u5B50\u53E5 (\u4F8B\u5982\uFF1Aid=1)\uFF1A",
2019
2038
  confirm: "\u522A\u9664 {table} \u4E2D\u7684\u5217\uFF1F (y/n)\uFF1A",
2020
- admin_only: "\u522A\u9664\u547D\u4EE4\u9700\u8981 data-admin \u6216 admin \u6B0A\u9650"
2039
+ admin_only: "\u522A\u9664\u547D\u4EE4\u9700\u8981 data-admin \u6216 admin \u6B0A\u9650",
2040
+ elasticsearch_unsupported: "Elasticsearch \u4E0D\u652F\u63F4 delete \u6307\u4EE4\uFF1B\u76EE\u524D\u8ACB\u4F7F\u7528\u5916\u90E8\u5DE5\u5177\uFF08\u5982 curl \u6216 Kibana DevTools\uFF09\u9032\u884C\u6587\u4EF6\u522A\u9664"
2021
2041
  },
2022
2042
  export: {
2023
2043
  description: "\u532F\u51FA\u67E5\u8A62\u7D50\u679C",
@@ -2152,11 +2172,95 @@ var shell_default2 = {
2152
2172
  rows_display: "{count} \u7B46\u8CC7\u6599",
2153
2173
  unknown_command: "\u672A\u77E5\u6307\u4EE4\uFF1A'{command}'\u3002\u8F38\u5165 '.help' \u67E5\u770B\u53EF\u7528\u6307\u4EE4\u3002"
2154
2174
  };
2175
+ // resources/lang/en/ceremony.json
2176
+ var ceremony_default = {
2177
+ updated: "Updated {count} row(s) in {table}",
2178
+ deleted: "Deleted {count} row(s) from {table}",
2179
+ inserted: "Inserted {count} row(s) into {table}",
2180
+ matched_nothing: "No rows matched in {table} \u2014 nothing changed",
2181
+ cancelled: "Cancelled. {table} was not changed",
2182
+ dry_run: "Preview only. {table} was not changed",
2183
+ elapsed: "Took {seconds}s",
2184
+ failed: "Failed: {reason}",
2185
+ unknown_error: "unknown error",
2186
+ confirm_sql: "Generated SQL:",
2187
+ confirm_command: "Command to run:",
2188
+ confirm_params: "Parameters:",
2189
+ confirm_destructive_warning: "\u26A0\uFE0F Warning: DELETE operation is destructive and cannot be undone!",
2190
+ confirm_destructive_prompt: "Are you sure you want to execute this DELETE operation? This cannot be undone.",
2191
+ confirm_destructive_warning_ddl: "\u26A0\uFE0F Warning: this schema change is destructive and cannot be undone!",
2192
+ confirm_ddl_prompt: "Are you sure you want to run this {operation}? This cannot be undone.",
2193
+ confirm_prompt: "Proceed with this operation?",
2194
+ gate_summary: "This will {operation} rows in {table}.",
2195
+ gate_summary_untargeted: "This will run a {operation} statement.",
2196
+ gate_statement: "Statement:",
2197
+ gate_cancelled: "Cancelled. Nothing was run.",
2198
+ gate_full_table_warning: "\u26A0\uFE0F This affects EVERY row in {table} and cannot be undone.",
2199
+ gate_ddl_warning: "\u26A0\uFE0F This destroys {table} and cannot be undone.",
2200
+ gate_ddl_warning_untargeted: "\u26A0\uFE0F This is a destructive schema change and cannot be undone.",
2201
+ gate_unparseable_warning: "\u26A0\uFE0F dbcli could not parse this statement, so it is treated as affecting everything.",
2202
+ gate_multiple_statements_warning: "\u26A0\uFE0F This is more than one statement, and dbcli will not judge them one at a time.",
2203
+ gate_typed_prompt: "Type {phrase} to run it",
2204
+ gate_typed_mismatch: "That did not match {phrase}. Nothing was run.",
2205
+ gate_refused: "Refused: this statement is not limited to specific rows and nobody is here to confirm it (reason={reason}).",
2206
+ gate_remedy_no_where: "Add a WHERE clause \u2014 WHERE 1=1 if you really do mean every row \u2014 or a LIMIT, then run it again.",
2207
+ gate_remedy_ddl_destruction: "No flag skips this. Run it from an interactive terminal, or apply the schema change through a reviewed migration.",
2208
+ gate_remedy_unparseable: "dbcli could not parse this statement and will not guess. Simplify it, or run it from an interactive terminal.",
2209
+ gate_remedy_multiple_statements: "Run one statement per command.",
2210
+ gate_remedy_non_unique_where: "Match on a primary key or a uniquely indexed column, or run it from an interactive terminal.",
2211
+ recovery_none: "This cannot be undone automatically \u2014 restore from a backup to get the previous values back.",
2212
+ recovery_retry: "Re-run with --recovery to write a recovery plan, then read it with: dbcli recover",
2213
+ blacklist_hint: "Run `dbcli blacklist list` to see what is protected"
2214
+ };
2215
+ // resources/lang/zh-TW/ceremony.json
2216
+ var ceremony_default2 = {
2217
+ updated: "\u5DF2\u66F4\u65B0 {table} \u7684 {count} \u5217",
2218
+ deleted: "\u5DF2\u5F9E {table} \u522A\u9664 {count} \u5217",
2219
+ inserted: "\u5DF2\u5BEB\u5165 {count} \u5217\u5230 {table}",
2220
+ matched_nothing: "{table} \u6C92\u6709\u4EFB\u4F55\u5217\u7B26\u5408\u689D\u4EF6\uFF0C\u8CC7\u6599\u672A\u8B8A\u52D5",
2221
+ cancelled: "\u5DF2\u53D6\u6D88\uFF0C{table} \u672A\u8B8A\u52D5",
2222
+ dry_run: "\u50C5\u9810\u89BD\uFF0C{table} \u672A\u8B8A\u52D5",
2223
+ elapsed: "\u8017\u6642 {seconds} \u79D2",
2224
+ failed: "\u5931\u6557\uFF1A{reason}",
2225
+ unknown_error: "\u672A\u77E5\u7684\u932F\u8AA4",
2226
+ confirm_sql: "\u7522\u751F\u7684 SQL\uFF1A",
2227
+ confirm_command: "\u5373\u5C07\u57F7\u884C\u7684\u6307\u4EE4\uFF1A",
2228
+ confirm_params: "\u53C3\u6578\uFF1A",
2229
+ confirm_destructive_warning: "\u26A0\uFE0F \u8B66\u544A\uFF1ADELETE \u5177\u7834\u58DE\u6027\uFF0C\u57F7\u884C\u5F8C\u7121\u6CD5\u5FA9\u539F\uFF01",
2230
+ confirm_destructive_prompt: "\u78BA\u5B9A\u8981\u57F7\u884C\u9019\u500B DELETE \u55CE\uFF1F\u6B64\u64CD\u4F5C\u7121\u6CD5\u5FA9\u539F\u3002",
2231
+ confirm_destructive_warning_ddl: "\u26A0\uFE0F \u8B66\u544A\uFF1A\u9019\u500B schema \u8B8A\u66F4\u5177\u7834\u58DE\u6027\uFF0C\u57F7\u884C\u5F8C\u7121\u6CD5\u5FA9\u539F\uFF01",
2232
+ confirm_ddl_prompt: "\u78BA\u5B9A\u8981\u57F7\u884C\u9019\u500B {operation} \u55CE\uFF1F\u6B64\u64CD\u4F5C\u7121\u6CD5\u5FA9\u539F\u3002",
2233
+ confirm_prompt: "\u8981\u7E7C\u7E8C\u57F7\u884C\u9019\u500B\u64CD\u4F5C\u55CE\uFF1F",
2234
+ gate_summary: "\u9019\u53E5\u6703\u5C0D {table} \u57F7\u884C {operation}\u3002",
2235
+ gate_summary_untargeted: "\u9019\u53E5\u6703\u57F7\u884C {operation}\u3002",
2236
+ gate_statement: "\u8A9E\u53E5\uFF1A",
2237
+ gate_cancelled: "\u5DF2\u53D6\u6D88\uFF0C\u6C92\u6709\u57F7\u884C\u4EFB\u4F55\u8A9E\u53E5\u3002",
2238
+ gate_full_table_warning: "\u26A0\uFE0F \u9019\u53E5\u6703\u5F71\u97FF {table} \u7684\u6BCF\u4E00\u5217\uFF0C\u57F7\u884C\u5F8C\u7121\u6CD5\u5FA9\u539F\u3002",
2239
+ gate_ddl_warning: "\u26A0\uFE0F \u9019\u53E5\u6703\u6467\u6BC0 {table}\uFF0C\u57F7\u884C\u5F8C\u7121\u6CD5\u5FA9\u539F\u3002",
2240
+ gate_ddl_warning_untargeted: "\u26A0\uFE0F \u9019\u662F\u7834\u58DE\u6027\u7684 schema \u8B8A\u66F4\uFF0C\u57F7\u884C\u5F8C\u7121\u6CD5\u5FA9\u539F\u3002",
2241
+ gate_unparseable_warning: "\u26A0\uFE0F dbcli \u7121\u6CD5\u89E3\u6790\u9019\u53E5\uFF0C\u56E0\u6B64\u4E00\u5F8B\u8996\u70BA\u6703\u5F71\u97FF\u5168\u90E8\u8CC7\u6599\u3002",
2242
+ gate_multiple_statements_warning: "\u26A0\uFE0F \u9019\u88E1\u4E0D\u53EA\u4E00\u53E5\u8A9E\u53E5\uFF0Cdbcli \u4E0D\u6703\u9010\u53E5\u5224\u65B7\u3002",
2243
+ gate_typed_prompt: "\u8F38\u5165 {phrase} \u624D\u6703\u57F7\u884C",
2244
+ gate_typed_mismatch: "\u8F38\u5165\u7684\u5167\u5BB9\u8207 {phrase} \u4E0D\u7B26\uFF0C\u6C92\u6709\u57F7\u884C\u4EFB\u4F55\u8A9E\u53E5\u3002",
2245
+ gate_refused: "\u5DF2\u62D2\u7D55\uFF1A\u9019\u53E5\u6C92\u6709\u9650\u5B9A\u8981\u52D5\u54EA\u4E9B\u5217\uFF0C\u800C\u73FE\u5728\u6C92\u6709\u4EBA\u80FD\u78BA\u8A8D\uFF08reason={reason}\uFF09\u3002",
2246
+ gate_remedy_no_where: "\u88DC\u4E0A WHERE\uFF08\u771F\u7684\u8981\u5168\u8868\u5C31\u5BEB WHERE 1=1\uFF09\u6216 LIMIT\uFF0C\u7136\u5F8C\u91CD\u8DD1\u3002",
2247
+ gate_remedy_ddl_destruction: "\u6C92\u6709\u4EFB\u4F55\u65D7\u6A19\u53EF\u4EE5\u8DF3\u904E\u9019\u4E00\u95DC\u3002\u8ACB\u5728\u4E92\u52D5\u7D42\u7AEF\u4E0B\u57F7\u884C\uFF0C\u6216\u6539\u8D70\u7D93\u904E\u5BE9\u67E5\u7684 migration\u3002",
2248
+ gate_remedy_unparseable: "dbcli \u7121\u6CD5\u89E3\u6790\u9019\u53E5\uFF0C\u4E5F\u4E0D\u6703\u7528\u731C\u7684\u3002\u8ACB\u7C21\u5316\u8A9E\u53E5\uFF0C\u6216\u5728\u4E92\u52D5\u7D42\u7AEF\u4E0B\u57F7\u884C\u3002",
2249
+ gate_remedy_multiple_statements: "\u4E00\u6B21\u53EA\u57F7\u884C\u4E00\u53E5\u8A9E\u53E5\u3002",
2250
+ gate_remedy_non_unique_where: "\u6539\u7528\u4E3B\u9375\u6216\u552F\u4E00\u7D22\u5F15\u6B04\u4F4D\u7576\u689D\u4EF6\uFF0C\u6216\u5728\u4E92\u52D5\u7D42\u7AEF\u4E0B\u57F7\u884C\u3002",
2251
+ recovery_none: "\u6B64\u64CD\u4F5C\u7121\u6CD5\u81EA\u52D5\u9084\u539F\uFF0C\u8981\u53D6\u56DE\u5148\u524D\u7684\u8CC7\u6599\u8ACB\u5F9E\u5099\u4EFD\u56DE\u5FA9\u3002",
2252
+ recovery_retry: "\u52A0\u4E0A --recovery \u91CD\u8DD1\u53EF\u7522\u751F\u56DE\u5FA9\u8A08\u756B\uFF0C\u518D\u7528 dbcli recover \u8B80\u53D6",
2253
+ blacklist_hint: "\u57F7\u884C `dbcli blacklist list` \u67E5\u770B\u53D7\u4FDD\u8B77\u7684\u9805\u76EE"
2254
+ };
2155
2255
 
2156
2256
  // src/i18n/message-loader.ts
2157
2257
  var BUNDLED_MESSAGES = {
2158
- en: { ...messages_default, shell: shell_default },
2159
- "zh-TW": { ...messages_default2, shell: shell_default2 }
2258
+ en: { ...messages_default, shell: shell_default, ceremony: ceremony_default },
2259
+ "zh-TW": {
2260
+ ...messages_default2,
2261
+ shell: shell_default2,
2262
+ ceremony: ceremony_default2
2263
+ }
2160
2264
  };
2161
2265
 
2162
2266
  class MessageLoader {
@@ -2219,6 +2323,7 @@ class MessageLoader {
2219
2323
  }
2220
2324
  }
2221
2325
  var messageLoader = MessageLoader.getInstance();
2326
+ var t = (key) => messageLoader.t(key);
2222
2327
  var t_vars = (key, vars) => messageLoader.interpolate(key, vars);
2223
2328
 
2224
2329
  // src/utils/colors.ts
@@ -3296,12 +3401,12 @@ function detectMongoType(v) {
3296
3401
  function accumulateDocPaths(doc, prefix, acc) {
3297
3402
  for (const [k, v] of Object.entries(doc)) {
3298
3403
  const path = prefix === "" ? k : `${prefix}.${k}`;
3299
- const t = detectMongoType(v);
3404
+ const t2 = detectMongoType(v);
3300
3405
  const slot = acc.get(path) ?? { types: new Set, count: 0 };
3301
- slot.types.add(t);
3406
+ slot.types.add(t2);
3302
3407
  slot.count += 1;
3303
3408
  acc.set(path, slot);
3304
- if (t === "object" && v && typeof v === "object") {
3409
+ if (t2 === "object" && v && typeof v === "object") {
3305
3410
  accumulateDocPaths(v, path, acc);
3306
3411
  }
3307
3412
  }
@@ -4812,18 +4917,7 @@ function continuesIdentifier(sql, index) {
4812
4917
  return run.replace(/^[0-9]+(?:[eE][0-9]+)?/, "").length > 0;
4813
4918
  }
4814
4919
 
4815
- // src/core/permission-guard.ts
4816
- class PermissionError extends Error {
4817
- classification;
4818
- requiredPermission;
4819
- constructor(message, classification, requiredPermission) {
4820
- super(message);
4821
- this.classification = classification;
4822
- this.requiredPermission = requiredPermission;
4823
- this.name = "PermissionError";
4824
- Object.setPrototypeOf(this, PermissionError.prototype);
4825
- }
4826
- }
4920
+ // src/core/permission/sql-analysis.ts
4827
4921
  function normalizeSQL(sql) {
4828
4922
  return sql.replace(/--[^\n]*\n/g, `
4829
4923
  `).replace(/\/\*[\s\S]*?\*\//g, " ").trim().replace(/\s+/g, " ");
@@ -5070,6 +5164,19 @@ function determineConfidence(type, _keyword, _sql) {
5070
5164
  function removeParameterMarkers(sql) {
5071
5165
  return sql.replace(/\$\d+/g, "").replace(/\?/g, "");
5072
5166
  }
5167
+
5168
+ // src/core/permission-guard.ts
5169
+ class PermissionError extends Error {
5170
+ classification;
5171
+ requiredPermission;
5172
+ constructor(message, classification, requiredPermission) {
5173
+ super(message);
5174
+ this.classification = classification;
5175
+ this.requiredPermission = requiredPermission;
5176
+ this.name = "PermissionError";
5177
+ Object.setPrototypeOf(this, PermissionError.prototype);
5178
+ }
5179
+ }
5073
5180
  function classifyStatement(sql) {
5074
5181
  const normalized = normalizeSQL(sql);
5075
5182
  const stripped = stripCommentsAndStrings(normalized);
@@ -5136,15 +5243,38 @@ function checkPermission(sql, permission, dialect) {
5136
5243
  if (permission !== "admin" && containsMultipleStatements(sql, dialect)) {
5137
5244
  return {
5138
5245
  allowed: false,
5139
- reason: "SQL containing multiple statements is refused below admin permission, because only " + "the first statement determines the permission check. Run each statement separately.",
5140
- classification
5246
+ reason: t("errors.multiple_statements_refused"),
5247
+ classification,
5248
+ requiredPermission: "admin"
5141
5249
  };
5142
5250
  }
5251
+ return checkPermissionForClassification(classification, permission);
5252
+ }
5253
+ var TIER_GRANTS = [
5254
+ { permission: "query-only", types: ["SELECT", "SHOW", "DESCRIBE", "EXPLAIN"] },
5255
+ { permission: "read-write", types: ["INSERT", "UPDATE"] },
5256
+ { permission: "data-admin", types: ["DELETE"] }
5257
+ ];
5258
+ function minimumPermissionFor(type) {
5259
+ return TIER_GRANTS.find((tier) => tier.types.includes(type))?.permission ?? "admin";
5260
+ }
5261
+ function refusalReason(type, permission) {
5262
+ return t_vars("errors.permission_requires_level", {
5263
+ type,
5264
+ minimum: minimumPermissionFor(type),
5265
+ permission
5266
+ });
5267
+ }
5268
+ function checkPermissionForClassification(classification, permission) {
5143
5269
  if (permission !== "admin" && classification.escalatedFrom) {
5144
5270
  return {
5145
5271
  allowed: false,
5146
- reason: `This statement opens as a read but contains an executable ` + `${classification.escalatedFrom}. A write hidden inside a read statement ` + `requires admin permission (current level: ${permission}).`,
5147
- classification
5272
+ reason: t_vars("errors.escalated_write_requires_admin", {
5273
+ keyword: classification.escalatedFrom,
5274
+ permission
5275
+ }),
5276
+ classification,
5277
+ requiredPermission: "admin"
5148
5278
  };
5149
5279
  }
5150
5280
  if (permission === "admin") {
@@ -5154,62 +5284,51 @@ function checkPermission(sql, permission, dialect) {
5154
5284
  classification
5155
5285
  };
5156
5286
  }
5157
- if (permission === "data-admin") {
5158
- const allowedTypes = ["SELECT", "INSERT", "UPDATE", "DELETE", "SHOW", "DESCRIBE", "EXPLAIN"];
5159
- if (allowedTypes.includes(classification.type)) {
5160
- return {
5161
- allowed: true,
5162
- reason: `${classification.type} operation allowed in data-admin mode`,
5163
- classification
5164
- };
5165
- }
5166
- return {
5167
- allowed: false,
5168
- reason: `${classification.type} operation requires admin permission`,
5169
- classification
5170
- };
5171
- }
5172
- if (permission === "read-write") {
5173
- const allowedTypes = ["SELECT", "INSERT", "UPDATE", "SHOW", "DESCRIBE", "EXPLAIN"];
5287
+ const tierIndex = TIER_GRANTS.findIndex((tier) => tier.permission === permission);
5288
+ if (tierIndex !== -1) {
5289
+ const allowedTypes = TIER_GRANTS.slice(0, tierIndex + 1).flatMap((tier) => tier.types);
5174
5290
  if (allowedTypes.includes(classification.type)) {
5175
5291
  return {
5176
5292
  allowed: true,
5177
- reason: `${classification.type} operation allowed in read-write mode`,
5293
+ reason: `${classification.type} operation allowed in ${permission} mode`,
5178
5294
  classification
5179
5295
  };
5180
5296
  }
5297
+ const isUnknown = permission === "query-only" && classification.type === "UNKNOWN";
5181
5298
  return {
5182
5299
  allowed: false,
5183
- reason: `${classification.type} operation requires data-admin or admin permission`,
5184
- classification
5185
- };
5186
- }
5187
- if (permission === "query-only") {
5188
- const allowedTypes = ["SELECT", "SHOW", "DESCRIBE", "EXPLAIN"];
5189
- if (allowedTypes.includes(classification.type)) {
5190
- return {
5191
- allowed: true,
5192
- reason: `${classification.type} operation allowed in query-only mode`,
5193
- classification
5194
- };
5195
- }
5196
- const isUnknown = classification.type === "UNKNOWN";
5197
- return {
5198
- allowed: false,
5199
- reason: isUnknown ? `Unrecognised SQL statement (current level: query-only). Security policy requires read-write+ for unknown statements. If this is a legitimate read-only statement, please open an issue at https://github.com/CarlLee1983/dbcli/issues.` : `${classification.type} operation requires read-write or admin permission`,
5200
- classification
5300
+ reason: isUnknown ? t("errors.unknown_statement_query_only") : refusalReason(classification.type, permission),
5301
+ classification,
5302
+ requiredPermission: isUnknown ? "read-write" : minimumPermissionFor(classification.type)
5201
5303
  };
5202
5304
  }
5203
5305
  return {
5204
5306
  allowed: false,
5205
5307
  reason: `Unknown permission level: ${permission}`,
5206
- classification
5308
+ classification,
5309
+ requiredPermission: "admin"
5207
5310
  };
5208
5311
  }
5312
+ function classificationForType(type) {
5313
+ return {
5314
+ type,
5315
+ isDangerous: isDestructiveOperation(type),
5316
+ keywords: [type],
5317
+ isComposite: false,
5318
+ confidence: "HIGH"
5319
+ };
5320
+ }
5321
+ function enforcePermissionForType(type, permission) {
5322
+ const classification = classificationForType(type);
5323
+ const result = checkPermissionForClassification(classification, permission);
5324
+ if (!result.allowed) {
5325
+ throw new PermissionError(result.reason, classification, minimumPermissionFor(type));
5326
+ }
5327
+ }
5209
5328
  function enforcePermission(sql, permission, dialect) {
5210
5329
  const result = checkPermission(sql, permission, dialect);
5211
5330
  if (!result.allowed) {
5212
- throw new PermissionError(result.reason, result.classification, permission);
5331
+ throw new PermissionError(result.reason, result.classification, result.requiredPermission ?? "admin");
5213
5332
  }
5214
5333
  return result.classification;
5215
5334
  }
@@ -5313,7 +5432,7 @@ function extractTableNameFromError(errorMessage) {
5313
5432
  async function getAllTablesFromAdapter(adapter) {
5314
5433
  try {
5315
5434
  const tables = await adapter.listTables();
5316
- return tables.map((t) => t.name);
5435
+ return tables.map((t2) => t2.name);
5317
5436
  } catch (error) {
5318
5437
  console.warn("Failed to list tables for suggestions:", error);
5319
5438
  return [];
@@ -5965,108 +6084,6 @@ function inferColumnType(value) {
5965
6084
  }
5966
6085
  return "unknown";
5967
6086
  }
5968
- // src/utils/prompts.ts
5969
- var promptsUnavailableReported = false;
5970
- async function loadInquirer() {
5971
- try {
5972
- return await import("@inquirer/prompts");
5973
- } catch (error) {
5974
- if (!promptsUnavailableReported) {
5975
- promptsUnavailableReported = true;
5976
- const reason = error instanceof Error ? error.message : String(error);
5977
- process.stderr.write(`[dbcli] rich interactive prompts are unavailable (${reason}); falling back to plain-text input
5978
- `);
5979
- }
5980
- return;
5981
- }
5982
- }
5983
- async function readLineFromStdin(prompt = "") {
5984
- return new Promise((resolve) => {
5985
- if (prompt) {
5986
- process.stdout.write(prompt);
5987
- }
5988
- let data = "";
5989
- const chunks = [];
5990
- const onData = (chunk) => {
5991
- chunks.push(chunk);
5992
- data = Buffer.concat(chunks).toString();
5993
- const lines = data.split(`
5994
- `);
5995
- if (lines.length > 1) {
5996
- process.stdin.pause();
5997
- process.stdin.removeListener("data", onData);
5998
- process.stdin.removeListener("end", onEnd);
5999
- resolve((lines[0] ?? "").trim());
6000
- }
6001
- };
6002
- const onEnd = () => {
6003
- process.stdin.removeListener("data", onData);
6004
- resolve(data.trim());
6005
- };
6006
- process.stdin.on("data", onData);
6007
- process.stdin.on("end", onEnd);
6008
- process.stdin.resume();
6009
- });
6010
- }
6011
- async function textFallback(message, defaultValue) {
6012
- const displayMessage = defaultValue ? `${message} [${defaultValue}]: ` : `${message}: `;
6013
- const answer = await readLineFromStdin(displayMessage);
6014
- return answer.trim() || defaultValue || "";
6015
- }
6016
- async function selectFallback(message, choices) {
6017
- console.log(message);
6018
- choices.forEach((choice, index) => {
6019
- console.log(` ${index + 1}) ${choice}`);
6020
- });
6021
- const answer = await readLineFromStdin("Select option (number): ");
6022
- const selectedIndex = parseInt(answer, 10) - 1;
6023
- if (selectedIndex >= 0 && selectedIndex < choices.length) {
6024
- return choices[selectedIndex] ?? choices[0] ?? "";
6025
- }
6026
- return choices[0] ?? "";
6027
- }
6028
- async function confirmFallback(message) {
6029
- const answer = await readLineFromStdin(`${message} (y/n): `);
6030
- return answer.toLowerCase() === "y" || answer.toLowerCase() === "yes";
6031
- }
6032
- async function text(message, defaultValue) {
6033
- if (!process.stdin.isTTY)
6034
- return textFallback(message, defaultValue);
6035
- const inquirer = await loadInquirer();
6036
- if (!inquirer)
6037
- return textFallback(message, defaultValue);
6038
- return await inquirer.input({ message, default: defaultValue });
6039
- }
6040
- async function select(message, choices) {
6041
- if (!process.stdin.isTTY)
6042
- return await selectFallback(message, choices);
6043
- const inquirer = await loadInquirer();
6044
- if (!inquirer)
6045
- return await selectFallback(message, choices);
6046
- return await inquirer.select({ message, choices });
6047
- }
6048
- async function secret(message) {
6049
- const inquirer = await loadInquirer();
6050
- if (!inquirer) {
6051
- throw new Error("Masked input is unavailable; pass the value with --stdin or --password instead.");
6052
- }
6053
- return await inquirer.password({ message, mask: "*" });
6054
- }
6055
- async function confirm(message) {
6056
- if (!process.stdin.isTTY)
6057
- return await confirmFallback(message);
6058
- const inquirer = await loadInquirer();
6059
- if (!inquirer)
6060
- return await confirmFallback(message);
6061
- return await inquirer.confirm({ message });
6062
- }
6063
- var promptUser = {
6064
- text,
6065
- select,
6066
- confirm,
6067
- secret
6068
- };
6069
-
6070
6087
  // src/types/blacklist.ts
6071
6088
  class BlacklistError extends Error {
6072
6089
  tableName;
@@ -6114,8 +6131,8 @@ class DataExecutor {
6114
6131
  const timestamp = new Date().toISOString();
6115
6132
  try {
6116
6133
  this.checkBlacklist("INSERT", tableName);
6117
- enforcePermission("INSERT INTO dummy", this.permission);
6118
- return await this.executeMutation("insert", this.buildInsertSql(tableName, data, schema), timestamp, options, { prompt: "Proceed with this operation?" });
6134
+ enforcePermissionForType("INSERT", this.permission);
6135
+ return await this.executeMutation("insert", this.buildInsertSql(tableName, data, schema), timestamp, options, { destructive: false });
6119
6136
  } catch (error) {
6120
6137
  return this.handleMutationError("insert", timestamp, error);
6121
6138
  }
@@ -6124,8 +6141,8 @@ class DataExecutor {
6124
6141
  const timestamp = new Date().toISOString();
6125
6142
  try {
6126
6143
  this.checkBlacklist("UPDATE", tableName);
6127
- enforcePermission("UPDATE dummy", this.permission);
6128
- return await this.executeMutation("update", this.buildUpdateSql(tableName, data, where, schema), timestamp, options, { prompt: "Proceed with this operation?" });
6144
+ enforcePermissionForType("UPDATE", this.permission);
6145
+ return await this.executeMutation("update", this.buildUpdateSql(tableName, data, where, schema), timestamp, options, { destructive: false });
6129
6146
  } catch (error) {
6130
6147
  return this.handleMutationError("update", timestamp, error);
6131
6148
  }
@@ -6134,19 +6151,8 @@ class DataExecutor {
6134
6151
  const timestamp = new Date().toISOString();
6135
6152
  try {
6136
6153
  this.checkBlacklist("DELETE", tableName);
6137
- if (this.permission !== "data-admin" && this.permission !== "admin") {
6138
- return {
6139
- status: "error",
6140
- operation: "delete",
6141
- rows_affected: 0,
6142
- timestamp,
6143
- error: "Permission denied: DELETE operation requires Data-Admin or Admin permission."
6144
- };
6145
- }
6146
- return await this.executeMutation("delete", this.buildDeleteSql(tableName, where, schema), timestamp, options, {
6147
- warning: "\u26A0\uFE0F Warning: DELETE operation is destructive and cannot be undone!",
6148
- prompt: "Are you sure you want to execute this DELETE operation? This cannot be undone."
6149
- });
6154
+ enforcePermissionForType("DELETE", this.permission);
6155
+ return await this.executeMutation("delete", this.buildDeleteSql(tableName, where, schema), timestamp, options, { destructive: true });
6150
6156
  } catch (error) {
6151
6157
  return this.handleMutationError("delete", timestamp, error);
6152
6158
  }
@@ -6160,31 +6166,31 @@ class DataExecutor {
6160
6166
  checkBlacklist(operation, tableName) {
6161
6167
  this.blacklistValidator?.checkTableBlacklist(operation, tableName, []);
6162
6168
  }
6163
- async executeMutation(operation, statement, timestamp, options, confirmation) {
6169
+ async executeMutation(operation, statement, timestamp, options, { destructive }) {
6164
6170
  if (options?.dryRun) {
6165
- return this.successResult(operation, 0, timestamp, statement.sql);
6171
+ return this.outcomeResult("dry_run", operation, 0, timestamp, statement.sql);
6166
6172
  }
6167
6173
  if (!options?.force) {
6168
- if (confirmation.warning) {
6169
- console.log(`
6170
- ${confirmation.warning}`);
6174
+ if (!options?.confirm) {
6175
+ throw new Error(`Refusing to ${operation} without confirmation: no confirmation handler was supplied. ` + "Pass options.confirm to ask the user, or options.force to proceed unattended.");
6171
6176
  }
6172
- console.log(`
6173
- Generated SQL:`);
6174
- console.log(` ${statement.sql}`);
6175
- console.log(`
6176
- Parameters:`);
6177
- console.log(` ${JSON.stringify(statement.params, null, 2)}`);
6178
- if (!await promptUser.confirm(confirmation.prompt)) {
6179
- return this.successResult(operation, 0, timestamp, statement.sql);
6177
+ const proceed = await options.confirm({
6178
+ operation,
6179
+ engine: "sql",
6180
+ sql: statement.sql,
6181
+ params: statement.params,
6182
+ destructive
6183
+ });
6184
+ if (!proceed) {
6185
+ return this.outcomeResult("cancelled", operation, 0, timestamp, statement.sql);
6180
6186
  }
6181
6187
  }
6182
6188
  const result = await this.adapter.execute(statement.sql, statement.params);
6183
- return this.successResult(operation, result.affectedRows, timestamp, statement.sql);
6189
+ return this.outcomeResult("success", operation, result.affectedRows, timestamp, statement.sql);
6184
6190
  }
6185
- successResult(operation, rowsAffected, timestamp, sql) {
6191
+ outcomeResult(status, operation, rowsAffected, timestamp, sql) {
6186
6192
  return {
6187
- status: "success",
6193
+ status,
6188
6194
  operation,
6189
6195
  rows_affected: rowsAffected,
6190
6196
  timestamp,
@@ -6195,13 +6201,13 @@ Parameters:`);
6195
6201
  if (error instanceof BlacklistError) {
6196
6202
  throw error;
6197
6203
  }
6198
- if (error instanceof PermissionError && operation !== "delete") {
6204
+ if (error instanceof PermissionError) {
6199
6205
  return {
6200
6206
  status: "error",
6201
6207
  operation,
6202
6208
  rows_affected: 0,
6203
6209
  timestamp,
6204
- error: `Permission denied: Query-only mode only allows SELECT. Use Read-Write or Admin mode to execute ${operation.toUpperCase()}.`
6210
+ error: t_vars("errors.permission_denied_reason", { reason: error.message })
6205
6211
  };
6206
6212
  }
6207
6213
  const errorMessage = error instanceof Error ? error.message : String(error);
@@ -6463,8 +6469,8 @@ var ZodParsedType = util.arrayToEnum([
6463
6469
  "set"
6464
6470
  ]);
6465
6471
  var getParsedType = (data) => {
6466
- const t = typeof data;
6467
- switch (t) {
6472
+ const t2 = typeof data;
6473
+ switch (t2) {
6468
6474
  case "undefined":
6469
6475
  return ZodParsedType.undefined;
6470
6476
  case "string":