From 38585b53f3589d606aa40ed6e361a56c15006df1 Mon Sep 17 00:00:00 2001 From: seven Date: Sun, 6 Oct 2024 15:42:05 +0800 Subject: [PATCH] feat: enable support for copy command as curl (#109) feat: enable support for copy command as curl user can copy the es query as a curl command to action it in the terminal Refs: #104 --------- Signed-off-by: seven --- package-lock.json | 168 ++++++++++++++++---------------- package.json | 2 +- src/common/index.ts | 1 + src/common/monaco/tokenlizer.ts | 81 +++++++++++++-- src/common/requestUtil.ts | 26 +++++ src/datasources/fetchApi.ts | 17 +--- src/lang/enUS.ts | 2 + src/lang/zhCN.ts | 2 + src/store/connectionStore.ts | 21 +++- src/views/editor/index.vue | 47 +++++---- 10 files changed, 243 insertions(+), 124 deletions(-) create mode 100644 src/common/requestUtil.ts diff --git a/package-lock.json b/package-lock.json index f497e43..206c749 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "dockit", - "version": "0.4.5", + "version": "0.4.6", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "dockit", - "version": "0.4.5", + "version": "0.4.6", "license": "Apache-2.0", "dependencies": { "@tauri-apps/api": "^1.6.0", @@ -1890,9 +1890,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz", - "integrity": "sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.0.tgz", + "integrity": "sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==", "cpu": [ "arm" ], @@ -1903,9 +1903,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.0.tgz", - "integrity": "sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.0.tgz", + "integrity": "sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==", "cpu": [ "arm64" ], @@ -1916,9 +1916,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.0.tgz", - "integrity": "sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.0.tgz", + "integrity": "sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==", "cpu": [ "arm64" ], @@ -1929,9 +1929,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.0.tgz", - "integrity": "sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.0.tgz", + "integrity": "sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==", "cpu": [ "x64" ], @@ -1942,9 +1942,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.0.tgz", - "integrity": "sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.0.tgz", + "integrity": "sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==", "cpu": [ "arm" ], @@ -1955,9 +1955,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.0.tgz", - "integrity": "sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.0.tgz", + "integrity": "sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==", "cpu": [ "arm" ], @@ -1968,9 +1968,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.0.tgz", - "integrity": "sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.0.tgz", + "integrity": "sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==", "cpu": [ "arm64" ], @@ -1981,9 +1981,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.0.tgz", - "integrity": "sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.0.tgz", + "integrity": "sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==", "cpu": [ "arm64" ], @@ -1994,9 +1994,9 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.0.tgz", - "integrity": "sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.0.tgz", + "integrity": "sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==", "cpu": [ "ppc64" ], @@ -2007,9 +2007,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.0.tgz", - "integrity": "sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.0.tgz", + "integrity": "sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==", "cpu": [ "riscv64" ], @@ -2020,9 +2020,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.0.tgz", - "integrity": "sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.0.tgz", + "integrity": "sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==", "cpu": [ "s390x" ], @@ -2033,9 +2033,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz", - "integrity": "sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.0.tgz", + "integrity": "sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==", "cpu": [ "x64" ], @@ -2046,9 +2046,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.0.tgz", - "integrity": "sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.0.tgz", + "integrity": "sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==", "cpu": [ "x64" ], @@ -2059,9 +2059,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.0.tgz", - "integrity": "sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.0.tgz", + "integrity": "sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==", "cpu": [ "arm64" ], @@ -2072,9 +2072,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.0.tgz", - "integrity": "sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.0.tgz", + "integrity": "sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==", "cpu": [ "ia32" ], @@ -2085,9 +2085,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz", - "integrity": "sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.0.tgz", + "integrity": "sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==", "cpu": [ "x64" ], @@ -2375,9 +2375,9 @@ } }, "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", "dev": true }, "node_modules/@types/graceful-fs": { @@ -6297,9 +6297,9 @@ } }, "node_modules/micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "dependencies": { "braces": "^3.0.3", @@ -7145,12 +7145,12 @@ } }, "node_modules/rollup": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.0.tgz", - "integrity": "sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.0.tgz", + "integrity": "sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg==", "dev": true, "dependencies": { - "@types/estree": "1.0.5" + "@types/estree": "1.0.6" }, "bin": { "rollup": "dist/bin/rollup" @@ -7160,22 +7160,22 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.18.0", - "@rollup/rollup-android-arm64": "4.18.0", - "@rollup/rollup-darwin-arm64": "4.18.0", - "@rollup/rollup-darwin-x64": "4.18.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.18.0", - "@rollup/rollup-linux-arm-musleabihf": "4.18.0", - "@rollup/rollup-linux-arm64-gnu": "4.18.0", - "@rollup/rollup-linux-arm64-musl": "4.18.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.18.0", - "@rollup/rollup-linux-riscv64-gnu": "4.18.0", - "@rollup/rollup-linux-s390x-gnu": "4.18.0", - "@rollup/rollup-linux-x64-gnu": "4.18.0", - "@rollup/rollup-linux-x64-musl": "4.18.0", - "@rollup/rollup-win32-arm64-msvc": "4.18.0", - "@rollup/rollup-win32-ia32-msvc": "4.18.0", - "@rollup/rollup-win32-x64-msvc": "4.18.0", + "@rollup/rollup-android-arm-eabi": "4.24.0", + "@rollup/rollup-android-arm64": "4.24.0", + "@rollup/rollup-darwin-arm64": "4.24.0", + "@rollup/rollup-darwin-x64": "4.24.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.24.0", + "@rollup/rollup-linux-arm-musleabihf": "4.24.0", + "@rollup/rollup-linux-arm64-gnu": "4.24.0", + "@rollup/rollup-linux-arm64-musl": "4.24.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.24.0", + "@rollup/rollup-linux-riscv64-gnu": "4.24.0", + "@rollup/rollup-linux-s390x-gnu": "4.24.0", + "@rollup/rollup-linux-x64-gnu": "4.24.0", + "@rollup/rollup-linux-x64-musl": "4.24.0", + "@rollup/rollup-win32-arm64-msvc": "4.24.0", + "@rollup/rollup-win32-ia32-msvc": "4.24.0", + "@rollup/rollup-win32-x64-msvc": "4.24.0", "fsevents": "~2.3.2" } }, @@ -7869,7 +7869,7 @@ "version": "5.5.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz", "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==", - "devOptional": true, + "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -8179,14 +8179,14 @@ } }, "node_modules/vite": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.1.tgz", - "integrity": "sha512-XBmSKRLXLxiaPYamLv3/hnP/KXDai1NDexN0FpkTaZXTfycHvkRHoenpgl/fvuK/kPbB6xAgoyiryAhQNxYmAQ==", + "version": "5.4.8", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.8.tgz", + "integrity": "sha512-FqrItQ4DT1NC4zCUqMB4c4AZORMKIa0m8/URVCZ77OZ/QSNeJ54bU1vrFADbDsuwfIPcgknRkmqakQcgnL4GiQ==", "dev": true, "dependencies": { "esbuild": "^0.21.3", - "postcss": "^8.4.38", - "rollup": "^4.13.0" + "postcss": "^8.4.43", + "rollup": "^4.20.0" }, "bin": { "vite": "bin/vite.js" @@ -8205,6 +8205,7 @@ "less": "*", "lightningcss": "^1.21.0", "sass": "*", + "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.4.0" @@ -8222,6 +8223,9 @@ "sass": { "optional": true }, + "sass-embedded": { + "optional": true + }, "stylus": { "optional": true }, diff --git a/package.json b/package.json index 351bb1b..69b95f0 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "dockit", "private": true, "type": "module", - "version": "0.4.5", + "version": "0.4.6", "description": "DocKit is a desktop client designed for NoSQL database, support Elasticsearch and OpenSearch across Mac, windows and Linux", "author": "geekfun ", "homepage": "ttps://dockit.geekfun.club", diff --git a/src/common/index.ts b/src/common/index.ts index 4de56ce..1d47f11 100644 --- a/src/common/index.ts +++ b/src/common/index.ts @@ -5,3 +5,4 @@ export * from './pureObject'; export * from './base64'; export * from './crypto'; export * from './valueConversion'; +export * from './requestUtil'; diff --git a/src/common/monaco/tokenlizer.ts b/src/common/monaco/tokenlizer.ts index f3ba064..f70a4f2 100644 --- a/src/common/monaco/tokenlizer.ts +++ b/src/common/monaco/tokenlizer.ts @@ -1,4 +1,4 @@ -import { Decoration, executeActions, monaco, SearchAction } from './'; +import { Decoration, Editor, executeActions, monaco, Range, SearchAction } from './'; import JSON5 from 'json5'; import { CustomError } from '../customError.ts'; @@ -46,6 +46,23 @@ export const buildSearchToken = (lines: Array<{ lineNumber: number; lineContent: return searchTokens; }; +export const getPositionAction = (position: Range) => { + return searchTokens.find(({ position: { startLineNumber, endLineNumber } }) => { + return position.startLineNumber >= startLineNumber && position.endLineNumber <= endLineNumber; + }); +}; +export const getPointerAction = (editor: Editor, tokens: Array) => { + const { lineNumber } = editor?.getPosition() || {}; + if (lineNumber === undefined || lineNumber === null) { + return; + } + + return tokens.find( + ({ position: { startLineNumber, endLineNumber } }) => + lineNumber >= startLineNumber && lineNumber <= endLineNumber, + ); +}; + export const executionGutterClass = 'execute-button-decoration'; export const getActionMarksDecorations = (searchTokens: SearchAction[]): Array => { return searchTokens @@ -57,8 +74,22 @@ export const getActionMarksDecorations = (searchTokens: SearchAction[]): Array (a as Decoration).id - (b as Decoration).id) as Array; }; -export const buildCodeLens = (searchTokens: SearchAction[], autoIndentCmdId: string) => - searchTokens +export const buildCodeLens = ( + searchTokens: SearchAction[], + autoIndentCmdId: string, + copyAsCurlCmdId: string, +) => { + const copyCurl = searchTokens.map(({ position }, index) => ({ + range: { ...position, endLineNumber: position.startLineNumber }, + id: `CopyAsCurl-${index}`, + command: { + id: copyAsCurlCmdId!, + title: 'Copy as CURL', + arguments: [position], + }, + })); + + const autoIndent = searchTokens .filter(({ qdsl }) => qdsl) .map(({ position }, index) => ({ range: { ...position, endLineNumber: position.startLineNumber }, @@ -70,6 +101,9 @@ export const buildCodeLens = (searchTokens: SearchAction[], autoIndentCmdId: str }, })); + return [...autoIndent, ...copyCurl]; +}; + export const formatQDSL = ( searchTokens: SearchAction[], model: monaco.editor.ITextModel, @@ -93,19 +127,50 @@ export const formatQDSL = ( return lines.map(line => JSON5.stringify(line)).join('\n'); }; -export const transformQDSL = (action: SearchAction) => { +export const transformQDSL = ({ path, qdsl }: Pick) => { try { - const bulkAction = action.path.includes('_bulk'); + const bulkAction = path.includes('_bulk'); if (bulkAction) { - const dsql = action.qdsl + const bulkQdsl = qdsl .split('\n') .map(line => JSON.stringify(JSON5.parse(line))) .join('\n'); - return `${dsql}\n`; + return `${bulkQdsl}\n`; } - return action.qdsl ? JSON.stringify(JSON5.parse(action.qdsl), null, 2) : undefined; + return qdsl ? JSON.stringify(JSON5.parse(qdsl), null, 2) : undefined; } catch (err) { throw new CustomError(400, (err as Error).message); } }; + +export const transformToCurl = ({ + method, + headers, + qdsl, + url, + ssl, +}: { + url: string; + method: string; + headers: { [key: string]: string }; + qdsl: string; + ssl: boolean | undefined; +}) => { + let curlCmd = `curl -X ${method} '${url}'`; + + if (url.startsWith('https') && ssl === false) { + curlCmd += ' --insecure'; + } + + if (headers) { + curlCmd += Object.entries(headers) + .map(([key, value]) => ` -H '${key}: ${value}'`) + .join(''); + } + if (qdsl) { + curlCmd += ` -d '${transformQDSL({ path: url, qdsl })}'`; + } + + return curlCmd; +}; diff --git a/src/common/requestUtil.ts b/src/common/requestUtil.ts new file mode 100644 index 0000000..f2a00c8 --- /dev/null +++ b/src/common/requestUtil.ts @@ -0,0 +1,26 @@ +import { base64Encode } from './base64.ts'; + +export const buildAuthHeader = (username: string | undefined, password: string | undefined) => { + const authorization = + username || password ? `Basic ${base64Encode(`${username}:${password}`)}` : undefined; + return authorization ? { authorization } : undefined; +}; + +export const buildURL = ( + host: string, + port: number, + index: string | undefined, + path: string | undefined, + queryParameters?: string, +) => { + const trimmedPath = path?.startsWith('/') ? path.slice(1) : path; + const pathWithIndex = + index && + !['_nodes', '_cluster', '_cat', '_bulk', '_aliases', '_analyze'].includes( + trimmedPath?.split('/')[0] ?? '', + ) + ? `${index}/${trimmedPath}` + : `${trimmedPath}`; + + return `${host}:${port}/${pathWithIndex}${queryParameters ? `?${queryParameters}` : ''}`; +}; diff --git a/src/datasources/fetchApi.ts b/src/datasources/fetchApi.ts index 6e167af..e02dcc8 100644 --- a/src/datasources/fetchApi.ts +++ b/src/datasources/fetchApi.ts @@ -1,4 +1,4 @@ -import { base64Encode, CustomError, debug } from '../common'; +import { buildAuthHeader, buildURL, CustomError, debug } from '../common'; import { lang } from '../lang'; import { invoke } from '@tauri-apps/api/tauri'; @@ -21,14 +21,6 @@ const handleFetch = (result: { data: unknown; status: number; details: string | throw new CustomError(result.status, result.details || ''); }; -const buildURL = (host: string, port: number, path?: string, queryParameters?: string) => { - let url = `${host}:${port}`; - url += path ?? ''; - url += queryParameters ? `?${queryParameters}` : ''; - - return url; -}; - const fetchWrapper = async ({ method, path, @@ -51,13 +43,10 @@ const fetchWrapper = async ({ ssl: boolean; }) => { try { - const authorization = - username || password ? `Basic ${base64Encode(`${username}:${password}`)}` : undefined; - - const url = buildURL(host, port, path, queryParameters); + const url = buildURL(host, port, undefined, path, queryParameters); const { data, status, details } = await fetchRequest(url, { method, - headers: { authorization }, + headers: { ...buildAuthHeader(username, password) }, payload, agent: { ssl }, }); diff --git a/src/lang/enUS.ts b/src/lang/enUS.ts index 4349acc..05c301d 100644 --- a/src/lang/enUS.ts +++ b/src/lang/enUS.ts @@ -148,6 +148,8 @@ export const enUS = { editor: { establishedRequired: 'Select a DB instance before execute actions', invalidJson: 'Invalid JSON format', + copySuccess: 'Copied to clipboard', + copyFailure: 'Failed to copy to clipboard', }, history: { empty: 'No history yet', diff --git a/src/lang/zhCN.ts b/src/lang/zhCN.ts index 0b32096..4b44f7a 100644 --- a/src/lang/zhCN.ts +++ b/src/lang/zhCN.ts @@ -148,6 +148,8 @@ export const zhCN = { editor: { establishedRequired: '请选择执行操作的数据库实例', invalidJson: '无效的 JSON 格式', + copySuccess: '已复制到粘贴板', + copyFailure: '复制失败', }, history: { empty: '无历史记录', diff --git a/src/store/connectionStore.ts b/src/store/connectionStore.ts index abde141..458e383 100644 --- a/src/store/connectionStore.ts +++ b/src/store/connectionStore.ts @@ -1,6 +1,7 @@ import { defineStore } from 'pinia'; -import { pureObject } from '../common'; +import { buildAuthHeader, buildURL, pureObject } from '../common'; import { loadHttpClient, storeApi } from '../datasources'; +import { SearchAction, transformToCurl } from '../common/monaco'; export type Connection = { id?: number; @@ -85,7 +86,6 @@ export const useConnectionStore = defineStore('connectionStore', { async establishConnection(connection: Connection) { await this.testConnection(connection); const client = loadHttpClient(connection); - const data = (await client.get('/_cat/indices', 'format=json')) as Array<{ [key: string]: string; }>; @@ -169,5 +169,22 @@ export const useConnectionStore = defineStore('connectionStore', { }; return dispatch[method](); }, + queryToCurl({ method, path, index, qdsl, queryParams }: SearchAction) { + const { username, password, host, port, sslCertVerification } = this.established ?? { + host: 'http://localhost', + port: 9200, + username: undefined, + password: undefined, + }; + const params = queryParams ? `${queryParams}&format=json` : 'format=json'; + const url = buildURL(host, port, index, path, params); + + const headers = { + 'Content-Type': 'application/json', + ...buildAuthHeader(username, password), + }; + + return transformToCurl({ method, headers, url, ssl: sslCertVerification, qdsl }); + }, }, }); diff --git a/src/views/editor/index.vue b/src/views/editor/index.vue index fc14832..d0603e5 100644 --- a/src/views/editor/index.vue +++ b/src/views/editor/index.vue @@ -30,7 +30,10 @@ import { formatQDSL, getActionApiDoc, getActionMarksDecorations, + getPointerAction, + getPositionAction, monaco, + Range, SearchAction, transformQDSL, } from '../../common/monaco'; @@ -44,7 +47,7 @@ const { readSourceFromFile, saveSourceToFile } = sourceFileStore; const { defaultFile } = storeToRefs(sourceFileStore); const connectionStore = useConnectionStore(); -const { searchQDSL } = connectionStore; +const { searchQDSL, queryToCurl } = connectionStore; const { established } = storeToRefs(connectionStore); const { getEditorTheme } = appStore; const { themeType } = storeToRefs(appStore); @@ -54,6 +57,7 @@ const { insertBoard } = storeToRefs(chatStore); // https://github.com/tjx666/adobe-devtools/commit/8055d8415ed3ec5996880b3a4ee2db2413a71c61 let queryEditor: Editor | null = null; let autoIndentCmdId: string | null = null; +let copyCurlCmdId: string | null = null; // DOM const queryEditorRef = ref(); const displayEditorRef = ref(); @@ -87,7 +91,7 @@ const codeLensProvider = monaco.languages.registerCodeLensProvider('search', { refreshActionMarks(queryEditor!, searchTokens); return { - lenses: buildCodeLens(searchTokens, autoIndentCmdId!), + lenses: buildCodeLens(searchTokens, autoIndentCmdId!, copyCurlCmdId!), dispose: () => {}, }; }, @@ -157,16 +161,17 @@ const executeQueryAction = async (position: { column: number; lineNumber: number } }; -const autoIndentAction = (editor: monaco.editor.IStandaloneCodeEditor) => { +const autoIndentAction = (editor: monaco.editor.IStandaloneCodeEditor, position: Range) => { const model = editor?.getModel(); - const { position } = getPointerAction(editor!, searchTokens) || {}; - if (!position || !model) { + const action = getPositionAction(position); + + if (!action || !model) { return; } - const { startLineNumber, endLineNumber } = position; + const { startLineNumber, endLineNumber } = action.position; try { - const formatted = formatQDSL(searchTokens, model, position); + const formatted = formatQDSL(searchTokens, model, action.position); model.pushEditOperations( [], [ @@ -192,16 +197,20 @@ const autoIndentAction = (editor: monaco.editor.IStandaloneCodeEditor) => { } }; -const getPointerAction = (editor: Editor, tokens: Array) => { - const { lineNumber } = editor?.getPosition() || {}; - if (lineNumber === undefined || lineNumber === null) { +const copyCurlAction = (position: Range) => { + const action = getPositionAction(position); + if (!action) { return; } - - return tokens.find( - ({ position: { startLineNumber, endLineNumber } }) => - lineNumber >= startLineNumber && lineNumber <= endLineNumber, - ); + try { + navigator.clipboard.writeText(queryToCurl(action)); + message.success(lang.t('editor.copySuccess')); + } catch (err) { + message.error(`${lang.t('editor.copyFailed')}: ${JSON.stringify(err)}`, { + closable: true, + keepAliveOnHover: true, + }); + } }; const setupQueryEditor = (code: string) => { @@ -216,7 +225,8 @@ const setupQueryEditor = (code: string) => { return; } - autoIndentCmdId = queryEditor.addCommand(0, () => autoIndentAction(queryEditor!)); + autoIndentCmdId = queryEditor.addCommand(0, (...args) => autoIndentAction(queryEditor!, args[1])); + copyCurlCmdId = queryEditor.addCommand(0, (...args) => copyCurlAction(args[1])); queryEditor.onMouseDown(({ event, target }) => { if ( @@ -231,7 +241,10 @@ const setupQueryEditor = (code: string) => { // Auto indent current request queryEditor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyI, () => { - autoIndentAction(queryEditor!); + const { position } = getPointerAction(queryEditor!, searchTokens) || {}; + if (position) { + autoIndentAction(queryEditor!, position); + } }); // Toggle Autocomplete