Compare commits
89 Commits
main
...
i18n_trans
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
660c6440a3 | ||
|
|
6ddcfb0f3a | ||
|
|
845da1a1bb | ||
|
|
bc7d6225c9 | ||
|
|
bbd06cc389 | ||
|
|
67259f1bab | ||
|
|
14c1c784e1 | ||
|
|
047e415cf7 | ||
|
|
c73ed7347e | ||
|
|
b86be3f787 | ||
|
|
15a45ebf47 | ||
|
|
992ec4aec3 | ||
|
|
67cc829acc | ||
|
|
569e488474 | ||
|
|
34d67cd7fc | ||
|
|
13e814567b | ||
|
|
8701477bf8 | ||
|
|
15ddf655a7 | ||
|
|
5faeb54fd5 | ||
|
|
dd0ae50192 | ||
|
|
acfc100e58 | ||
|
|
2496a87170 | ||
|
|
ded43ca488 | ||
|
|
e2e9d385aa | ||
|
|
87054e7271 | ||
|
|
3165e40ee2 | ||
|
|
668ebcace4 | ||
|
|
2f9984c4fc | ||
|
|
de779def67 | ||
|
|
49f247f507 | ||
|
|
675691f2c9 | ||
|
|
1e91262ef6 | ||
|
|
299b499011 | ||
|
|
dca583aa7c | ||
|
|
dffb0abde2 | ||
|
|
35e08f5c6b | ||
|
|
5f37a60495 | ||
|
|
f52824a626 | ||
|
|
01da42c5af | ||
|
|
72a3bae676 | ||
|
|
b6b5c06da8 | ||
|
|
c58d74819e | ||
|
|
830c5d7692 | ||
|
|
f3db62dc3f | ||
|
|
845a1759e5 | ||
|
|
2315dbd4b4 | ||
|
|
5f0baa7ad9 | ||
|
|
fdf72d7802 | ||
|
|
675bd58e60 | ||
|
|
35888f8716 | ||
|
|
53b28ab4d9 | ||
|
|
5e4a618b7f | ||
|
|
9c273c8c42 | ||
|
|
d2a9115a07 | ||
|
|
924c7a1f8e | ||
|
|
81c70a6f26 | ||
|
|
9ddbdc5823 | ||
|
|
ed728ae018 | ||
|
|
67ca8a7bcd | ||
|
|
7c1ff50390 | ||
|
|
beef66ce65 | ||
|
|
e1e8b4cc29 | ||
|
|
dbc5be2d02 | ||
|
|
c41a689007 | ||
|
|
e6b620b236 | ||
|
|
e17c52bc70 | ||
|
|
d8cd06d68e | ||
|
|
31d3490cd7 | ||
|
|
27e32b9b21 | ||
|
|
b2e0b58e0d | ||
|
|
e38308325c | ||
|
|
45c643ef2e | ||
|
|
0ba6ecd7a2 | ||
|
|
c300c429b0 | ||
|
|
11c0ec855d | ||
|
|
377767f7d5 | ||
|
|
07a933e5bd | ||
|
|
c7846a7e6d | ||
|
|
44a1bfdc46 | ||
|
|
116e9e2fe6 | ||
|
|
dc8c89d645 | ||
|
|
2abace5580 | ||
|
|
50a6408736 | ||
|
|
2824352f35 | ||
|
|
683b015913 | ||
|
|
012a3e07b8 | ||
|
|
fb33346b67 | ||
|
|
aad3410b42 | ||
|
|
eb7da4acac |
2
.github/workflows/docker.yml
vendored
2
.github/workflows/docker.yml
vendored
@@ -17,7 +17,7 @@ on:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v5
|
||||
|
||||
27
.github/workflows/electron.yml
vendored
27
.github/workflows/electron.yml
vendored
@@ -356,7 +356,7 @@ jobs:
|
||||
|
||||
build-macos:
|
||||
runs-on: macos-latest
|
||||
if: (github.event.inputs.build_type == 'macos' || github.event.inputs.build_type == 'all') && github.event.inputs.artifact_destination != 'submit'
|
||||
if: github.event.inputs.build_type == 'macos' || github.event.inputs.build_type == 'all'
|
||||
needs: []
|
||||
permissions:
|
||||
contents: write
|
||||
@@ -584,7 +584,7 @@ jobs:
|
||||
|
||||
submit-to-chocolatey:
|
||||
runs-on: windows-latest
|
||||
if: github.event.inputs.artifact_destination == 'submit' && (github.event.inputs.build_type == 'all' || github.event.inputs.build_type == 'windows' || github.event.inputs.build_type == '')
|
||||
if: github.event.inputs.artifact_destination == 'submit'
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
@@ -689,7 +689,7 @@ jobs:
|
||||
|
||||
submit-to-flatpak:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event.inputs.artifact_destination == 'submit' && (github.event.inputs.build_type == 'all' || github.event.inputs.build_type == 'linux' || github.event.inputs.build_type == '')
|
||||
if: github.event.inputs.artifact_destination == 'submit'
|
||||
needs: []
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -776,7 +776,7 @@ jobs:
|
||||
|
||||
submit-to-homebrew:
|
||||
runs-on: macos-latest
|
||||
if: github.event.inputs.artifact_destination == 'submit' && (github.event.inputs.build_type == 'all' || github.event.inputs.build_type == 'macos')
|
||||
if: github.event.inputs.artifact_destination == 'submit'
|
||||
needs: []
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -801,20 +801,11 @@ jobs:
|
||||
URL="https://github.com/Termix-SSH/Termix/releases/download/release-$VERSION-tag/$DMG_NAME"
|
||||
|
||||
mkdir -p release_asset
|
||||
DOWNLOAD_PATH="release_asset/$DMG_NAME"
|
||||
PATH="release_asset/$DMG_NAME"
|
||||
echo "Downloading DMG from $URL"
|
||||
curl -L -o "$PATH" "$URL"
|
||||
|
||||
if command -v curl &> /dev/null; then
|
||||
curl -L -o "$DOWNLOAD_PATH" "$URL"
|
||||
elif command -v wget &> /dev/null; then
|
||||
wget -O "$DOWNLOAD_PATH" "$URL"
|
||||
else
|
||||
echo "Neither curl nor wget is available, installing curl"
|
||||
brew install curl
|
||||
curl -L -o "$DOWNLOAD_PATH" "$URL"
|
||||
fi
|
||||
|
||||
CHECKSUM=$(shasum -a 256 "$DOWNLOAD_PATH" | awk '{print $1}')
|
||||
CHECKSUM=$(shasum -a 256 "$PATH" | awk '{print $1}')
|
||||
|
||||
echo "dmg_name=$DMG_NAME" >> $GITHUB_OUTPUT
|
||||
echo "checksum=$CHECKSUM" >> $GITHUB_OUTPUT
|
||||
@@ -881,7 +872,7 @@ jobs:
|
||||
|
||||
submit-to-testflight:
|
||||
runs-on: macos-latest
|
||||
if: github.event.inputs.artifact_destination == 'submit' && (github.event.inputs.build_type == 'all' || github.event.inputs.build_type == 'macos')
|
||||
if: github.event.inputs.artifact_destination == 'submit'
|
||||
needs: []
|
||||
permissions:
|
||||
contents: write
|
||||
@@ -986,7 +977,7 @@ jobs:
|
||||
- name: Deploy to App Store Connect (TestFlight)
|
||||
if: steps.check_asc_creds.outputs.has_credentials == 'true'
|
||||
run: |
|
||||
PKG_FILE=$(find release -name "termix_macos_universal_mas.pkg" -type f | head -n 1)
|
||||
PKG_FILE=$(find artifact-mas -name "*.pkg" -type f | head -n 1)
|
||||
if [ -z "$PKG_FILE" ]; then
|
||||
echo "PKG file not found, exiting."
|
||||
exit 1
|
||||
|
||||
@@ -84,7 +84,7 @@ Supported Devices:
|
||||
- MSI Installer
|
||||
- Chocolatey Package Manager
|
||||
- Linux (x64/ia32)
|
||||
- Portable [(AUR available)](https://aur.archlinux.org/packages/termix-bin)
|
||||
- Portable
|
||||
- AppImage
|
||||
- Deb
|
||||
- Flatpak
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
files:
|
||||
- source: /src/locales/en.json
|
||||
translation: /src/locales/translated/%two_letters_code%.json
|
||||
@@ -19,7 +19,7 @@ COPY . .
|
||||
RUN find public/fonts -name "*.ttf" ! -name "*Regular.ttf" ! -name "*Bold.ttf" ! -name "*Italic.ttf" -delete
|
||||
|
||||
RUN npm cache clean --force && \
|
||||
NODE_OPTIONS="--max-old-space-size=3072" npm run build
|
||||
npm run build
|
||||
|
||||
# Stage 3: Build backend
|
||||
FROM deps AS backend-builder
|
||||
|
||||
60
package-lock.json
generated
60
package-lock.json
generated
@@ -158,7 +158,6 @@
|
||||
"integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.27.1",
|
||||
"@babel/generator": "^7.28.5",
|
||||
@@ -444,7 +443,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.19.1.tgz",
|
||||
"integrity": "sha512-q6NenYkEy2fn9+JyjIxMWcNjzTL/IhwqfzOut1/G3PrIFkrbl4AL7Wkse5tLrQUUyqGoAKU5+Pi5jnnXxH5HGw==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@codemirror/language": "^6.0.0",
|
||||
"@codemirror/state": "^6.0.0",
|
||||
@@ -493,7 +491,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lang-css/-/lang-css-6.3.1.tgz",
|
||||
"integrity": "sha512-kr5fwBGiGtmz6l0LSJIbno9QrifNMUusivHbnA1H6Dmqy4HZFte3UAICix1VuKo0lMPKQr2rqB+0BkKi/S3Ejg==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@codemirror/autocomplete": "^6.0.0",
|
||||
"@codemirror/language": "^6.0.0",
|
||||
@@ -520,7 +517,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lang-html/-/lang-html-6.4.11.tgz",
|
||||
"integrity": "sha512-9NsXp7Nwp891pQchI7gPdTwBuSuT3K65NGTHWHNJ55HjYcHLllr0rbIZNdOzas9ztc1EUVBlHou85FFZS4BNnw==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@codemirror/autocomplete": "^6.0.0",
|
||||
"@codemirror/lang-css": "^6.0.0",
|
||||
@@ -548,7 +544,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lang-javascript/-/lang-javascript-6.2.4.tgz",
|
||||
"integrity": "sha512-0WVmhp1QOqZ4Rt6GlVGwKJN3KW7Xh4H2q8ZZNGZaP6lRdxXJzmjm4FqvmOojVj6khWJHIb9sp7U/72W7xQgqAA==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@codemirror/autocomplete": "^6.0.0",
|
||||
"@codemirror/language": "^6.6.0",
|
||||
@@ -749,7 +744,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.11.3.tgz",
|
||||
"integrity": "sha512-9HBM2XnwDj7fnu0551HkGdrUrrqmYq/WC5iv6nbY2WdicXdGbhR/gfbZOH73Aqj4351alY1+aoG9rCNfiwS1RA==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@codemirror/view": "^6.23.0",
|
||||
@@ -826,7 +820,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.5.2.tgz",
|
||||
"integrity": "sha512-FVqsPqtPWKVVL3dPSxy8wEF/ymIEuVzF1PK3VbUgrxXpJUSHQWWZz4JMToquRxnkw+36LTamCZG2iua2Ptq0fA==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@marijn/find-cluster-break": "^1.0.0"
|
||||
}
|
||||
@@ -848,7 +841,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.38.6.tgz",
|
||||
"integrity": "sha512-qiS0z1bKs5WOvHIAC0Cybmv4AJSkAXgX5aD6Mqd2epSLlVJsQl8NG23jCVouIgkh4All/mrbdsf2UOLFnJw0tw==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@codemirror/state": "^6.5.0",
|
||||
"crelt": "^1.0.6",
|
||||
@@ -1176,7 +1168,6 @@
|
||||
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"fast-deep-equal": "^3.1.1",
|
||||
"fast-json-stable-stringify": "^2.0.0",
|
||||
@@ -1563,6 +1554,7 @@
|
||||
"dev": true,
|
||||
"license": "BSD-2-Clause",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"cross-dirname": "^0.1.0",
|
||||
"debug": "^4.3.4",
|
||||
@@ -1584,6 +1576,7 @@
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^6.0.1",
|
||||
@@ -2630,8 +2623,7 @@
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.3.0.tgz",
|
||||
"integrity": "sha512-L9X8uHCYU310o99L3/MpJKYxPzXPOS7S0NmBaM7UO/x2Kb2WbmMLSkfvdr1KxRIFYOpbY0Jhn7CfLSUDzL8arQ==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@lezer/cpp": {
|
||||
"version": "1.1.3",
|
||||
@@ -2671,7 +2663,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.3.tgz",
|
||||
"integrity": "sha512-qXdH7UqTvGfdVBINrgKhDsVTJTxactNNxLk7+UMwZhU13lMHaOBlJe9Vqp907ya56Y3+ed2tlqzys7jDkTmW0g==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@lezer/common": "^1.3.0"
|
||||
}
|
||||
@@ -2703,7 +2694,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@lezer/javascript/-/javascript-1.5.4.tgz",
|
||||
"integrity": "sha512-vvYx3MhWqeZtGPwDStM2dwgljd5smolYD2lR2UyFcHfxbBQebqx8yjmFmxtJ/E6nN6u1D9srOiVWm3Rb4tmcUA==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@lezer/common": "^1.2.0",
|
||||
"@lezer/highlight": "^1.1.3",
|
||||
@@ -2726,7 +2716,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.2.tgz",
|
||||
"integrity": "sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@lezer/common": "^1.0.0"
|
||||
}
|
||||
@@ -5174,7 +5163,6 @@
|
||||
"integrity": "sha512-NMv9ASNARoKksWtsq/SHakpYAYnhBrQgGD8zkLYk/jaK8jUGn08CfEdTRgYhMypUQAfzSP8W6gNLe0q19/t4VA==",
|
||||
"devOptional": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
@@ -5332,7 +5320,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.5.tgz",
|
||||
"integrity": "sha512-LuIQOcb6UmnF7C1PCFmEU1u2hmiHL43fgFQX67sN3H4Z+0Yk0Neo++mFsBjhOAuLzvlQeqAAkeDOZrJs9rzumQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@types/body-parser": "*",
|
||||
"@types/express-serve-static-core": "^5.0.0",
|
||||
@@ -5455,7 +5442,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.9.2.tgz",
|
||||
"integrity": "sha512-uWN8YqxXxqFMX2RqGOrumsKeti4LlmIMIyV0lgut4jx7KQBcBiW6vkDtIBvHnHIquwNfJhk8v2OtmO8zXWHfPA==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"undici-types": "~7.16.0"
|
||||
}
|
||||
@@ -5498,7 +5484,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.2.tgz",
|
||||
"integrity": "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"csstype": "^3.0.2"
|
||||
}
|
||||
@@ -5509,7 +5494,6 @@
|
||||
"integrity": "sha512-9KQPoO6mZCi7jcIStSnlOWn2nEF3mNmyr3rIAsGnAbQKYbRLyqmeSc39EVgtxXVia+LMT8j3knZLAZAh+xLmrw==",
|
||||
"devOptional": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"peerDependencies": {
|
||||
"@types/react": "^19.2.0"
|
||||
}
|
||||
@@ -5677,7 +5661,6 @@
|
||||
"integrity": "sha512-BnOroVl1SgrPLywqxyqdJ4l3S2MsKVLDVxZvjI1Eoe8ev2r3kGDo+PcMihNmDE+6/KjkTubSJnmqGZZjQSBq/g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/scope-manager": "8.46.2",
|
||||
"@typescript-eslint/types": "8.46.2",
|
||||
@@ -6085,8 +6068,7 @@
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@xterm/xterm/-/xterm-5.5.0.tgz",
|
||||
"integrity": "sha512-hqJHYaQb5OptNunnyAnkHyM8aCjZ1MEIDTQu1iIbbTD/xops91NB5yq1ZK/dC2JDbVWtF23zUtl9JE2NqwT87A==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/7zip-bin": {
|
||||
"version": "5.2.0",
|
||||
@@ -6121,7 +6103,6 @@
|
||||
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"acorn": "bin/acorn"
|
||||
},
|
||||
@@ -6549,7 +6530,6 @@
|
||||
"integrity": "sha512-3yVdyZhklTiNrtg+4WqHpJpFDd+WHTg2oM7UcR80GqL05AOV0xEJzc6qNvFYoEtE+hRp1n9MpN6/+4yhlGkDXQ==",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"bindings": "^1.5.0",
|
||||
"prebuild-install": "^7.1.1"
|
||||
@@ -6692,7 +6672,6 @@
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"baseline-browser-mapping": "^2.8.19",
|
||||
"caniuse-lite": "^1.0.30001751",
|
||||
@@ -7692,7 +7671,6 @@
|
||||
"integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"env-paths": "^2.2.1",
|
||||
"import-fresh": "^3.3.0",
|
||||
@@ -7769,7 +7747,8 @@
|
||||
"integrity": "sha512-+R08/oI0nl3vfPcqftZRpytksBXDzOUveBq/NBVx0sUp1axwzPQrKinNx5yd5sxPu8j1wIy8AfnVQ+5eFdha6Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true
|
||||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/cross-spawn": {
|
||||
"version": "7.0.6",
|
||||
@@ -8232,7 +8211,6 @@
|
||||
"integrity": "sha512-59CAAjAhTaIMCN8y9kD573vDkxbs1uhDcrFLHSgutYdPcGOU35Rf95725snvzEOy4BFB7+eLJ8djCNPmGwG67w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"app-builder-lib": "26.0.12",
|
||||
"builder-util": "26.0.11",
|
||||
@@ -8330,7 +8308,8 @@
|
||||
"version": "3.1.7",
|
||||
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.7.tgz",
|
||||
"integrity": "sha512-VaTstWtsneJY8xzy7DekmYWEOZcmzIe3Qb3zPd4STve1OBTa+e+WmS1ITQec1fZYXI3HCsOZZiSMpG6oxoWMWQ==",
|
||||
"license": "(MPL-2.0 OR Apache-2.0)"
|
||||
"license": "(MPL-2.0 OR Apache-2.0)",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/dot-prop": {
|
||||
"version": "5.3.0",
|
||||
@@ -8705,6 +8684,7 @@
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@electron/asar": "^3.2.1",
|
||||
"debug": "^4.1.1",
|
||||
@@ -8725,6 +8705,7 @@
|
||||
"integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.1.2",
|
||||
"jsonfile": "^4.0.0",
|
||||
@@ -8740,6 +8721,7 @@
|
||||
"integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"optionalDependencies": {
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
@@ -8750,6 +8732,7 @@
|
||||
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">= 4.0.0"
|
||||
}
|
||||
@@ -9011,7 +8994,6 @@
|
||||
"integrity": "sha512-iy2GE3MHrYTL5lrCtMZ0X1KLEKKUjmK0kzwcnefhR66txcEmXZD2YWgR5GNdcEwkNx3a0siYkSvl0vIC+Svjmg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.8.0",
|
||||
"@eslint-community/regexpp": "^4.12.1",
|
||||
@@ -11023,7 +11005,6 @@
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.27.6"
|
||||
},
|
||||
@@ -12590,6 +12571,7 @@
|
||||
"resolved": "https://registry.npmjs.org/marked/-/marked-14.0.0.tgz",
|
||||
"integrity": "sha512-uIj4+faQ+MgHgwUW1l2PsPglZLOLOT1uErt06dAPtx2kjteLAkbsd/0FiYg/MGS+i7ZKLb7w2WClxHkzOOuryQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"marked": "bin/marked.js"
|
||||
},
|
||||
@@ -14619,6 +14601,7 @@
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"commander": "^9.4.0"
|
||||
},
|
||||
@@ -14636,6 +14619,7 @@
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": "^12.20.0 || >=14"
|
||||
}
|
||||
@@ -15121,7 +15105,6 @@
|
||||
"resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz",
|
||||
"integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
@@ -15131,7 +15114,6 @@
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.0.tgz",
|
||||
"integrity": "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"scheduler": "^0.27.0"
|
||||
},
|
||||
@@ -15158,7 +15140,6 @@
|
||||
"resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.66.0.tgz",
|
||||
"integrity": "sha512-xXBqsWGKrY46ZqaHDo+ZUYiMUgi8suYu5kdrS20EG8KiL7VRQitEbNjm+UcrDYrNi1YLyfpmAeGjCZYXLT9YBw==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
},
|
||||
@@ -15306,7 +15287,6 @@
|
||||
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz",
|
||||
"integrity": "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@types/use-sync-external-store": "^0.0.6",
|
||||
"use-sync-external-store": "^1.4.0"
|
||||
@@ -15515,8 +15495,7 @@
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz",
|
||||
"integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/redux-thunk": {
|
||||
"version": "3.1.0",
|
||||
@@ -16906,6 +16885,7 @@
|
||||
"integrity": "sha512-yYrrsWnrXMcdsnu/7YMYAofM1ktpL5By7vZhf15CrXijWWrEYZks5AXBudalfSWJLlnen/QUJUB5aoB0kqZUGA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"mkdirp": "^0.5.1",
|
||||
"rimraf": "~2.6.2"
|
||||
@@ -16946,6 +16926,7 @@
|
||||
"integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"minimist": "^1.2.6"
|
||||
},
|
||||
@@ -16960,6 +16941,7 @@
|
||||
"deprecated": "Rimraf versions prior to v4 are no longer supported",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"glob": "^7.1.3"
|
||||
},
|
||||
@@ -17064,7 +17046,6 @@
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
|
||||
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
@@ -17270,7 +17251,6 @@
|
||||
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
||||
"devOptional": true,
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
@@ -17683,7 +17663,6 @@
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-7.1.12.tgz",
|
||||
"integrity": "sha512-ZWyE8YXEXqJrrSLvYgrRP7p62OziLW7xI5HYGWFzOvupfAlrLvURSzv/FyGyy0eidogEM3ujU+kUG1zuHgb6Ug==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"esbuild": "^0.25.0",
|
||||
"fdir": "^6.5.0",
|
||||
@@ -17775,7 +17754,6 @@
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
|
||||
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
|
||||
@@ -343,27 +343,6 @@ function getMimeType(fileName: string): string {
|
||||
return mimeTypes[ext || ""] || "application/octet-stream";
|
||||
}
|
||||
|
||||
function detectBinary(buffer: Buffer): boolean {
|
||||
if (buffer.length === 0) return false;
|
||||
|
||||
const sampleSize = Math.min(buffer.length, 8192);
|
||||
let nullBytes = 0;
|
||||
|
||||
for (let i = 0; i < sampleSize; i++) {
|
||||
const byte = buffer[i];
|
||||
|
||||
if (byte === 0) {
|
||||
nullBytes++;
|
||||
}
|
||||
|
||||
if (byte < 32 && byte !== 9 && byte !== 10 && byte !== 13) {
|
||||
if (++nullBytes > 1) return true;
|
||||
}
|
||||
}
|
||||
|
||||
return nullBytes / sampleSize > 0.01;
|
||||
}
|
||||
|
||||
app.post("/ssh/file_manager/ssh/connect", async (req, res) => {
|
||||
const {
|
||||
sessionId,
|
||||
@@ -1389,11 +1368,11 @@ app.get("/ssh/file_manager/ssh/readFile", (req, res) => {
|
||||
return res.status(500).json({ error: err.message });
|
||||
}
|
||||
|
||||
let binaryData = Buffer.alloc(0);
|
||||
let data = "";
|
||||
let errorData = "";
|
||||
|
||||
stream.on("data", (chunk: Buffer) => {
|
||||
binaryData = Buffer.concat([binaryData, chunk]);
|
||||
data += chunk.toString();
|
||||
});
|
||||
|
||||
stream.stderr.on("data", (chunk: Buffer) => {
|
||||
@@ -1417,23 +1396,7 @@ app.get("/ssh/file_manager/ssh/readFile", (req, res) => {
|
||||
});
|
||||
}
|
||||
|
||||
const isBinary = detectBinary(binaryData);
|
||||
|
||||
if (isBinary) {
|
||||
const base64Content = binaryData.toString("base64");
|
||||
res.json({
|
||||
content: base64Content,
|
||||
path: filePath,
|
||||
encoding: "base64",
|
||||
});
|
||||
} else {
|
||||
const textContent = binaryData.toString("utf8");
|
||||
res.json({
|
||||
content: textContent,
|
||||
path: filePath,
|
||||
encoding: "utf8",
|
||||
});
|
||||
}
|
||||
res.json({ content: data, path: filePath });
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1477,16 +1440,7 @@ app.post("/ssh/file_manager/ssh/writeFile", async (req, res) => {
|
||||
let fileBuffer;
|
||||
try {
|
||||
if (typeof content === "string") {
|
||||
try {
|
||||
const testBuffer = Buffer.from(content, "base64");
|
||||
if (testBuffer.toString("base64") === content) {
|
||||
fileBuffer = testBuffer;
|
||||
} else {
|
||||
fileBuffer = Buffer.from(content, "utf8");
|
||||
}
|
||||
} catch {
|
||||
fileBuffer = Buffer.from(content, "utf8");
|
||||
}
|
||||
fileBuffer = Buffer.from(content, "base64");
|
||||
} else if (Buffer.isBuffer(content)) {
|
||||
fileBuffer = content;
|
||||
} else {
|
||||
|
||||
2402
src/locales/translated/af.json
Normal file
2402
src/locales/translated/af.json
Normal file
File diff suppressed because it is too large
Load Diff
2402
src/locales/translated/ar.json
Normal file
2402
src/locales/translated/ar.json
Normal file
File diff suppressed because it is too large
Load Diff
2402
src/locales/translated/bg.json
Normal file
2402
src/locales/translated/bg.json
Normal file
File diff suppressed because it is too large
Load Diff
2402
src/locales/translated/bn.json
Normal file
2402
src/locales/translated/bn.json
Normal file
File diff suppressed because it is too large
Load Diff
2402
src/locales/translated/ca.json
Normal file
2402
src/locales/translated/ca.json
Normal file
File diff suppressed because it is too large
Load Diff
2402
src/locales/translated/cs.json
Normal file
2402
src/locales/translated/cs.json
Normal file
File diff suppressed because it is too large
Load Diff
2402
src/locales/translated/da.json
Normal file
2402
src/locales/translated/da.json
Normal file
File diff suppressed because it is too large
Load Diff
2402
src/locales/translated/de.json
Normal file
2402
src/locales/translated/de.json
Normal file
File diff suppressed because it is too large
Load Diff
2402
src/locales/translated/el.json
Normal file
2402
src/locales/translated/el.json
Normal file
File diff suppressed because it is too large
Load Diff
2402
src/locales/translated/en.json
Normal file
2402
src/locales/translated/en.json
Normal file
File diff suppressed because it is too large
Load Diff
2402
src/locales/translated/es.json
Normal file
2402
src/locales/translated/es.json
Normal file
File diff suppressed because it is too large
Load Diff
2402
src/locales/translated/fi.json
Normal file
2402
src/locales/translated/fi.json
Normal file
File diff suppressed because it is too large
Load Diff
2402
src/locales/translated/fr.json
Normal file
2402
src/locales/translated/fr.json
Normal file
File diff suppressed because it is too large
Load Diff
2402
src/locales/translated/he.json
Normal file
2402
src/locales/translated/he.json
Normal file
File diff suppressed because it is too large
Load Diff
2402
src/locales/translated/hi.json
Normal file
2402
src/locales/translated/hi.json
Normal file
File diff suppressed because it is too large
Load Diff
2402
src/locales/translated/hu.json
Normal file
2402
src/locales/translated/hu.json
Normal file
File diff suppressed because it is too large
Load Diff
2402
src/locales/translated/id.json
Normal file
2402
src/locales/translated/id.json
Normal file
File diff suppressed because it is too large
Load Diff
2402
src/locales/translated/it.json
Normal file
2402
src/locales/translated/it.json
Normal file
File diff suppressed because it is too large
Load Diff
2402
src/locales/translated/ja.json
Normal file
2402
src/locales/translated/ja.json
Normal file
File diff suppressed because it is too large
Load Diff
2402
src/locales/translated/ko.json
Normal file
2402
src/locales/translated/ko.json
Normal file
File diff suppressed because it is too large
Load Diff
2402
src/locales/translated/nl.json
Normal file
2402
src/locales/translated/nl.json
Normal file
File diff suppressed because it is too large
Load Diff
2402
src/locales/translated/no.json
Normal file
2402
src/locales/translated/no.json
Normal file
File diff suppressed because it is too large
Load Diff
2402
src/locales/translated/pl.json
Normal file
2402
src/locales/translated/pl.json
Normal file
File diff suppressed because it is too large
Load Diff
2402
src/locales/translated/pt.json
Normal file
2402
src/locales/translated/pt.json
Normal file
File diff suppressed because it is too large
Load Diff
2402
src/locales/translated/ro.json
Normal file
2402
src/locales/translated/ro.json
Normal file
File diff suppressed because it is too large
Load Diff
2402
src/locales/translated/ru.json
Normal file
2402
src/locales/translated/ru.json
Normal file
File diff suppressed because it is too large
Load Diff
2402
src/locales/translated/sr.json
Normal file
2402
src/locales/translated/sr.json
Normal file
File diff suppressed because it is too large
Load Diff
2402
src/locales/translated/sv.json
Normal file
2402
src/locales/translated/sv.json
Normal file
File diff suppressed because it is too large
Load Diff
2402
src/locales/translated/th.json
Normal file
2402
src/locales/translated/th.json
Normal file
File diff suppressed because it is too large
Load Diff
2402
src/locales/translated/tr.json
Normal file
2402
src/locales/translated/tr.json
Normal file
File diff suppressed because it is too large
Load Diff
2402
src/locales/translated/uk.json
Normal file
2402
src/locales/translated/uk.json
Normal file
File diff suppressed because it is too large
Load Diff
2402
src/locales/translated/vi.json
Normal file
2402
src/locales/translated/vi.json
Normal file
File diff suppressed because it is too large
Load Diff
2402
src/locales/translated/zh.json
Normal file
2402
src/locales/translated/zh.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -13,7 +13,7 @@ import { AdminSettings } from "@/ui/desktop/apps/admin/AdminSettings.tsx";
|
||||
import { UserProfile } from "@/ui/desktop/user/UserProfile.tsx";
|
||||
import { Toaster } from "@/components/ui/sonner.tsx";
|
||||
import { CommandPalette } from "@/ui/desktop/apps/command-palette/CommandPalette.tsx";
|
||||
import { getUserInfo, logoutUser, isElectron } from "@/ui/main-axios.ts";
|
||||
import { getUserInfo } from "@/ui/main-axios.ts";
|
||||
import { useTheme } from "@/components/theme-provider";
|
||||
|
||||
function AppContent() {
|
||||
@@ -163,6 +163,7 @@ function AppContent() {
|
||||
|
||||
setTimeout(async () => {
|
||||
try {
|
||||
const { logoutUser, isElectron } = await import("@/ui/main-axios.ts");
|
||||
await logoutUser();
|
||||
|
||||
if (isElectron()) {
|
||||
|
||||
@@ -4,7 +4,6 @@ import { Button } from "@/components/ui/button.tsx";
|
||||
import { getUserAlerts, dismissAlert } from "@/ui/main-axios.ts";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import type { TermixAlert } from "../../../../../../types";
|
||||
import { toast } from "sonner";
|
||||
|
||||
interface AlertManagerProps {
|
||||
userId: string | null;
|
||||
@@ -54,6 +53,7 @@ export function AlertManager({
|
||||
setAlerts(sortedAlerts);
|
||||
setCurrentAlertIndex(0);
|
||||
} catch {
|
||||
const { toast } = await import("sonner");
|
||||
toast.error(t("homepage.failedToLoadAlerts"));
|
||||
setError(t("homepage.failedToLoadAlerts"));
|
||||
} finally {
|
||||
|
||||
@@ -18,7 +18,6 @@ import {
|
||||
keepaliveDockerSession,
|
||||
verifyDockerTOTP,
|
||||
logActivity,
|
||||
getSSHHosts,
|
||||
} from "@/ui/main-axios.ts";
|
||||
import { SimpleLoader } from "@/ui/desktop/navigation/animations/SimpleLoader.tsx";
|
||||
import { AlertCircle } from "lucide-react";
|
||||
@@ -122,6 +121,7 @@ export function DockerManager({
|
||||
const fetchLatestHostConfig = async () => {
|
||||
if (hostConfig?.id) {
|
||||
try {
|
||||
const { getSSHHosts } = await import("@/ui/main-axios.ts");
|
||||
const hosts = await getSSHHosts();
|
||||
const updatedHost = hosts.find((h) => h.id === hostConfig.id);
|
||||
if (updatedHost) {
|
||||
@@ -138,6 +138,7 @@ export function DockerManager({
|
||||
const handleHostsChanged = async () => {
|
||||
if (hostConfig?.id) {
|
||||
try {
|
||||
const { getSSHHosts } = await import("@/ui/main-axios.ts");
|
||||
const hosts = await getSSHHosts();
|
||||
const updatedHost = hosts.find((h) => h.id === hostConfig.id);
|
||||
if (updatedHost) {
|
||||
|
||||
@@ -333,7 +333,13 @@ export function FileViewer({
|
||||
const ext = fileName.split(".").pop()?.toLowerCase() || "";
|
||||
|
||||
if (ext === "svg") {
|
||||
return `data:image/svg+xml;base64,${content}`;
|
||||
try {
|
||||
const base64 = btoa(unescape(encodeURIComponent(content)));
|
||||
return `data:image/svg+xml;base64,${base64}`;
|
||||
} catch (e) {
|
||||
console.error("Failed to encode SVG:", e);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
return `data:image/*;base64,${content}`;
|
||||
|
||||
@@ -47,22 +47,6 @@ interface FileWindowProps {
|
||||
onFileNotFound?: (file: FileItem) => void;
|
||||
}
|
||||
|
||||
function isDisplayableText(str: string): boolean {
|
||||
let printable = 0;
|
||||
for (let i = 0; i < Math.min(str.length, 1000); i++) {
|
||||
const code = str.charCodeAt(i);
|
||||
if (
|
||||
(code >= 32 && code <= 126) ||
|
||||
code === 9 ||
|
||||
code === 10 ||
|
||||
code === 13
|
||||
) {
|
||||
printable++;
|
||||
}
|
||||
}
|
||||
return printable / Math.min(str.length, 1000) > 0.85;
|
||||
}
|
||||
|
||||
export function FileWindow({
|
||||
windowId,
|
||||
file,
|
||||
@@ -122,19 +106,7 @@ export function FileWindow({
|
||||
await ensureSSHConnection();
|
||||
|
||||
const response = await readSSHFile(sshSessionId, file.path);
|
||||
let fileContent = response.content || "";
|
||||
|
||||
if (response.encoding === "base64") {
|
||||
try {
|
||||
const decoded = atob(fileContent);
|
||||
if (isDisplayableText(decoded)) {
|
||||
fileContent = decoded;
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("Failed to decode base64 content:", err);
|
||||
}
|
||||
}
|
||||
|
||||
const fileContent = response.content || "";
|
||||
setContent(fileContent);
|
||||
setPendingContent(fileContent);
|
||||
|
||||
|
||||
@@ -11,8 +11,6 @@ import {
|
||||
submitMetricsTOTP,
|
||||
executeSnippet,
|
||||
logActivity,
|
||||
sendMetricsHeartbeat,
|
||||
getSSHHosts,
|
||||
type ServerMetrics,
|
||||
} from "@/ui/main-axios.ts";
|
||||
import { TOTPDialog } from "@/ui/desktop/navigation/TOTPDialog.tsx";
|
||||
@@ -147,6 +145,7 @@ export function ServerStats({
|
||||
|
||||
const heartbeatInterval = setInterval(async () => {
|
||||
try {
|
||||
const { sendMetricsHeartbeat } = await import("@/ui/main-axios.ts");
|
||||
await sendMetricsHeartbeat(viewerSessionId);
|
||||
} catch (error) {
|
||||
console.error("Failed to send heartbeat:", error);
|
||||
@@ -274,6 +273,7 @@ export function ServerStats({
|
||||
const fetchLatestHostConfig = async () => {
|
||||
if (hostConfig?.id) {
|
||||
try {
|
||||
const { getSSHHosts } = await import("@/ui/main-axios.ts");
|
||||
const hosts = await getSSHHosts();
|
||||
const updatedHost = hosts.find((h) => h.id === hostConfig.id);
|
||||
if (updatedHost) {
|
||||
@@ -290,6 +290,7 @@ export function ServerStats({
|
||||
const handleHostsChanged = async () => {
|
||||
if (hostConfig?.id) {
|
||||
try {
|
||||
const { getSSHHosts } = await import("@/ui/main-axios.ts");
|
||||
const hosts = await getSSHHosts();
|
||||
const updatedHost = hosts.find((h) => h.id === hostConfig.id);
|
||||
if (updatedHost) {
|
||||
|
||||
@@ -18,8 +18,6 @@ import {
|
||||
isElectron,
|
||||
logActivity,
|
||||
getSnippets,
|
||||
deleteCommandFromHistory,
|
||||
getCommandHistory,
|
||||
} from "@/ui/main-axios.ts";
|
||||
import { TOTPDialog } from "@/ui/desktop/navigation/TOTPDialog.tsx";
|
||||
import { SSHAuthDialog } from "@/ui/desktop/navigation/SSHAuthDialog.tsx";
|
||||
@@ -214,7 +212,8 @@ export const Terminal = forwardRef<TerminalHandle, SSHTerminalProps>(
|
||||
if (showHistoryDialog && hostConfig.id) {
|
||||
setIsLoadingHistory(true);
|
||||
setIsLoadingRef.current(true);
|
||||
getCommandHistory(hostConfig.id!)
|
||||
import("@/ui/main-axios.ts")
|
||||
.then((module) => module.getCommandHistory(hostConfig.id!))
|
||||
.then((history) => {
|
||||
setCommandHistory(history);
|
||||
setCommandHistoryContextRef.current(history);
|
||||
@@ -236,7 +235,8 @@ export const Terminal = forwardRef<TerminalHandle, SSHTerminalProps>(
|
||||
localStorage.getItem("commandAutocomplete") === "true";
|
||||
|
||||
if (hostConfig.id && autocompleteEnabled) {
|
||||
getCommandHistory(hostConfig.id!)
|
||||
import("@/ui/main-axios.ts")
|
||||
.then((module) => module.getCommandHistory(hostConfig.id!))
|
||||
.then((history) => {
|
||||
autocompleteHistory.current = history;
|
||||
})
|
||||
@@ -1107,6 +1107,8 @@ export const Terminal = forwardRef<TerminalHandle, SSHTerminalProps>(
|
||||
if (!hostConfig.id) return;
|
||||
|
||||
try {
|
||||
const { deleteCommandFromHistory } =
|
||||
await import("@/ui/main-axios.ts");
|
||||
await deleteCommandFromHistory(hostConfig.id, command);
|
||||
|
||||
setCommandHistory((prev) => {
|
||||
|
||||
@@ -3,7 +3,6 @@ import { useSidebar } from "@/components/ui/sidebar.tsx";
|
||||
import { Separator } from "@/components/ui/separator.tsx";
|
||||
import { Tunnel } from "@/ui/desktop/apps/features/tunnel/Tunnel.tsx";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { getSSHHosts } from "@/ui/main-axios.ts";
|
||||
|
||||
interface HostConfig {
|
||||
id: number;
|
||||
@@ -45,6 +44,7 @@ export function TunnelManager({
|
||||
const fetchLatestHostConfig = async () => {
|
||||
if (hostConfig?.id) {
|
||||
try {
|
||||
const { getSSHHosts } = await import("@/ui/main-axios.ts");
|
||||
const hosts = await getSSHHosts();
|
||||
const updatedHost = hosts.find((h) => h.id === hostConfig.id);
|
||||
if (updatedHost) {
|
||||
@@ -61,6 +61,7 @@ export function TunnelManager({
|
||||
const handleHostsChanged = async () => {
|
||||
if (hostConfig?.id) {
|
||||
try {
|
||||
const { getSSHHosts } = await import("@/ui/main-axios.ts");
|
||||
const hosts = await getSSHHosts();
|
||||
const updatedHost = hosts.find((h) => h.id === hostConfig.id);
|
||||
if (updatedHost) {
|
||||
|
||||
@@ -5,7 +5,6 @@ import { FormControl, FormItem, FormLabel } from "@/components/ui/form.tsx";
|
||||
import { getCredentials } from "@/ui/main-axios.ts";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import type { Credential } from "../../../../../types";
|
||||
import { toast } from "sonner";
|
||||
|
||||
interface CredentialSelectorProps {
|
||||
value?: number | null;
|
||||
@@ -37,6 +36,7 @@ export function CredentialSelector({
|
||||
: data.credentials || data.data || [];
|
||||
setCredentials(credentialsArray);
|
||||
} catch {
|
||||
const { toast } = await import("sonner");
|
||||
toast.error(t("credentials.failedToFetchCredentials"));
|
||||
setCredentials([]);
|
||||
} finally {
|
||||
|
||||
@@ -52,7 +52,6 @@ import {
|
||||
getHostAccess,
|
||||
revokeHostAccess,
|
||||
getSSHHostById,
|
||||
notifyHostCreatedOrUpdated,
|
||||
type Role,
|
||||
type AccessRecord,
|
||||
} from "@/ui/main-axios.ts";
|
||||
@@ -820,6 +819,8 @@ export function HostManagerEditor({
|
||||
window.dispatchEvent(new CustomEvent("ssh-hosts:changed"));
|
||||
|
||||
if (savedHost?.id) {
|
||||
const { notifyHostCreatedOrUpdated } =
|
||||
await import("@/ui/main-axios.ts");
|
||||
notifyHostCreatedOrUpdated(savedHost.id);
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
@@ -26,7 +26,6 @@ import {
|
||||
updateFolderMetadata,
|
||||
deleteAllHostsInFolder,
|
||||
getServerStatusById,
|
||||
refreshServerPolling,
|
||||
} from "@/ui/main-axios.ts";
|
||||
import { toast } from "sonner";
|
||||
import { useTranslation } from "react-i18next";
|
||||
@@ -314,6 +313,7 @@ export function HostManagerViewer({ onEditHost }: SSHManagerHostViewerProps) {
|
||||
await fetchHosts();
|
||||
window.dispatchEvent(new CustomEvent("ssh-hosts:changed"));
|
||||
|
||||
const { refreshServerPolling } = await import("@/ui/main-axios.ts");
|
||||
refreshServerPolling();
|
||||
} catch {
|
||||
toast.error(t("hosts.failedToDeleteHost"));
|
||||
|
||||
@@ -18,7 +18,7 @@ import {
|
||||
DropdownMenuItem,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
import { useTabs } from "@/ui/desktop/navigation/tabs/TabContext";
|
||||
import { getServerStatusById, getSSHHosts } from "@/ui/main-axios";
|
||||
import { getServerStatusById } from "@/ui/main-axios";
|
||||
import type { HostProps } from "../../../../types";
|
||||
import { DEFAULT_STATS_CONFIG } from "@/types/stats-widgets";
|
||||
import { useTranslation } from "react-i18next";
|
||||
@@ -47,6 +47,7 @@ export function Host({ host: initialHost }: HostProps): React.ReactElement {
|
||||
|
||||
useEffect(() => {
|
||||
const handleHostsChanged = async () => {
|
||||
const { getSSHHosts } = await import("@/ui/main-axios.ts");
|
||||
const hosts = await getSSHHosts();
|
||||
const updatedHost = hosts.find((h) => h.id === host.id);
|
||||
if (updatedHost) {
|
||||
|
||||
@@ -42,7 +42,6 @@ import { PasswordReset } from "@/ui/desktop/user/PasswordReset.tsx";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { LanguageSwitcher } from "@/ui/desktop/user/LanguageSwitcher.tsx";
|
||||
import { useSidebar } from "@/components/ui/sidebar.tsx";
|
||||
import { toast } from "sonner";
|
||||
|
||||
interface UserProfileProps {
|
||||
isTopbarOpen?: boolean;
|
||||
@@ -145,6 +144,7 @@ export function UserProfile({
|
||||
const info = await getVersionInfo();
|
||||
setVersionInfo({ version: info.localVersion });
|
||||
} catch {
|
||||
const { toast } = await import("sonner");
|
||||
toast.error(t("user.failedToLoadVersionInfo"));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import axios, { AxiosError, type AxiosInstance } from "axios";
|
||||
import { toast } from "sonner";
|
||||
import type {
|
||||
SSHHost,
|
||||
SSHHostData,
|
||||
@@ -447,7 +446,9 @@ function createApiInstance(
|
||||
|
||||
if (isSessionExpired && typeof window !== "undefined") {
|
||||
console.warn("Session expired - please log in again");
|
||||
toast.warning("Session expired. Please log in again.");
|
||||
import("sonner").then(({ toast }) => {
|
||||
toast.warning("Session expired. Please log in again.");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1420,11 +1421,7 @@ export async function identifySSHSymlink(
|
||||
export async function readSSHFile(
|
||||
sessionId: string,
|
||||
path: string,
|
||||
): Promise<{
|
||||
content: string;
|
||||
path: string;
|
||||
encoding?: "base64" | "utf8";
|
||||
}> {
|
||||
): Promise<{ content: string; path: string }> {
|
||||
try {
|
||||
const response = await fileManagerApi.get("/ssh/readFile", {
|
||||
params: { sessionId, path },
|
||||
|
||||
@@ -20,17 +20,6 @@ export default defineConfig({
|
||||
base: "./",
|
||||
build: {
|
||||
sourcemap: false,
|
||||
rollupOptions: {
|
||||
output: {
|
||||
manualChunks: {
|
||||
'react-vendor': ['react', 'react-dom'],
|
||||
'ui-vendor': ['@radix-ui/react-dialog', '@radix-ui/react-dropdown-menu', '@radix-ui/react-select', '@radix-ui/react-tabs', '@radix-ui/react-switch', '@radix-ui/react-tooltip', '@radix-ui/react-scroll-area', '@radix-ui/react-separator', 'lucide-react', 'clsx', 'tailwind-merge', 'class-variance-authority'],
|
||||
'monaco': ['monaco-editor'],
|
||||
'codemirror': ['@uiw/react-codemirror', '@codemirror/view', '@codemirror/state', '@codemirror/language', '@codemirror/commands', '@codemirror/search', '@codemirror/autocomplete'],
|
||||
}
|
||||
}
|
||||
},
|
||||
chunkSizeWarningLimit: 1000,
|
||||
},
|
||||
server: {
|
||||
https: useHTTPS
|
||||
|
||||
Reference in New Issue
Block a user