@carllee1983/dbcli 0.4.0-beta → 0.5.0-beta
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/CHANGELOG.md +25 -0
- package/README.md +66 -0
- package/README.zh-TW.md +66 -4
- package/assets/SKILL.md +50 -1
- package/dist/cli.mjs +839 -95
- package/package.json +2 -1
package/dist/cli.mjs
CHANGED
|
@@ -2064,6 +2064,76 @@ var require_commander = __commonJS((exports) => {
|
|
|
2064
2064
|
exports.InvalidOptionArgumentError = InvalidArgumentError;
|
|
2065
2065
|
});
|
|
2066
2066
|
|
|
2067
|
+
// node_modules/picocolors/picocolors.js
|
|
2068
|
+
var require_picocolors = __commonJS((exports, module) => {
|
|
2069
|
+
var p = process || {};
|
|
2070
|
+
var argv = p.argv || [];
|
|
2071
|
+
var env = p.env || {};
|
|
2072
|
+
var isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
|
|
2073
|
+
var formatter = (open, close, replace = open) => (input) => {
|
|
2074
|
+
let string = "" + input, index = string.indexOf(close, open.length);
|
|
2075
|
+
return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
|
|
2076
|
+
};
|
|
2077
|
+
var replaceClose = (string, close, replace, index) => {
|
|
2078
|
+
let result = "", cursor = 0;
|
|
2079
|
+
do {
|
|
2080
|
+
result += string.substring(cursor, index) + replace;
|
|
2081
|
+
cursor = index + close.length;
|
|
2082
|
+
index = string.indexOf(close, cursor);
|
|
2083
|
+
} while (~index);
|
|
2084
|
+
return result + string.substring(cursor);
|
|
2085
|
+
};
|
|
2086
|
+
var createColors = (enabled = isColorSupported) => {
|
|
2087
|
+
let f = enabled ? formatter : () => String;
|
|
2088
|
+
return {
|
|
2089
|
+
isColorSupported: enabled,
|
|
2090
|
+
reset: f("\x1B[0m", "\x1B[0m"),
|
|
2091
|
+
bold: f("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
|
|
2092
|
+
dim: f("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
|
|
2093
|
+
italic: f("\x1B[3m", "\x1B[23m"),
|
|
2094
|
+
underline: f("\x1B[4m", "\x1B[24m"),
|
|
2095
|
+
inverse: f("\x1B[7m", "\x1B[27m"),
|
|
2096
|
+
hidden: f("\x1B[8m", "\x1B[28m"),
|
|
2097
|
+
strikethrough: f("\x1B[9m", "\x1B[29m"),
|
|
2098
|
+
black: f("\x1B[30m", "\x1B[39m"),
|
|
2099
|
+
red: f("\x1B[31m", "\x1B[39m"),
|
|
2100
|
+
green: f("\x1B[32m", "\x1B[39m"),
|
|
2101
|
+
yellow: f("\x1B[33m", "\x1B[39m"),
|
|
2102
|
+
blue: f("\x1B[34m", "\x1B[39m"),
|
|
2103
|
+
magenta: f("\x1B[35m", "\x1B[39m"),
|
|
2104
|
+
cyan: f("\x1B[36m", "\x1B[39m"),
|
|
2105
|
+
white: f("\x1B[37m", "\x1B[39m"),
|
|
2106
|
+
gray: f("\x1B[90m", "\x1B[39m"),
|
|
2107
|
+
bgBlack: f("\x1B[40m", "\x1B[49m"),
|
|
2108
|
+
bgRed: f("\x1B[41m", "\x1B[49m"),
|
|
2109
|
+
bgGreen: f("\x1B[42m", "\x1B[49m"),
|
|
2110
|
+
bgYellow: f("\x1B[43m", "\x1B[49m"),
|
|
2111
|
+
bgBlue: f("\x1B[44m", "\x1B[49m"),
|
|
2112
|
+
bgMagenta: f("\x1B[45m", "\x1B[49m"),
|
|
2113
|
+
bgCyan: f("\x1B[46m", "\x1B[49m"),
|
|
2114
|
+
bgWhite: f("\x1B[47m", "\x1B[49m"),
|
|
2115
|
+
blackBright: f("\x1B[90m", "\x1B[39m"),
|
|
2116
|
+
redBright: f("\x1B[91m", "\x1B[39m"),
|
|
2117
|
+
greenBright: f("\x1B[92m", "\x1B[39m"),
|
|
2118
|
+
yellowBright: f("\x1B[93m", "\x1B[39m"),
|
|
2119
|
+
blueBright: f("\x1B[94m", "\x1B[39m"),
|
|
2120
|
+
magentaBright: f("\x1B[95m", "\x1B[39m"),
|
|
2121
|
+
cyanBright: f("\x1B[96m", "\x1B[39m"),
|
|
2122
|
+
whiteBright: f("\x1B[97m", "\x1B[39m"),
|
|
2123
|
+
bgBlackBright: f("\x1B[100m", "\x1B[49m"),
|
|
2124
|
+
bgRedBright: f("\x1B[101m", "\x1B[49m"),
|
|
2125
|
+
bgGreenBright: f("\x1B[102m", "\x1B[49m"),
|
|
2126
|
+
bgYellowBright: f("\x1B[103m", "\x1B[49m"),
|
|
2127
|
+
bgBlueBright: f("\x1B[104m", "\x1B[49m"),
|
|
2128
|
+
bgMagentaBright: f("\x1B[105m", "\x1B[49m"),
|
|
2129
|
+
bgCyanBright: f("\x1B[106m", "\x1B[49m"),
|
|
2130
|
+
bgWhiteBright: f("\x1B[107m", "\x1B[49m")
|
|
2131
|
+
};
|
|
2132
|
+
};
|
|
2133
|
+
module.exports = createColors();
|
|
2134
|
+
module.exports.createColors = createColors;
|
|
2135
|
+
});
|
|
2136
|
+
|
|
2067
2137
|
// node_modules/@inquirer/core/dist/esm/lib/key.mjs
|
|
2068
2138
|
var isUpKey = (key) => key.name === "up" || key.name === "k" || key.ctrl && key.name === "p", isDownKey = (key) => key.name === "down" || key.name === "j" || key.ctrl && key.name === "n", isSpaceKey = (key) => key.name === "space", isBackspaceKey = (key) => key.name === "backspace", isNumberKey = (key) => "123456789".includes(key.name), isEnterKey = (key) => key.name === "enter" || key.name === "return";
|
|
2069
2139
|
|
|
@@ -2267,49 +2337,49 @@ var require_yoctocolors_cjs = __commonJS((exports, module) => {
|
|
|
2267
2337
|
return result;
|
|
2268
2338
|
};
|
|
2269
2339
|
};
|
|
2270
|
-
var
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
module.exports =
|
|
2340
|
+
var colors2 = {};
|
|
2341
|
+
colors2.reset = format(0, 0);
|
|
2342
|
+
colors2.bold = format(1, 22);
|
|
2343
|
+
colors2.dim = format(2, 22);
|
|
2344
|
+
colors2.italic = format(3, 23);
|
|
2345
|
+
colors2.underline = format(4, 24);
|
|
2346
|
+
colors2.overline = format(53, 55);
|
|
2347
|
+
colors2.inverse = format(7, 27);
|
|
2348
|
+
colors2.hidden = format(8, 28);
|
|
2349
|
+
colors2.strikethrough = format(9, 29);
|
|
2350
|
+
colors2.black = format(30, 39);
|
|
2351
|
+
colors2.red = format(31, 39);
|
|
2352
|
+
colors2.green = format(32, 39);
|
|
2353
|
+
colors2.yellow = format(33, 39);
|
|
2354
|
+
colors2.blue = format(34, 39);
|
|
2355
|
+
colors2.magenta = format(35, 39);
|
|
2356
|
+
colors2.cyan = format(36, 39);
|
|
2357
|
+
colors2.white = format(37, 39);
|
|
2358
|
+
colors2.gray = format(90, 39);
|
|
2359
|
+
colors2.bgBlack = format(40, 49);
|
|
2360
|
+
colors2.bgRed = format(41, 49);
|
|
2361
|
+
colors2.bgGreen = format(42, 49);
|
|
2362
|
+
colors2.bgYellow = format(43, 49);
|
|
2363
|
+
colors2.bgBlue = format(44, 49);
|
|
2364
|
+
colors2.bgMagenta = format(45, 49);
|
|
2365
|
+
colors2.bgCyan = format(46, 49);
|
|
2366
|
+
colors2.bgWhite = format(47, 49);
|
|
2367
|
+
colors2.bgGray = format(100, 49);
|
|
2368
|
+
colors2.redBright = format(91, 39);
|
|
2369
|
+
colors2.greenBright = format(92, 39);
|
|
2370
|
+
colors2.yellowBright = format(93, 39);
|
|
2371
|
+
colors2.blueBright = format(94, 39);
|
|
2372
|
+
colors2.magentaBright = format(95, 39);
|
|
2373
|
+
colors2.cyanBright = format(96, 39);
|
|
2374
|
+
colors2.whiteBright = format(97, 39);
|
|
2375
|
+
colors2.bgRedBright = format(101, 49);
|
|
2376
|
+
colors2.bgGreenBright = format(102, 49);
|
|
2377
|
+
colors2.bgYellowBright = format(103, 49);
|
|
2378
|
+
colors2.bgBlueBright = format(104, 49);
|
|
2379
|
+
colors2.bgMagentaBright = format(105, 49);
|
|
2380
|
+
colors2.bgCyanBright = format(106, 49);
|
|
2381
|
+
colors2.bgWhiteBright = format(107, 49);
|
|
2382
|
+
module.exports = colors2;
|
|
2313
2383
|
});
|
|
2314
2384
|
|
|
2315
2385
|
// node_modules/@inquirer/figures/dist/esm/index.js
|
|
@@ -41827,17 +41897,17 @@ var require_zalgo = __commonJS((exports, module) => {
|
|
|
41827
41897
|
|
|
41828
41898
|
// node_modules/@colors/colors/lib/maps/america.js
|
|
41829
41899
|
var require_america = __commonJS((exports, module) => {
|
|
41830
|
-
module["exports"] = function(
|
|
41900
|
+
module["exports"] = function(colors9) {
|
|
41831
41901
|
return function(letter, i, exploded) {
|
|
41832
41902
|
if (letter === " ")
|
|
41833
41903
|
return letter;
|
|
41834
41904
|
switch (i % 3) {
|
|
41835
41905
|
case 0:
|
|
41836
|
-
return
|
|
41906
|
+
return colors9.red(letter);
|
|
41837
41907
|
case 1:
|
|
41838
|
-
return
|
|
41908
|
+
return colors9.white(letter);
|
|
41839
41909
|
case 2:
|
|
41840
|
-
return
|
|
41910
|
+
return colors9.blue(letter);
|
|
41841
41911
|
}
|
|
41842
41912
|
};
|
|
41843
41913
|
};
|
|
@@ -41845,22 +41915,22 @@ var require_america = __commonJS((exports, module) => {
|
|
|
41845
41915
|
|
|
41846
41916
|
// node_modules/@colors/colors/lib/maps/zebra.js
|
|
41847
41917
|
var require_zebra = __commonJS((exports, module) => {
|
|
41848
|
-
module["exports"] = function(
|
|
41918
|
+
module["exports"] = function(colors9) {
|
|
41849
41919
|
return function(letter, i, exploded) {
|
|
41850
|
-
return i % 2 === 0 ? letter :
|
|
41920
|
+
return i % 2 === 0 ? letter : colors9.inverse(letter);
|
|
41851
41921
|
};
|
|
41852
41922
|
};
|
|
41853
41923
|
});
|
|
41854
41924
|
|
|
41855
41925
|
// node_modules/@colors/colors/lib/maps/rainbow.js
|
|
41856
41926
|
var require_rainbow = __commonJS((exports, module) => {
|
|
41857
|
-
module["exports"] = function(
|
|
41927
|
+
module["exports"] = function(colors9) {
|
|
41858
41928
|
var rainbowColors = ["red", "yellow", "green", "blue", "magenta"];
|
|
41859
41929
|
return function(letter, i, exploded) {
|
|
41860
41930
|
if (letter === " ") {
|
|
41861
41931
|
return letter;
|
|
41862
41932
|
} else {
|
|
41863
|
-
return
|
|
41933
|
+
return colors9[rainbowColors[i++ % rainbowColors.length]](letter);
|
|
41864
41934
|
}
|
|
41865
41935
|
};
|
|
41866
41936
|
};
|
|
@@ -41868,7 +41938,7 @@ var require_rainbow = __commonJS((exports, module) => {
|
|
|
41868
41938
|
|
|
41869
41939
|
// node_modules/@colors/colors/lib/maps/random.js
|
|
41870
41940
|
var require_random = __commonJS((exports, module) => {
|
|
41871
|
-
module["exports"] = function(
|
|
41941
|
+
module["exports"] = function(colors9) {
|
|
41872
41942
|
var available = [
|
|
41873
41943
|
"underline",
|
|
41874
41944
|
"inverse",
|
|
@@ -41889,40 +41959,40 @@ var require_random = __commonJS((exports, module) => {
|
|
|
41889
41959
|
"brightMagenta"
|
|
41890
41960
|
];
|
|
41891
41961
|
return function(letter, i, exploded) {
|
|
41892
|
-
return letter === " " ? letter :
|
|
41962
|
+
return letter === " " ? letter : colors9[available[Math.round(Math.random() * (available.length - 2))]](letter);
|
|
41893
41963
|
};
|
|
41894
41964
|
};
|
|
41895
41965
|
});
|
|
41896
41966
|
|
|
41897
41967
|
// node_modules/@colors/colors/lib/colors.js
|
|
41898
41968
|
var require_colors = __commonJS((exports, module) => {
|
|
41899
|
-
var
|
|
41900
|
-
module["exports"] =
|
|
41901
|
-
|
|
41969
|
+
var colors9 = {};
|
|
41970
|
+
module["exports"] = colors9;
|
|
41971
|
+
colors9.themes = {};
|
|
41902
41972
|
var util3 = __require("util");
|
|
41903
|
-
var ansiStyles =
|
|
41973
|
+
var ansiStyles = colors9.styles = require_styles();
|
|
41904
41974
|
var defineProps = Object.defineProperties;
|
|
41905
41975
|
var newLineRegex = new RegExp(/[\r\n]+/g);
|
|
41906
|
-
|
|
41907
|
-
if (typeof
|
|
41908
|
-
|
|
41976
|
+
colors9.supportsColor = require_supports_colors().supportsColor;
|
|
41977
|
+
if (typeof colors9.enabled === "undefined") {
|
|
41978
|
+
colors9.enabled = colors9.supportsColor() !== false;
|
|
41909
41979
|
}
|
|
41910
|
-
|
|
41911
|
-
|
|
41980
|
+
colors9.enable = function() {
|
|
41981
|
+
colors9.enabled = true;
|
|
41912
41982
|
};
|
|
41913
|
-
|
|
41914
|
-
|
|
41983
|
+
colors9.disable = function() {
|
|
41984
|
+
colors9.enabled = false;
|
|
41915
41985
|
};
|
|
41916
|
-
|
|
41986
|
+
colors9.stripColors = colors9.strip = function(str) {
|
|
41917
41987
|
return ("" + str).replace(/\x1B\[\d+m/g, "");
|
|
41918
41988
|
};
|
|
41919
|
-
var stylize =
|
|
41920
|
-
if (!
|
|
41989
|
+
var stylize = colors9.stylize = function stylize2(str, style) {
|
|
41990
|
+
if (!colors9.enabled) {
|
|
41921
41991
|
return str + "";
|
|
41922
41992
|
}
|
|
41923
41993
|
var styleMap = ansiStyles[style];
|
|
41924
|
-
if (!styleMap && style in
|
|
41925
|
-
return
|
|
41994
|
+
if (!styleMap && style in colors9) {
|
|
41995
|
+
return colors9[style](str);
|
|
41926
41996
|
}
|
|
41927
41997
|
return styleMap.open + str + styleMap.close;
|
|
41928
41998
|
};
|
|
@@ -41954,7 +42024,7 @@ var require_colors = __commonJS((exports, module) => {
|
|
|
41954
42024
|
});
|
|
41955
42025
|
return ret;
|
|
41956
42026
|
}();
|
|
41957
|
-
var proto = defineProps(function
|
|
42027
|
+
var proto = defineProps(function colors10() {}, styles);
|
|
41958
42028
|
function applyStyle() {
|
|
41959
42029
|
var args = Array.prototype.slice.call(arguments);
|
|
41960
42030
|
var str = args.map(function(arg) {
|
|
@@ -41964,7 +42034,7 @@ var require_colors = __commonJS((exports, module) => {
|
|
|
41964
42034
|
return util3.inspect(arg);
|
|
41965
42035
|
}
|
|
41966
42036
|
}).join(" ");
|
|
41967
|
-
if (!
|
|
42037
|
+
if (!colors9.enabled || !str) {
|
|
41968
42038
|
return str;
|
|
41969
42039
|
}
|
|
41970
42040
|
var newLinesPresent = str.indexOf(`
|
|
@@ -41982,22 +42052,22 @@ var require_colors = __commonJS((exports, module) => {
|
|
|
41982
42052
|
}
|
|
41983
42053
|
return str;
|
|
41984
42054
|
}
|
|
41985
|
-
|
|
42055
|
+
colors9.setTheme = function(theme) {
|
|
41986
42056
|
if (typeof theme === "string") {
|
|
41987
42057
|
console.log("colors.setTheme now only accepts an object, not a string. " + "If you are trying to set a theme from a file, it is now your (the " + "caller's) responsibility to require the file. The old syntax " + "looked like colors.setTheme(__dirname + " + "'/../themes/generic-logging.js'); The new syntax looks like " + "colors.setTheme(require(__dirname + " + "'/../themes/generic-logging.js'));");
|
|
41988
42058
|
return;
|
|
41989
42059
|
}
|
|
41990
42060
|
for (var style in theme) {
|
|
41991
42061
|
(function(style2) {
|
|
41992
|
-
|
|
42062
|
+
colors9[style2] = function(str) {
|
|
41993
42063
|
if (typeof theme[style2] === "object") {
|
|
41994
42064
|
var out = str;
|
|
41995
42065
|
for (var i in theme[style2]) {
|
|
41996
|
-
out =
|
|
42066
|
+
out = colors9[theme[style2][i]](out);
|
|
41997
42067
|
}
|
|
41998
42068
|
return out;
|
|
41999
42069
|
}
|
|
42000
|
-
return
|
|
42070
|
+
return colors9[theme[style2]](str);
|
|
42001
42071
|
};
|
|
42002
42072
|
})(style);
|
|
42003
42073
|
}
|
|
@@ -42018,28 +42088,28 @@ var require_colors = __commonJS((exports, module) => {
|
|
|
42018
42088
|
exploded = exploded.map(map2);
|
|
42019
42089
|
return exploded.join("");
|
|
42020
42090
|
};
|
|
42021
|
-
|
|
42022
|
-
|
|
42023
|
-
|
|
42024
|
-
|
|
42025
|
-
|
|
42026
|
-
|
|
42027
|
-
|
|
42028
|
-
for (map in
|
|
42091
|
+
colors9.trap = require_trap();
|
|
42092
|
+
colors9.zalgo = require_zalgo();
|
|
42093
|
+
colors9.maps = {};
|
|
42094
|
+
colors9.maps.america = require_america()(colors9);
|
|
42095
|
+
colors9.maps.zebra = require_zebra()(colors9);
|
|
42096
|
+
colors9.maps.rainbow = require_rainbow()(colors9);
|
|
42097
|
+
colors9.maps.random = require_random()(colors9);
|
|
42098
|
+
for (map in colors9.maps) {
|
|
42029
42099
|
(function(map2) {
|
|
42030
|
-
|
|
42031
|
-
return sequencer(
|
|
42100
|
+
colors9[map2] = function(str) {
|
|
42101
|
+
return sequencer(colors9.maps[map2], str);
|
|
42032
42102
|
};
|
|
42033
42103
|
})(map);
|
|
42034
42104
|
}
|
|
42035
42105
|
var map;
|
|
42036
|
-
defineProps(
|
|
42106
|
+
defineProps(colors9, init());
|
|
42037
42107
|
});
|
|
42038
42108
|
|
|
42039
42109
|
// node_modules/@colors/colors/safe.js
|
|
42040
42110
|
var require_safe = __commonJS((exports, module) => {
|
|
42041
|
-
var
|
|
42042
|
-
module["exports"] =
|
|
42111
|
+
var colors9 = require_colors();
|
|
42112
|
+
module["exports"] = colors9;
|
|
42043
42113
|
});
|
|
42044
42114
|
|
|
42045
42115
|
// node_modules/cli-table3/src/cell.js
|
|
@@ -42209,11 +42279,11 @@ var require_cell = __commonJS((exports, module) => {
|
|
|
42209
42279
|
wrapWithStyleColors(styleProperty, content) {
|
|
42210
42280
|
if (this[styleProperty] && this[styleProperty].length) {
|
|
42211
42281
|
try {
|
|
42212
|
-
let
|
|
42282
|
+
let colors9 = require_safe();
|
|
42213
42283
|
for (let i = this[styleProperty].length - 1;i >= 0; i--) {
|
|
42214
|
-
|
|
42284
|
+
colors9 = colors9[this[styleProperty][i]];
|
|
42215
42285
|
}
|
|
42216
|
-
return
|
|
42286
|
+
return colors9(content);
|
|
42217
42287
|
} catch (e) {
|
|
42218
42288
|
return content;
|
|
42219
42289
|
}
|
|
@@ -42758,7 +42828,7 @@ var {
|
|
|
42758
42828
|
// package.json
|
|
42759
42829
|
var package_default = {
|
|
42760
42830
|
name: "@carllee1983/dbcli",
|
|
42761
|
-
version: "0.
|
|
42831
|
+
version: "0.5.0-beta",
|
|
42762
42832
|
description: "Database CLI for AI agents",
|
|
42763
42833
|
type: "module",
|
|
42764
42834
|
publishConfig: {
|
|
@@ -42796,6 +42866,7 @@ var package_default = {
|
|
|
42796
42866
|
dotenv: "^16.3.1",
|
|
42797
42867
|
mysql2: "^3.20.0",
|
|
42798
42868
|
pg: "^8.20.0",
|
|
42869
|
+
picocolors: "^1.1.1",
|
|
42799
42870
|
zod: "^3.22.4"
|
|
42800
42871
|
},
|
|
42801
42872
|
devDependencies: {
|
|
@@ -43101,6 +43172,47 @@ var messageLoader = MessageLoader.getInstance();
|
|
|
43101
43172
|
var t = (key) => messageLoader.t(key);
|
|
43102
43173
|
var t_vars = (key, vars) => messageLoader.interpolate(key, vars);
|
|
43103
43174
|
|
|
43175
|
+
// src/utils/colors.ts
|
|
43176
|
+
var import_picocolors = __toESM(require_picocolors(), 1);
|
|
43177
|
+
var colors = {
|
|
43178
|
+
success: (text) => import_picocolors.default.green(text),
|
|
43179
|
+
error: (text) => import_picocolors.default.red(text),
|
|
43180
|
+
warn: (text) => import_picocolors.default.yellow(text),
|
|
43181
|
+
info: (text) => import_picocolors.default.blue(text),
|
|
43182
|
+
dim: (text) => import_picocolors.default.dim(text),
|
|
43183
|
+
bold: (text) => import_picocolors.default.bold(text),
|
|
43184
|
+
keyword: (text) => import_picocolors.default.blue(import_picocolors.default.bold(text))
|
|
43185
|
+
};
|
|
43186
|
+
|
|
43187
|
+
// src/utils/logger.ts
|
|
43188
|
+
function formatArgs(args) {
|
|
43189
|
+
return args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
|
|
43190
|
+
}
|
|
43191
|
+
function createLogger(level = 1 /* NORMAL */) {
|
|
43192
|
+
const write = (minLevel, prefix, args) => {
|
|
43193
|
+
if (level < minLevel)
|
|
43194
|
+
return;
|
|
43195
|
+
const message = `${prefix} ${formatArgs(args)}
|
|
43196
|
+
`;
|
|
43197
|
+
process.stderr.write(message);
|
|
43198
|
+
};
|
|
43199
|
+
return {
|
|
43200
|
+
error: (...args) => write(0 /* QUIET */, colors.error("[ERROR]"), args),
|
|
43201
|
+
warn: (...args) => write(1 /* NORMAL */, colors.warn("[WARN]"), args),
|
|
43202
|
+
info: (...args) => write(1 /* NORMAL */, colors.info("[INFO]"), args),
|
|
43203
|
+
verbose: (...args) => write(2 /* VERBOSE */, colors.dim("[VERBOSE]"), args),
|
|
43204
|
+
debug: (...args) => write(3 /* DEBUG */, colors.dim("[DEBUG]"), args),
|
|
43205
|
+
level
|
|
43206
|
+
};
|
|
43207
|
+
}
|
|
43208
|
+
var globalLogger = createLogger(1 /* NORMAL */);
|
|
43209
|
+
function setGlobalLogger(logger) {
|
|
43210
|
+
globalLogger = logger;
|
|
43211
|
+
}
|
|
43212
|
+
function getLogger() {
|
|
43213
|
+
return globalLogger;
|
|
43214
|
+
}
|
|
43215
|
+
|
|
43104
43216
|
// src/utils/errors.ts
|
|
43105
43217
|
class EnvParseError extends Error {
|
|
43106
43218
|
constructor(message) {
|
|
@@ -48210,7 +48322,7 @@ var Table = require_table();
|
|
|
48210
48322
|
class TableFormatter {
|
|
48211
48323
|
format(columns) {
|
|
48212
48324
|
const table = new Table({
|
|
48213
|
-
head: ["Column", "Type", "Nullable", "Default", "Key"],
|
|
48325
|
+
head: ["Column", "Type", "Nullable", "Default", "Key"].map((h) => colors.bold(h)),
|
|
48214
48326
|
style: { compact: false, "padding-left": 1, "padding-right": 1 },
|
|
48215
48327
|
colWidths: [25, 25, 10, 25, 20]
|
|
48216
48328
|
});
|
|
@@ -48236,7 +48348,7 @@ class TableFormatter {
|
|
|
48236
48348
|
class TableListFormatter {
|
|
48237
48349
|
format(tables) {
|
|
48238
48350
|
const table = new Table({
|
|
48239
|
-
head: ["Table", "Columns", "Rows", "Engine"],
|
|
48351
|
+
head: ["Table", "Columns", "Rows", "Engine"].map((h) => colors.bold(h)),
|
|
48240
48352
|
style: { compact: false, "padding-left": 1, "padding-right": 1 },
|
|
48241
48353
|
colWidths: [30, 12, 15, 15]
|
|
48242
48354
|
});
|
|
@@ -50824,8 +50936,637 @@ var statusCommand = new Command("status").description("Show current configuratio
|
|
|
50824
50936
|
}
|
|
50825
50937
|
});
|
|
50826
50938
|
|
|
50939
|
+
// src/commands/doctor.ts
|
|
50940
|
+
import { join as join3 } from "path";
|
|
50941
|
+
var SENSITIVE_PATTERNS = [
|
|
50942
|
+
"password",
|
|
50943
|
+
"passwd",
|
|
50944
|
+
"secret",
|
|
50945
|
+
"token",
|
|
50946
|
+
"api_key",
|
|
50947
|
+
"apikey",
|
|
50948
|
+
"access_key",
|
|
50949
|
+
"private_key",
|
|
50950
|
+
"credential",
|
|
50951
|
+
"auth_token",
|
|
50952
|
+
"refresh_token",
|
|
50953
|
+
"session_token",
|
|
50954
|
+
"ssn",
|
|
50955
|
+
"credit_card"
|
|
50956
|
+
];
|
|
50957
|
+
function compareSemver(a, b) {
|
|
50958
|
+
const pa = a.split(".").map(Number);
|
|
50959
|
+
const pb = b.split(".").map(Number);
|
|
50960
|
+
for (let i = 0;i < 3; i++) {
|
|
50961
|
+
const diff = (pa[i] ?? 0) - (pb[i] ?? 0);
|
|
50962
|
+
if (diff !== 0)
|
|
50963
|
+
return diff;
|
|
50964
|
+
}
|
|
50965
|
+
return 0;
|
|
50966
|
+
}
|
|
50967
|
+
var runDoctorChecks = {
|
|
50968
|
+
checkBunVersion(current, required) {
|
|
50969
|
+
const passes = compareSemver(current, required) >= 0;
|
|
50970
|
+
return {
|
|
50971
|
+
group: "Environment",
|
|
50972
|
+
label: "Bun version",
|
|
50973
|
+
status: passes ? "pass" : "error",
|
|
50974
|
+
message: passes ? `Bun v${current} (meets >= ${required})` : `Bun v${current} is below required >= ${required}`
|
|
50975
|
+
};
|
|
50976
|
+
},
|
|
50977
|
+
async checkLatestVersion(currentVersion) {
|
|
50978
|
+
try {
|
|
50979
|
+
const response = await fetch("https://registry.npmjs.org/@carllee1983/dbcli/latest", { signal: AbortSignal.timeout(5000) });
|
|
50980
|
+
if (!response.ok)
|
|
50981
|
+
throw new Error(`HTTP ${response.status}`);
|
|
50982
|
+
const data = await response.json();
|
|
50983
|
+
const latest = data.version;
|
|
50984
|
+
const isLatest = currentVersion === latest;
|
|
50985
|
+
return {
|
|
50986
|
+
group: "Environment",
|
|
50987
|
+
label: "dbcli version",
|
|
50988
|
+
status: isLatest ? "pass" : "warn",
|
|
50989
|
+
message: isLatest ? `dbcli v${currentVersion} (latest)` : `dbcli v${currentVersion} (latest: ${latest})`
|
|
50990
|
+
};
|
|
50991
|
+
} catch {
|
|
50992
|
+
return {
|
|
50993
|
+
group: "Environment",
|
|
50994
|
+
label: "dbcli version",
|
|
50995
|
+
status: "pass",
|
|
50996
|
+
message: `dbcli v${currentVersion} (version check skipped)`
|
|
50997
|
+
};
|
|
50998
|
+
}
|
|
50999
|
+
},
|
|
51000
|
+
async checkConfigExists(configPath, existsFn) {
|
|
51001
|
+
const exists = existsFn ? await existsFn(configPath) : await Bun.file(configPath).exists() || await Bun.file(join3(configPath, "config.json")).exists();
|
|
51002
|
+
return {
|
|
51003
|
+
group: "Configuration",
|
|
51004
|
+
label: "Config exists",
|
|
51005
|
+
status: exists ? "pass" : "error",
|
|
51006
|
+
message: exists ? `Config found: ${configPath}` : `No config found at ${configPath}. Run "dbcli init" first.`
|
|
51007
|
+
};
|
|
51008
|
+
},
|
|
51009
|
+
checkBlacklistCompleteness(tableColumns, blacklistedColumns) {
|
|
51010
|
+
const unprotected = [];
|
|
51011
|
+
for (const [table, columns] of tableColumns) {
|
|
51012
|
+
const blacklisted = blacklistedColumns.get(table) ?? new Set;
|
|
51013
|
+
for (const col of columns) {
|
|
51014
|
+
const colLower = col.toLowerCase();
|
|
51015
|
+
const isSensitive = SENSITIVE_PATTERNS.some((p) => colLower.includes(p));
|
|
51016
|
+
if (isSensitive && !blacklisted.has(col)) {
|
|
51017
|
+
unprotected.push(`${table}.${col}`);
|
|
51018
|
+
}
|
|
51019
|
+
}
|
|
51020
|
+
}
|
|
51021
|
+
if (unprotected.length === 0) {
|
|
51022
|
+
return {
|
|
51023
|
+
group: "Configuration",
|
|
51024
|
+
label: "Blacklist completeness",
|
|
51025
|
+
status: "pass",
|
|
51026
|
+
message: "All detected sensitive columns are protected"
|
|
51027
|
+
};
|
|
51028
|
+
}
|
|
51029
|
+
return {
|
|
51030
|
+
group: "Configuration",
|
|
51031
|
+
label: "Blacklist completeness",
|
|
51032
|
+
status: "warn",
|
|
51033
|
+
message: `Consider protecting: ${unprotected.join(", ")}`
|
|
51034
|
+
};
|
|
51035
|
+
},
|
|
51036
|
+
checkSchemaCacheFreshness(lastUpdated) {
|
|
51037
|
+
if (!lastUpdated) {
|
|
51038
|
+
return {
|
|
51039
|
+
group: "Connection & Data",
|
|
51040
|
+
label: "Schema cache",
|
|
51041
|
+
status: "warn",
|
|
51042
|
+
message: 'No schema cache found \u2014 run "dbcli schema --refresh"'
|
|
51043
|
+
};
|
|
51044
|
+
}
|
|
51045
|
+
const ageMs = Date.now() - new Date(lastUpdated).getTime();
|
|
51046
|
+
const ageDays = Math.floor(ageMs / (24 * 60 * 60 * 1000));
|
|
51047
|
+
if (ageDays > 7) {
|
|
51048
|
+
return {
|
|
51049
|
+
group: "Connection & Data",
|
|
51050
|
+
label: "Schema cache",
|
|
51051
|
+
status: "warn",
|
|
51052
|
+
message: `Schema cache is ${ageDays} days old \u2014 run "dbcli schema --refresh"`
|
|
51053
|
+
};
|
|
51054
|
+
}
|
|
51055
|
+
return {
|
|
51056
|
+
group: "Connection & Data",
|
|
51057
|
+
label: "Schema cache",
|
|
51058
|
+
status: "pass",
|
|
51059
|
+
message: `Schema cache is ${ageDays} day(s) old`
|
|
51060
|
+
};
|
|
51061
|
+
},
|
|
51062
|
+
checkLargeTables(tables) {
|
|
51063
|
+
const large = tables.filter((t7) => (t7.estimatedRowCount ?? 0) > 1e6);
|
|
51064
|
+
if (large.length === 0) {
|
|
51065
|
+
return {
|
|
51066
|
+
group: "Connection & Data",
|
|
51067
|
+
label: "Large tables",
|
|
51068
|
+
status: "pass",
|
|
51069
|
+
message: "No tables exceed 1M rows"
|
|
51070
|
+
};
|
|
51071
|
+
}
|
|
51072
|
+
const list = large.map((t7) => `${t7.name} (${((t7.estimatedRowCount ?? 0) / 1e6).toFixed(1)}M rows)`).join(", ");
|
|
51073
|
+
return {
|
|
51074
|
+
group: "Connection & Data",
|
|
51075
|
+
label: "Large tables",
|
|
51076
|
+
status: "warn",
|
|
51077
|
+
message: `Large tables: ${list}`
|
|
51078
|
+
};
|
|
51079
|
+
},
|
|
51080
|
+
formatTextOutput(results, version) {
|
|
51081
|
+
const lines2 = [`dbcli doctor v${version}`, ""];
|
|
51082
|
+
const groups = ["Environment", "Configuration", "Connection & Data"];
|
|
51083
|
+
for (const group of groups) {
|
|
51084
|
+
const groupResults = results.filter((r) => r.group === group);
|
|
51085
|
+
if (groupResults.length === 0)
|
|
51086
|
+
continue;
|
|
51087
|
+
lines2.push(group);
|
|
51088
|
+
for (const r of groupResults) {
|
|
51089
|
+
const icon = r.status === "pass" ? colors.success("\u2713") : r.status === "warn" ? colors.warn("\u26A0") : colors.error("\u2717");
|
|
51090
|
+
lines2.push(` ${icon} ${r.message}`);
|
|
51091
|
+
}
|
|
51092
|
+
lines2.push("");
|
|
51093
|
+
}
|
|
51094
|
+
const passed = results.filter((r) => r.status === "pass").length;
|
|
51095
|
+
const warnings = results.filter((r) => r.status === "warn").length;
|
|
51096
|
+
const errors3 = results.filter((r) => r.status === "error").length;
|
|
51097
|
+
lines2.push(`Summary: ${passed} passed, ${warnings} warning(s), ${errors3} error(s)`);
|
|
51098
|
+
return lines2.join(`
|
|
51099
|
+
`);
|
|
51100
|
+
}
|
|
51101
|
+
};
|
|
51102
|
+
var doctorCommand = new Command("doctor").description("Run diagnostic checks on dbcli configuration, environment, and connection").option("--format <type>", "Output format: text, json", "text").action(async (options) => {
|
|
51103
|
+
const logger = getLogger();
|
|
51104
|
+
const results = [];
|
|
51105
|
+
const configPath = doctorCommand.parent?.opts().config ?? ".dbcli";
|
|
51106
|
+
const bunVersion = process.versions.bun ?? "unknown";
|
|
51107
|
+
const requiredBun = package_default.engines?.bun?.replace(">=", "") ?? "1.3.3";
|
|
51108
|
+
results.push(runDoctorChecks.checkBunVersion(bunVersion, requiredBun));
|
|
51109
|
+
results.push(await runDoctorChecks.checkLatestVersion(package_default.version));
|
|
51110
|
+
const configExists = await runDoctorChecks.checkConfigExists(configPath);
|
|
51111
|
+
results.push(configExists);
|
|
51112
|
+
if (configExists.status !== "error") {
|
|
51113
|
+
try {
|
|
51114
|
+
const config = await configModule.read(configPath);
|
|
51115
|
+
results.push({
|
|
51116
|
+
group: "Configuration",
|
|
51117
|
+
label: "Config valid",
|
|
51118
|
+
status: "pass",
|
|
51119
|
+
message: "Config valid"
|
|
51120
|
+
});
|
|
51121
|
+
results.push({
|
|
51122
|
+
group: "Configuration",
|
|
51123
|
+
label: "Permission",
|
|
51124
|
+
status: "pass",
|
|
51125
|
+
message: `Permission: ${config.permission}`
|
|
51126
|
+
});
|
|
51127
|
+
const blacklistedColumns = new Map;
|
|
51128
|
+
if (config.blacklist?.columns) {
|
|
51129
|
+
for (const [table, cols] of Object.entries(config.blacklist.columns)) {
|
|
51130
|
+
blacklistedColumns.set(table, new Set(cols));
|
|
51131
|
+
}
|
|
51132
|
+
}
|
|
51133
|
+
try {
|
|
51134
|
+
const adapter = AdapterFactory.createAdapter(config.connection);
|
|
51135
|
+
await adapter.connect();
|
|
51136
|
+
results.push({
|
|
51137
|
+
group: "Connection & Data",
|
|
51138
|
+
label: "Connection",
|
|
51139
|
+
status: "pass",
|
|
51140
|
+
message: `Connected to ${config.connection.system} ${config.connection.database}@${config.connection.host}:${config.connection.port}`
|
|
51141
|
+
});
|
|
51142
|
+
try {
|
|
51143
|
+
const tables = await adapter.listTables();
|
|
51144
|
+
const tableColumns = new Map;
|
|
51145
|
+
for (const t7 of tables) {
|
|
51146
|
+
tableColumns.set(t7.name, t7.columns.map((c) => c.name));
|
|
51147
|
+
}
|
|
51148
|
+
results.push(runDoctorChecks.checkBlacklistCompleteness(tableColumns, blacklistedColumns));
|
|
51149
|
+
results.push(runDoctorChecks.checkLargeTables(tables));
|
|
51150
|
+
} catch {
|
|
51151
|
+
logger.debug("Could not list tables for blacklist/large table check");
|
|
51152
|
+
}
|
|
51153
|
+
try {
|
|
51154
|
+
const indexPath = join3(configPath, "schemas", "index.json");
|
|
51155
|
+
const indexFile = Bun.file(indexPath);
|
|
51156
|
+
if (await indexFile.exists()) {
|
|
51157
|
+
const indexContent = await indexFile.text();
|
|
51158
|
+
const index = JSON.parse(indexContent);
|
|
51159
|
+
results.push(runDoctorChecks.checkSchemaCacheFreshness(index.updatedAt ?? null));
|
|
51160
|
+
} else {
|
|
51161
|
+
results.push(runDoctorChecks.checkSchemaCacheFreshness(null));
|
|
51162
|
+
}
|
|
51163
|
+
} catch {
|
|
51164
|
+
results.push(runDoctorChecks.checkSchemaCacheFreshness(null));
|
|
51165
|
+
}
|
|
51166
|
+
await adapter.disconnect();
|
|
51167
|
+
} catch (error) {
|
|
51168
|
+
results.push({
|
|
51169
|
+
group: "Connection & Data",
|
|
51170
|
+
label: "Connection",
|
|
51171
|
+
status: "error",
|
|
51172
|
+
message: `Connection failed: ${error.message}`
|
|
51173
|
+
});
|
|
51174
|
+
}
|
|
51175
|
+
} catch (error) {
|
|
51176
|
+
results.push({
|
|
51177
|
+
group: "Configuration",
|
|
51178
|
+
label: "Config valid",
|
|
51179
|
+
status: "error",
|
|
51180
|
+
message: `Config invalid: ${error.message}`
|
|
51181
|
+
});
|
|
51182
|
+
}
|
|
51183
|
+
}
|
|
51184
|
+
const hasError = results.some((r) => r.status === "error");
|
|
51185
|
+
if (options.format === "json") {
|
|
51186
|
+
console.log(JSON.stringify({ results, hasError }, null, 2));
|
|
51187
|
+
} else {
|
|
51188
|
+
console.log(runDoctorChecks.formatTextOutput(results, package_default.version));
|
|
51189
|
+
}
|
|
51190
|
+
if (hasError) {
|
|
51191
|
+
process.exit(1);
|
|
51192
|
+
}
|
|
51193
|
+
});
|
|
51194
|
+
|
|
51195
|
+
// src/commands/completion.ts
|
|
51196
|
+
import { join as join4 } from "path";
|
|
51197
|
+
import { homedir as homedir2 } from "os";
|
|
51198
|
+
function extractCommands(program2) {
|
|
51199
|
+
return program2.commands.map((cmd) => ({
|
|
51200
|
+
name: cmd.name(),
|
|
51201
|
+
options: cmd.options.map((o) => o.long ?? o.short ?? "").filter(Boolean)
|
|
51202
|
+
}));
|
|
51203
|
+
}
|
|
51204
|
+
function extractGlobalOptions(program2) {
|
|
51205
|
+
return program2.options.map((o) => o.long ?? o.short ?? "").filter(Boolean);
|
|
51206
|
+
}
|
|
51207
|
+
function generateBashCompletion(commands, globalOptions) {
|
|
51208
|
+
const cmdNames = commands.map((c) => c.name).join(" ");
|
|
51209
|
+
const globalOpts = globalOptions.join(" ");
|
|
51210
|
+
const caseEntries = commands.map((c) => ` ${c.name})
|
|
51211
|
+
COMPREPLY=( $(compgen -W "${c.options.join(" ")}" -- "\${cur}") )
|
|
51212
|
+
;;`).join(`
|
|
51213
|
+
`);
|
|
51214
|
+
return `#!/bin/bash
|
|
51215
|
+
# dbcli bash completion \u2014 auto-generated, do not edit
|
|
51216
|
+
_dbcli_completions() {
|
|
51217
|
+
local cur prev commands
|
|
51218
|
+
cur="\${COMP_WORDS[COMP_CWORD]}"
|
|
51219
|
+
prev="\${COMP_WORDS[COMP_CWORD-1]}"
|
|
51220
|
+
commands="${cmdNames}"
|
|
51221
|
+
|
|
51222
|
+
if [[ \${COMP_CWORD} -eq 1 ]]; then
|
|
51223
|
+
COMPREPLY=( $(compgen -W "\${commands} ${globalOpts}" -- "\${cur}") )
|
|
51224
|
+
return 0
|
|
51225
|
+
fi
|
|
51226
|
+
|
|
51227
|
+
case "\${COMP_WORDS[1]}" in
|
|
51228
|
+
${caseEntries}
|
|
51229
|
+
*)
|
|
51230
|
+
COMPREPLY=( $(compgen -W "${globalOpts}" -- "\${cur}") )
|
|
51231
|
+
;;
|
|
51232
|
+
esac
|
|
51233
|
+
}
|
|
51234
|
+
complete -F _dbcli_completions dbcli
|
|
51235
|
+
`;
|
|
51236
|
+
}
|
|
51237
|
+
function generateZshCompletion(commands, globalOptions) {
|
|
51238
|
+
const cmdLines = commands.map((c) => ` '${c.name}:${c.name} command'`).join(`
|
|
51239
|
+
`);
|
|
51240
|
+
const subcmdCases = commands.map((c) => {
|
|
51241
|
+
const opts = c.options.map((o) => `'${o}[${o}]'`).join(" ");
|
|
51242
|
+
return ` ${c.name})
|
|
51243
|
+
_arguments ${opts}
|
|
51244
|
+
;;`;
|
|
51245
|
+
}).join(`
|
|
51246
|
+
`);
|
|
51247
|
+
const globalOpts = globalOptions.map((o) => `'${o}[${o}]'`).join(" ");
|
|
51248
|
+
return `#compdef dbcli
|
|
51249
|
+
# dbcli zsh completion \u2014 auto-generated, do not edit
|
|
51250
|
+
_dbcli() {
|
|
51251
|
+
local -a commands
|
|
51252
|
+
commands=(
|
|
51253
|
+
${cmdLines}
|
|
51254
|
+
)
|
|
51255
|
+
|
|
51256
|
+
_arguments -C \\
|
|
51257
|
+
${globalOpts} \\
|
|
51258
|
+
'1:command:->cmd' \\
|
|
51259
|
+
'*::arg:->args'
|
|
51260
|
+
|
|
51261
|
+
case "$state" in
|
|
51262
|
+
cmd)
|
|
51263
|
+
_describe 'command' commands
|
|
51264
|
+
;;
|
|
51265
|
+
args)
|
|
51266
|
+
case "$words[1]" in
|
|
51267
|
+
${subcmdCases}
|
|
51268
|
+
esac
|
|
51269
|
+
;;
|
|
51270
|
+
esac
|
|
51271
|
+
}
|
|
51272
|
+
_dbcli
|
|
51273
|
+
`;
|
|
51274
|
+
}
|
|
51275
|
+
function generateFishCompletion(commands, globalOptions) {
|
|
51276
|
+
const lines2 = [
|
|
51277
|
+
"# dbcli fish completion \u2014 auto-generated, do not edit",
|
|
51278
|
+
""
|
|
51279
|
+
];
|
|
51280
|
+
for (const opt of globalOptions) {
|
|
51281
|
+
const longName = opt.replace(/^--/, "");
|
|
51282
|
+
lines2.push(`complete -c dbcli -n '__fish_use_subcommand' -l ${longName} -d '${opt}'`);
|
|
51283
|
+
}
|
|
51284
|
+
for (const cmd of commands) {
|
|
51285
|
+
lines2.push(`complete -c dbcli -n '__fish_use_subcommand' -a ${cmd.name} -d '${cmd.name} command'`);
|
|
51286
|
+
}
|
|
51287
|
+
for (const cmd of commands) {
|
|
51288
|
+
for (const opt of cmd.options) {
|
|
51289
|
+
const longName = opt.replace(/^--/, "");
|
|
51290
|
+
lines2.push(`complete -c dbcli -n '__fish_seen_subcommand_from ${cmd.name}' -l ${longName} -d '${opt}'`);
|
|
51291
|
+
}
|
|
51292
|
+
}
|
|
51293
|
+
return lines2.join(`
|
|
51294
|
+
`) + `
|
|
51295
|
+
`;
|
|
51296
|
+
}
|
|
51297
|
+
function getInstallPath2(shell) {
|
|
51298
|
+
const home = homedir2();
|
|
51299
|
+
switch (shell) {
|
|
51300
|
+
case "bash":
|
|
51301
|
+
return join4(home, ".bashrc");
|
|
51302
|
+
case "zsh":
|
|
51303
|
+
return join4(home, ".zshrc");
|
|
51304
|
+
case "fish":
|
|
51305
|
+
return join4(home, ".config", "fish", "completions", "dbcli.fish");
|
|
51306
|
+
default:
|
|
51307
|
+
throw new Error(`Unsupported shell: ${shell}. Supported: bash, zsh, fish`);
|
|
51308
|
+
}
|
|
51309
|
+
}
|
|
51310
|
+
function detectShell() {
|
|
51311
|
+
const shellEnv = process.env.SHELL ?? "";
|
|
51312
|
+
if (shellEnv.includes("zsh"))
|
|
51313
|
+
return "zsh";
|
|
51314
|
+
if (shellEnv.includes("bash"))
|
|
51315
|
+
return "bash";
|
|
51316
|
+
if (shellEnv.includes("fish"))
|
|
51317
|
+
return "fish";
|
|
51318
|
+
return "bash";
|
|
51319
|
+
}
|
|
51320
|
+
var MARKER_START = "# >>> dbcli completion >>>";
|
|
51321
|
+
var MARKER_END = "# <<< dbcli completion <<<";
|
|
51322
|
+
async function installCompletion(shell, script) {
|
|
51323
|
+
const targetPath = getInstallPath2(shell);
|
|
51324
|
+
if (shell === "fish") {
|
|
51325
|
+
const dir = join4(homedir2(), ".config", "fish", "completions");
|
|
51326
|
+
await Bun.$`mkdir -p ${dir}`.quiet();
|
|
51327
|
+
await Bun.file(targetPath).write(script);
|
|
51328
|
+
console.log(colors.success(`\u2713 Fish completion installed to ${targetPath}`));
|
|
51329
|
+
return;
|
|
51330
|
+
}
|
|
51331
|
+
const file = Bun.file(targetPath);
|
|
51332
|
+
let content = "";
|
|
51333
|
+
if (await file.exists()) {
|
|
51334
|
+
content = await file.text();
|
|
51335
|
+
}
|
|
51336
|
+
const markerRegex = new RegExp(`${MARKER_START}[\\s\\S]*?${MARKER_END}\\n?`, "g");
|
|
51337
|
+
content = content.replace(markerRegex, "");
|
|
51338
|
+
const block = `
|
|
51339
|
+
${MARKER_START}
|
|
51340
|
+
eval "$(dbcli completion ${shell})"
|
|
51341
|
+
${MARKER_END}
|
|
51342
|
+
`;
|
|
51343
|
+
content = content.trimEnd() + `
|
|
51344
|
+
` + block;
|
|
51345
|
+
await Bun.file(targetPath).write(content);
|
|
51346
|
+
console.log(colors.success(`\u2713 Completion installed to ${targetPath}`));
|
|
51347
|
+
console.log(colors.info(` Run: source ${targetPath}`));
|
|
51348
|
+
}
|
|
51349
|
+
var completionCommand = new Command("completion").description("Generate shell completion scripts (bash, zsh, fish)").argument("[shell]", "Shell type: bash, zsh, fish").option("--install [shell]", "Auto-install completion to shell rc file").action(async (shellArg, options) => {
|
|
51350
|
+
const parentProgram = completionCommand.parent;
|
|
51351
|
+
if (!parentProgram) {
|
|
51352
|
+
console.error(colors.error("Error: completion command must be registered to a program"));
|
|
51353
|
+
process.exit(1);
|
|
51354
|
+
}
|
|
51355
|
+
const commands = extractCommands(parentProgram);
|
|
51356
|
+
const globalOptions = extractGlobalOptions(parentProgram);
|
|
51357
|
+
if (options.install !== undefined) {
|
|
51358
|
+
const shell2 = typeof options.install === "string" ? options.install : shellArg ?? detectShell();
|
|
51359
|
+
const generators2 = {
|
|
51360
|
+
bash: generateBashCompletion,
|
|
51361
|
+
zsh: generateZshCompletion,
|
|
51362
|
+
fish: generateFishCompletion
|
|
51363
|
+
};
|
|
51364
|
+
const generate2 = generators2[shell2];
|
|
51365
|
+
if (!generate2) {
|
|
51366
|
+
console.error(colors.error(`Unsupported shell: ${shell2}. Supported: bash, zsh, fish`));
|
|
51367
|
+
process.exit(1);
|
|
51368
|
+
}
|
|
51369
|
+
const script = generate2(commands, globalOptions);
|
|
51370
|
+
await installCompletion(shell2, script);
|
|
51371
|
+
return;
|
|
51372
|
+
}
|
|
51373
|
+
const shell = shellArg ?? detectShell();
|
|
51374
|
+
const generators = {
|
|
51375
|
+
bash: generateBashCompletion,
|
|
51376
|
+
zsh: generateZshCompletion,
|
|
51377
|
+
fish: generateFishCompletion
|
|
51378
|
+
};
|
|
51379
|
+
const generate = generators[shell];
|
|
51380
|
+
if (!generate) {
|
|
51381
|
+
console.error(colors.error(`Unsupported shell: ${shell}. Supported: bash, zsh, fish`));
|
|
51382
|
+
process.exit(1);
|
|
51383
|
+
}
|
|
51384
|
+
process.stdout.write(generate(commands, globalOptions));
|
|
51385
|
+
});
|
|
51386
|
+
|
|
51387
|
+
// src/utils/version-check.ts
|
|
51388
|
+
var NPM_REGISTRY_URL = "https://registry.npmjs.org/@carllee1983/dbcli/latest";
|
|
51389
|
+
var STALE_THRESHOLD_MS = 24 * 60 * 60 * 1000;
|
|
51390
|
+
var FETCH_TIMEOUT_MS = 3000;
|
|
51391
|
+
function compareVersions(a, b) {
|
|
51392
|
+
const stripSuffix = (v) => v.replace(/-.*$/, "");
|
|
51393
|
+
const pa = stripSuffix(a).split(".").map(Number);
|
|
51394
|
+
const pb = stripSuffix(b).split(".").map(Number);
|
|
51395
|
+
for (let i = 0;i < 3; i++) {
|
|
51396
|
+
const diff = (pa[i] ?? 0) - (pb[i] ?? 0);
|
|
51397
|
+
if (diff !== 0)
|
|
51398
|
+
return diff;
|
|
51399
|
+
}
|
|
51400
|
+
if (a === b)
|
|
51401
|
+
return 0;
|
|
51402
|
+
const aHasSuffix = a.includes("-");
|
|
51403
|
+
const bHasSuffix = b.includes("-");
|
|
51404
|
+
if (!aHasSuffix && bHasSuffix)
|
|
51405
|
+
return 1;
|
|
51406
|
+
if (aHasSuffix && !bHasSuffix)
|
|
51407
|
+
return -1;
|
|
51408
|
+
return a.localeCompare(b);
|
|
51409
|
+
}
|
|
51410
|
+
function isStale(checkedAt) {
|
|
51411
|
+
const checked = new Date(checkedAt).getTime();
|
|
51412
|
+
if (isNaN(checked))
|
|
51413
|
+
return true;
|
|
51414
|
+
return Date.now() - checked >= STALE_THRESHOLD_MS;
|
|
51415
|
+
}
|
|
51416
|
+
async function fetchLatestVersion() {
|
|
51417
|
+
try {
|
|
51418
|
+
const response = await fetch(NPM_REGISTRY_URL, {
|
|
51419
|
+
signal: AbortSignal.timeout(FETCH_TIMEOUT_MS)
|
|
51420
|
+
});
|
|
51421
|
+
if (!response.ok)
|
|
51422
|
+
return null;
|
|
51423
|
+
const data = await response.json();
|
|
51424
|
+
return data.version ?? null;
|
|
51425
|
+
} catch {
|
|
51426
|
+
return null;
|
|
51427
|
+
}
|
|
51428
|
+
}
|
|
51429
|
+
async function checkForUpdate(currentVersion, cachePath, existingCache) {
|
|
51430
|
+
let cache = existingCache ?? null;
|
|
51431
|
+
if (cache === undefined && cachePath) {
|
|
51432
|
+
try {
|
|
51433
|
+
const cacheFile = Bun.file(`${cachePath}/version-check.json`);
|
|
51434
|
+
if (await cacheFile.exists()) {
|
|
51435
|
+
cache = await cacheFile.json();
|
|
51436
|
+
}
|
|
51437
|
+
} catch {
|
|
51438
|
+
cache = null;
|
|
51439
|
+
}
|
|
51440
|
+
}
|
|
51441
|
+
if (cache && !isStale(cache.checkedAt)) {
|
|
51442
|
+
return {
|
|
51443
|
+
hasUpdate: compareVersions(cache.latestVersion, currentVersion) > 0,
|
|
51444
|
+
latestVersion: cache.latestVersion
|
|
51445
|
+
};
|
|
51446
|
+
}
|
|
51447
|
+
const latestVersion = await fetchLatestVersion();
|
|
51448
|
+
if (!latestVersion)
|
|
51449
|
+
return null;
|
|
51450
|
+
if (cachePath) {
|
|
51451
|
+
try {
|
|
51452
|
+
const newCache = {
|
|
51453
|
+
latestVersion,
|
|
51454
|
+
checkedAt: new Date().toISOString()
|
|
51455
|
+
};
|
|
51456
|
+
await Bun.write(`${cachePath}/version-check.json`, JSON.stringify(newCache, null, 2));
|
|
51457
|
+
} catch {}
|
|
51458
|
+
}
|
|
51459
|
+
return {
|
|
51460
|
+
hasUpdate: compareVersions(latestVersion, currentVersion) > 0,
|
|
51461
|
+
latestVersion
|
|
51462
|
+
};
|
|
51463
|
+
}
|
|
51464
|
+
|
|
51465
|
+
// src/commands/upgrade.ts
|
|
51466
|
+
function formatAlreadyUpToDate(version) {
|
|
51467
|
+
return colors.success(`\u2713 Already up to date (v${version})`);
|
|
51468
|
+
}
|
|
51469
|
+
function formatUpgradeMessage(currentVersion, latestVersion) {
|
|
51470
|
+
return [
|
|
51471
|
+
colors.info(` Current version : v${currentVersion}`),
|
|
51472
|
+
colors.success(` Latest version : v${latestVersion}`)
|
|
51473
|
+
].join(`
|
|
51474
|
+
`);
|
|
51475
|
+
}
|
|
51476
|
+
function formatUpdateHint(latestVersion) {
|
|
51477
|
+
return colors.warn(`[INFO] dbcli v${latestVersion} available. Run "dbcli upgrade" to upgrade.`);
|
|
51478
|
+
}
|
|
51479
|
+
var upgradeCommand = new Command("upgrade").description("Check for updates and upgrade dbcli to the latest version").option("--check", "Only check for updates, do not upgrade").action(async (options) => {
|
|
51480
|
+
const configPath = upgradeCommand.parent?.opts().config ?? ".dbcli";
|
|
51481
|
+
const currentVersion = package_default.version;
|
|
51482
|
+
console.log(colors.bold("Checking for updates..."));
|
|
51483
|
+
let cachePath = null;
|
|
51484
|
+
try {
|
|
51485
|
+
const file = Bun.file(configPath);
|
|
51486
|
+
const isDir = !configPath.includes(".") || await file.exists() === false;
|
|
51487
|
+
if (isDir) {
|
|
51488
|
+
cachePath = configPath;
|
|
51489
|
+
}
|
|
51490
|
+
} catch {
|
|
51491
|
+
cachePath = null;
|
|
51492
|
+
}
|
|
51493
|
+
const result = await checkForUpdate(currentVersion, cachePath);
|
|
51494
|
+
if (!result) {
|
|
51495
|
+
console.error(colors.warn("\u26A0 Could not check for updates (network error or registry unavailable)"));
|
|
51496
|
+
process.exit(0);
|
|
51497
|
+
}
|
|
51498
|
+
if (!result.hasUpdate) {
|
|
51499
|
+
console.log(formatAlreadyUpToDate(currentVersion));
|
|
51500
|
+
process.exit(0);
|
|
51501
|
+
}
|
|
51502
|
+
console.log(colors.warn(`
|
|
51503
|
+
New version available: v${result.latestVersion}`));
|
|
51504
|
+
console.log(formatUpgradeMessage(currentVersion, result.latestVersion));
|
|
51505
|
+
console.log();
|
|
51506
|
+
if (options.check) {
|
|
51507
|
+
console.log(colors.dim(' Run "dbcli upgrade" to install the update.'));
|
|
51508
|
+
process.exit(0);
|
|
51509
|
+
}
|
|
51510
|
+
console.log(colors.bold("Upgrading..."));
|
|
51511
|
+
console.log(colors.dim(` bun add -g @carllee1983/dbcli@latest`));
|
|
51512
|
+
console.log();
|
|
51513
|
+
const proc = Bun.$`bun add -g @carllee1983/dbcli@latest`.nothrow();
|
|
51514
|
+
const result2 = await proc;
|
|
51515
|
+
if (result2.exitCode === 0) {
|
|
51516
|
+
console.log(colors.success(`
|
|
51517
|
+
\u2713 Successfully upgraded to v${result.latestVersion}`));
|
|
51518
|
+
} else {
|
|
51519
|
+
console.error(colors.error(`
|
|
51520
|
+
\u2717 Upgrade failed. Try running manually:`));
|
|
51521
|
+
console.error(colors.dim(" bun add -g @carllee1983/dbcli@latest"));
|
|
51522
|
+
process.exit(1);
|
|
51523
|
+
}
|
|
51524
|
+
});
|
|
51525
|
+
|
|
50827
51526
|
// src/cli.ts
|
|
50828
|
-
|
|
51527
|
+
import { join as join5 } from "path";
|
|
51528
|
+
var _bgVersionCheckResult;
|
|
51529
|
+
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");
|
|
51530
|
+
program2.hook("preAction", (thisCommand, actionCommand) => {
|
|
51531
|
+
const opts = thisCommand.opts();
|
|
51532
|
+
if (opts.color === false) {
|
|
51533
|
+
process.env.NO_COLOR = "1";
|
|
51534
|
+
}
|
|
51535
|
+
let level = 1 /* NORMAL */;
|
|
51536
|
+
if (opts.quiet) {
|
|
51537
|
+
level = 0 /* QUIET */;
|
|
51538
|
+
} else if (opts.verbose >= 2) {
|
|
51539
|
+
level = 3 /* DEBUG */;
|
|
51540
|
+
} else if (opts.verbose >= 1) {
|
|
51541
|
+
level = 2 /* VERBOSE */;
|
|
51542
|
+
}
|
|
51543
|
+
setGlobalLogger(createLogger(level));
|
|
51544
|
+
const isUpgradeCommand = actionCommand.name() === "upgrade";
|
|
51545
|
+
if (!opts.quiet && !isUpgradeCommand) {
|
|
51546
|
+
const configPath = opts.config ?? ".dbcli";
|
|
51547
|
+
(async () => {
|
|
51548
|
+
try {
|
|
51549
|
+
let cache = null;
|
|
51550
|
+
try {
|
|
51551
|
+
const cacheFile = Bun.file(join5(configPath, "version-check.json"));
|
|
51552
|
+
if (await cacheFile.exists()) {
|
|
51553
|
+
cache = await cacheFile.json();
|
|
51554
|
+
}
|
|
51555
|
+
} catch {}
|
|
51556
|
+
const result = await checkForUpdate(package_default.version, configPath, cache);
|
|
51557
|
+
_bgVersionCheckResult = result;
|
|
51558
|
+
} catch {
|
|
51559
|
+
_bgVersionCheckResult = null;
|
|
51560
|
+
}
|
|
51561
|
+
})();
|
|
51562
|
+
}
|
|
51563
|
+
});
|
|
51564
|
+
program2.hook("postAction", () => {
|
|
51565
|
+
if (_bgVersionCheckResult?.hasUpdate) {
|
|
51566
|
+
process.stderr.write(formatUpdateHint(_bgVersionCheckResult.latestVersion) + `
|
|
51567
|
+
`);
|
|
51568
|
+
}
|
|
51569
|
+
});
|
|
50829
51570
|
program2.addCommand(initCommand);
|
|
50830
51571
|
program2.addCommand(listCommand);
|
|
50831
51572
|
program2.addCommand(schemaCommand);
|
|
@@ -50885,6 +51626,9 @@ program2.addCommand(blacklistCommand);
|
|
|
50885
51626
|
program2.addCommand(checkCommand);
|
|
50886
51627
|
program2.addCommand(diffCommand);
|
|
50887
51628
|
program2.addCommand(statusCommand);
|
|
51629
|
+
program2.addCommand(doctorCommand);
|
|
51630
|
+
program2.addCommand(completionCommand);
|
|
51631
|
+
program2.addCommand(upgradeCommand);
|
|
50888
51632
|
if (!process.argv.slice(2).length) {
|
|
50889
51633
|
program2.outputHelp();
|
|
50890
51634
|
}
|