UNPKG

hudada-cli

Version:

专为程序员准备的本地文档搜索,快捷开发工具

3 lines (2 loc) 15.9 kB
#!/usr/bin/env node import{Command as o,Argument as n}from"commander";import e from"chalk";import{existsSync as t,statSync as i,appendFileSync as r,writeFileSync as s,readFileSync as a}from"fs";import c,{dirname as m,sep as p,join as d}from"path";import{marked as l}from"marked";import{markedTerminal as f}from"marked-terminal";import{getAllSearchPaths as y,getExistingPaths as g,mydirFile as h,configDir as w,dataPath as u,getFileContent as x,searchInDirectory as j,getDirectoryContent as v,availableFiles as $}from"./file.mjs";import{removeFileOrDirectory as b}from"./rm.mjs";import{handleHttpUrl as k,handleHttpUrlPrivate as N,handleGithubSearch as S,handleBaiduSearch as A,handleStackOverflowSearch as D,handleBilibiliSearch as C,handleJuejinSearch as E,handleZhihuSearch as G,handleMDN as M,handleCSDNSearch as B,handleNpmSearch as H,handleGoogleSearch as I,handleBingSearch as P}from"./websearch/web.mjs";import{handleDNSLookup as R}from"./websearch/dns.mjs";import{handlePngUrls as z}from"./websearch/images.mjs";import{handleMusicUrls as U}from"./websearch/music.mjs";import{handleSetTranslateKey as O}from"./websearch/translate.mjs";import{handleAi as X}from"./ai.mjs";import{startPreview as T}from"./preview.mjs";import{handleDate as _}from"./date.mjs";import{handleColor as F}from"./color.mjs";import{handleVSCode as J}from"./vs.mjs";import{startLocalServer as L}from"./local.mjs";import{startSSHServer as W}from"./ssh.mjs";import{compressImages as V}from"./image/compress.mjs";import{processImages as q}from"./image/remove-bg.mjs";import{listFiles as K}from"./file/list.mjs";import{killPort as Q}from"./process/kill.mjs";import{touchFile as Y}from"./file/touch.mjs";import{makeDirectory as Z}from"./file/mkdir.mjs";import{moveFileOrDirectory as oo}from"./file/move.mjs";import{copyFileOrDirectory as no}from"./file/copy.mjs";import{zipFileOrDirectory as eo}from"./file/zip.mjs";import{unzipFile as to}from"./file/unzip.mjs";import{findItems as io}from"./file/find.mjs";import{getSystemInfo as ro}from"./system/os.mjs";import{managePath as so}from"./system/path.mjs";import{manageHosts as ao}from"./system/host.mjs";import{fileURLToPath as co}from"url";import{md5String as mo}from"./md5.mjs";import{base64String as po}from"./base64.mjs";import{getRandomComment as lo}from"./comment.mjs";import{cleanNodeModules as fo}from"./cleanModules.mjs";import{installDependencies as yo}from"./npmInstall.mjs";const go=m(co(import.meta.url));l.use(f({}));const ho=new o;ho.name("my").description("一个基于nodejs的命令行工具,可以干很多活").version(function(){try{const o=c.resolve(go,"..","package.json");return JSON.parse(a(o,"utf-8")).version||"0.0.0"}catch(o){return console.error(e.yellow("无法读取 package.json 版本号"),o),"0.0.0"}}()).arguments("[command...]").option("-s, --search <keyword>","搜索指定内容(仅限文本文件)").option("-d, --dir <path>","添加目录路径到 mydir.txt").option("-l, --list","列出所有可用的搜索路径").option("-r, --remove-dir <path>","从 mydir.txt 中删除指定的目录路径").option("-a, --append <text>","追加文本到文档中").action((async(o,n)=>{try{if(console.log("my"),process.argv.length<=2&&ho.help(),n.list){const o=y();return console.log(e.green("可用的搜索路径:")),void o.forEach((o=>{console.log(e.blue(`- ${o}`))}))}if(n.dir)try{const o=n.dir;t(o)||(console.error(e.red(`Directory not found: ${o}`)),process.exit(1)),i(o).isDirectory()||(console.error(e.red(`Not a directory: ${o}`)),process.exit(1));const s=g(h),a=o.replace(/\\/g,"/").replace(/\/+$/,"");return s.some((o=>o.replace(/\\/g,"/").replace(/\/+$/,"")===a))?void console.log(e.yellow(`目录已经存在 ${w}${p}mydir.txt: ${o}`)):(r(h,o+"\n"),void console.log(e.green(`本地文档路径已添加: ${o}`)))}catch(o){console.error(e.red(`Error adding directory: ${o.message}`)),process.exit(1)}if(n.removeDir)try{const o=n.removeDir,t=g(h),i=o.replace(/\\/g,"/").replace(/\/+$/,""),r=t.filter((o=>o.replace(/\\/g,"/").replace(/\/+$/,"")!==i));return r.length===t.length?void console.log(e.yellow(`目录在 ${w}${p}mydir.txt: ${o}\n 不存在`)):(s(h,r.join("\n")+(r.length>0?"\n":"")),void console.log(e.green(`本地文档路径已移除: ${o}`)))}catch(o){console.error(e.red(`移除文档路径错误: ${o.message}`)),process.exit(1)}let a=process.argv.slice(2),c=["-a","--append","-r","--remove-dir","-d","--dir","-l","--list","-s","--search"],m=a.findIndex((o=>!!c.includes(o))),f="",$="";[f,$]=-1===m?a:a.slice(0,m);const b=d(u,f),k={mainCommand:f,subCommand:$,commandPath:b};let N=!1;try{N=i(b).isDirectory()}catch{N=!1}if(N){if(!$){if(n.search){const o=j(b,n.search);return void(o.length>0?(console.log(e.green(`Found matches in ${o.length} files:`)),o.forEach((({file:o,matches:n})=>{console.log(e.blue(`\nFile: ${o}`)),console.log(e.yellow(`${n.length} matches found:`)),console.log(l(n.join("\n")))}))):console.log(e.yellow("No matches found.")))}const o=v(b);return console.log(e.green(`Contents of ${f} directory:`)),void o.forEach((o=>{const n=i(d(b,o)).isDirectory();console.log(e.blue(`${n?"📁":"📄"} ${o}`))}))}x(n,k,!0,o)}else x(n,k,!1,o)}catch(o){console.error(e.red(`Error: ${o instanceof Error?o.message:"Unknown error"}`)),console.log(e.yellow(`Available commands: ${$.join(", ")}`)),process.exit(1)}finally{process.exit(0)}})),ho.command("local [port]").description(`启动本地文件传输服务,适合大部分公司内部局域网传输;\n 将在本地命令行所在的文件夹创建一个${e.green("uploads")}文件夹,上传的文件都保存到该文件夹下`).option("-p, --port <number>","指定端口号(默认: 667)").action(((o,n)=>{console.log(o,"cmdPort",n);const t=o||n.port||667,i=parseInt(t,10);isNaN(i)||i<0||i>65535?console.error(e.red("无效的端口号,端口号必须在 0-65535 之间")):L(t)})),ho.command("ls").description("格式化列出当前目录内容").action((async()=>{await K(),process.exit(0)})),ho.command("kill <port>").description("结束指定端口的进程").action((async o=>{await Q(o),process.exit(0)})),ho.command("koutu").description("批量处理图片抠图,将当前目录下的所有图片进行智能抠图处理").action((async()=>{await q(),process.exit(0)})),ho.command("imgp").description("压缩当前目录下的所有图片,支持 jpg、png、gif 等格式\n 压缩后的图片将保存在 compressed 文件夹中").action((async()=>{await V(),process.exit(0)})),ho.command("ssh").description("启动 SSH 服务器,用于远程连接和文件传输\n 默认端口为 22,可通过 --port 选项指定其他端口").option("-p, --port <number>","指定 SSH 服务器端口号").action((async o=>{console.log(o),await W(o.port)})),ho.command("vs [paths...]").description("使用 VS Code 打开指定的文件或目录\n 如果不指定路径,则打开当前目录").option("-n, --new","在新窗口中打开").option("-r, --reuse","复用已有窗口").action((o=>{J(o),process.exit(0)})),ho.command("color <value>").description("颜色值转换工具,支持多种颜色格式互转:\n - HEX 转 RGB/RGBA\n - RGB/RGBA 转 HEX\n - 颜色名称转 HEX/RGB\n示例:\n color #ff0000\n color rgb(255,0,0)\n color red").action((o=>{F([o]),process.exit(0)})),ho.command("date").description("显示当前日期时间信息:\n - 当前时间戳\n - 格式化日期时间\n - UTC 时间\n - 本地时区信息").action((()=>{_(),process.exit(0)})),ho.command("preview").description("启动本地预览服务器\n - 支持热更新\n - 自动打开浏览器\n - 支持静态文件服务").option("-p, --port <number>","指定预览服务器端口号","3000").action((async o=>{await T(o.port),process.exit(0)})),ho.command("translate").alias("t").description("文本翻译工具").arguments("<text...>").option("--to <lang>","翻译目标语言").action((async(o,n)=>{await O(),process.exit(0)})),ho.command("http <url>").description("在默认浏览器中打开网页\n - 支持自动补全 http:// 前缀\n - 支持本地和远程 URL\n - 支持多种协议 (http, https)\n示例:\n http google.com\n http https://github.com\n http localhost:3000").action((async o=>{await k(o)})),ho.command("httpp <url>").description("在浏览器隐私模式下打开网页\n - 自动使用隐私模式\n - 支持多种浏览器\n - 不保留浏览记录\n示例:\n httpp google.com\n httpp https://github.com\n httpp localhost:3000").action((async o=>{await N(o)})),ho.command("mp3").description("给出10个mp3 文件链接").action((()=>{U(),process.exit(0)})),ho.command("png").description("给出10个png 图片链接").action((()=>{z(),process.exit(0)})),ho.command("dns <domain>").description("DNS 查询工具\n - 支持 A 记录查询\n - 支持 CNAME 查询\n - 支持 MX 记录查询\n示例:dns example.com").action((async o=>{await R(o),process.exit(0)})),ho.command("rm <path>").description("删除文件或目录\n - 支持递归删除\n - 支持强制删除\n - 支持通配符").option("-f, --force","强制删除,不提示").option("-r, --recursive","递归删除目录").action((async(o,n)=>{await b(o),process.exit(0)})),ho.command("touch <path>").description("创建新文件或更新时间戳\n - 如果文件不存在则创建\n - 如果文件存在则更新时间戳").action((async o=>{await Y(o),process.exit(0)})),ho.command("mkdir <path>").description("创建目录\n - 支持递归创建\n - 支持权限设置").option("-p, --parents","递归创建父目录").option("-m, --mode <mode>","设置目录权限").action((async(o,n)=>{await Z(o),process.exit(0)})),ho.command("mv <source> <destination>").description("移动文件或目录\n - 支持重命名\n - 支持跨目录移动\n - 支持批量移动").action((async(o,n)=>{await oo(o,n),process.exit(0)})),ho.command("cp <source> <destination>").description("复制文件或目录\n - 支持递归复制\n - 支持保留属性\n - 支持批量复制").option("-r, --recursive","递归复制目录").option("-p, --preserve","保留文件属性").action((async(o,n,e)=>{await no(o,n),process.exit(0)})),ho.command("zip <source> <destination>").description("压缩文件或目录\n - 支持多种压缩格式\n - 支持密码保护\n - 支持压缩等级设置").option("-p, --password <password>","设置压缩包密码").option("-l, --level <level>","设置压缩等级 (1-9)","6").action((async(o,n,e)=>{await eo(o,n),process.exit(0)})),ho.command("unzip <source> [destination]").description("解压缩文件\n - 支持多种压缩格式\n - 支持密码保护\n - 自动检测编码").option("-p, --password <password>","设置解压密码").action((async(o,n,e)=>{await to(o,n),process.exit(0)})),ho.command("find [path] [pattern]").description("查找文件和目录\n - 支持正则表达式\n - 支持文件类型过滤\n - 支持大小和时间过滤").action((async()=>{await io(),process.exit(0)})),ho.command("os").description("显示系统信息\n - CPU 信息\n - 内存使用情况\n - 磁盘使用情况\n - 网络接口信息").action((async()=>{await ro(),process.exit(0)})),ho.command("host <action> [hostname] [ip]").description("hosts 文件管理工具\n命令:\n - add: 添加 hosts 记录\n - remove: 删除 hosts 记录\n - list: 列出所有记录\n示例:\n host add example.com 127.0.0.1\n host remove example.com\n host list").action((async(o,n,e)=>{await ao(o,n,e),process.exit(0)})),ho.command("s <keyword>").description("在所有支持的平台上搜索内容\n - 同时搜索多个平台\n - 自动打开浏览器标签页\n - 支持的平台包括:\n · GitHub, NPM\n · Google, Bing, Baidu\n · StackOverflow, MDN\n · 掘金, 知乎, CSDN, 哔哩哔哩").action((async o=>{const n=[{fn:S,name:"GitHub"},{fn:A,name:"百度"},{fn:D,name:"StackOverflow"},{fn:C,name:"哔哩哔哩"},{fn:E,name:"掘金"},{fn:G,name:"知乎"},{fn:M,name:"MDN"},{fn:B,name:"CSDN"},{fn:H,name:"NPM"},{fn:I,name:"Google"},{fn:P,name:"Bing"}];console.log(e.blue(`正在所有平台搜索: ${o}`));for(const{fn:o,name:t}of n)try{console.log(e.green(`正在 ${t} 上搜索...`))}catch(o){console.error(e.red(`${t} 搜索失败:`,o.message))}})),ho.command("github <keyword>").description("在 GitHub 上搜索代码和项目\n - 搜索仓库\n - 搜索代码\n - 搜索问题").action((async o=>{await S(o)})),ho.command("baidu <keyword>").description("使用百度搜索\n - 支持中文搜索\n - 支持智能推荐").action((async o=>{await A(o)})),ho.command("bug <keyword>").alias("stackoverflow").description("在 StackOverflow 上搜索问题和解答\n - 搜索编程问题\n - 查看解决方案").action((async o=>{await D(o)})),ho.command("bili <keyword>").alias("bilibili").description("在哔哩哔哩搜索视频\n - 搜索视频\n - 搜索UP主\n - 搜索专栏").action((async o=>{await C(o)})),ho.command("juejin <keyword>").description("在掘金搜索技术文章\n - 搜索文章\n - 搜索作者\n - 搜索专栏").action((async o=>{await E(o)})),ho.command("zhihu <keyword>").description("在知乎搜索问答\n - 搜索问题\n - 搜索回答\n - 搜索专栏").action((async o=>{await G(o)})),ho.command("mdn <keyword>").description("在 MDN 搜索 Web 开发文档\n - HTML/CSS/JavaScript 文档\n - Web API 文档\n - 开发指南").action((async o=>{await M([o])})),ho.command("csdn <keyword>").description("在 CSDN 搜索技术文章\n - 搜索博客\n - 搜索问答\n - 搜索资源").action((async o=>{await B(o)})),ho.command("npm <keyword>").description("在 NPM 搜索包\n - 搜索包名\n - 查看包信息\n - 查看包文档").action((async o=>{await H(o)})),ho.command("google <keyword>").description("使用 Google 搜索\n - 全球搜索\n - 支持高级搜索语法").action((async o=>{await I(o)})),ho.command("bing <keyword>").description("使用 Bing 搜索\n - 全球搜索\n - AI 驱动的搜索结果").action((async o=>{await P(o)})),ho.command("md5 <text>").description("对字符串进行 MD5 加密").action((async o=>{o&&0!==o.length?(mo(o),process.exit(0)):console.log(e.yellow("请输入要加密的字符串"))})),ho.command("base64 <text>").description("Base64 转换功能").action((async o=>{o&&0!==o.length?(po(o),process.exit(0)):console.log(e.yellow("请输入文件路径"))})),ho.command("path").description("管理系统环境变量 PATH").argument("[action]","操作类型:add/remove/list").argument("[targetPath]","目标路径").action((async(o,n)=>{await so(o,n)})),ho.command("comment").option("-g, --all","获取所有的注释").description("获取意思的注释").action((async o=>{await lo(o),process.exit(0)})),ho.command("cleannode").description("默认递归清除node_modules,使用my cleannode [dir] 递归清除指定目录").addArgument(new n("[dir]")).action((async(o,n)=>{const e=process.cwd();let t="node_modules";o&&(t=o),console.log(`开始清理 ${t},起始路径: ${e}`);try{const o=await fo(e,t);console.log("\n清理完成!"),console.log(`共删除了 ${o.length}${t} 文件夹:`),o.forEach((o=>console.log(`- ${o}`)))}catch(o){console.error("清理过程中发生错误:",o)}finally{process.exit(0)}})),ho.command("install [path]").description("递归安装所有 package.json 的依赖\n - 自动检测子目录中的 package.json\n - 使用 pnpm 进行安装\n - 跳过 node_modules 目录").action((async o=>{await yo(),process.exit(0)})),ho.command("ai [prompt...]").description("AI 助手工具\n my ai list: 列出所有 AI 对话模板\n my ai add: 添加新的 AI 对话模板\n my ai key :添加deepseek api key\n my ai clear:清除聊天历史记录\n my ai <prompt> --save=<文件路径>:保存AI对话到文件\n \n \n ").option("--save <文件路径>","保存AI对话到文件").action((async(o,n)=>{await X(o)})),ho.parse();