chore: refresh dependencies and modernize Go test idioms

Frontend deps: @hookform/resolvers 5.4.3 -> 5.5.7, Storybook 10.5.4 -> 10.5.5
across the four packages we declare, globals 17.7.0 -> 17.8.0, and jsdom
29.1.1 -> 30.0.1. The jsdom major replaces its CSS and selector stack --
@asamuzakjp/css-color 5 -> 6, @asamuzakjp/dom-selector 7 -> 8, undici 7 -> 8,
nwsapi and generational-cache folded into their parents, whatwg-url 17 nested
underneath. Nothing in the Vitest suites reaches those directly and the whole
frontend gate (typecheck, lint, tests, build, Storybook compile) is green.
Panel frontend version to 0.6.0.

Backend deps: mattn/go-sqlite3 1.14.48 -> 1.14.49 and valyala/fasthttp
1.72.0 -> 1.73.0, plus the golang.org/x/exp and genproto/googleapis/rpc
indirect bumps that came with them.

Go tests: modernize -fix output, covering range-over-int, sync.WaitGroup.Go
in place of manual Add/Done pairs, maps.Copy, and Go 1.26 new(expr) for
pointer-to-value in the forwarded-trust table. The storedAs helper is deleted
instead of being left behind a //go:fix inline directive -- keeping it that way
fails govet on the one call site the rewrite did not reach, and every caller now
takes new(...) directly. Behaviour is unchanged.

DnsTab: the hosts-sync effect tested dns while declaring dnsEnabled in its
dependency array. Both carry the same truth value, so this is exhaustive-deps
hygiene rather than a behaviour change.
This commit is contained in:
Sanaei
2026-07-30 03:14:22 +02:00
parent 66740b7ef4
commit c56f6447a8
10 changed files with 159 additions and 152 deletions
+123 -106
View File
@@ -1,17 +1,17 @@
{
"name": "3x-ui-frontend",
"version": "0.4.3",
"version": "0.6.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "3x-ui-frontend",
"version": "0.4.3",
"version": "0.6.0",
"dependencies": {
"@ant-design/icons": "^6.3.2",
"@codemirror/lang-json": "^6.0.2",
"@codemirror/theme-one-dark": "^6.1.3",
"@hookform/resolvers": "^5.4.3",
"@hookform/resolvers": "^5.5.7",
"@noble/hashes": "^2.2.0",
"@tanstack/react-query": "^5.101.4",
"@tanstack/react-query-devtools": "^5.101.4",
@@ -32,10 +32,10 @@
},
"devDependencies": {
"@eslint/js": "^10.0.1",
"@storybook/addon-a11y": "^10.5.4",
"@storybook/addon-docs": "^10.5.4",
"@storybook/addon-vitest": "^10.5.4",
"@storybook/react-vite": "^10.5.4",
"@storybook/addon-a11y": "^10.5.5",
"@storybook/addon-docs": "^10.5.5",
"@storybook/addon-vitest": "^10.5.5",
"@storybook/react-vite": "^10.5.5",
"@testing-library/dom": "^10.4.1",
"@testing-library/react": "^16.3.2",
"@types/react": "^19.2.17",
@@ -47,13 +47,13 @@
"eslint": "^10.8.0",
"eslint-plugin-jsx-a11y": "^6.10.2",
"eslint-plugin-react-hooks": "^7.1.1",
"globals": "^17.7.0",
"globals": "^17.8.0",
"husky": "^9.1.7",
"jsdom": "^29.1.1",
"jsdom": "^30.0.1",
"lint-staged": "^17.2.0",
"msw": "^2.15.0",
"playwright": "^1.62.0",
"storybook": "^10.5.4",
"storybook": "^10.5.5",
"typescript": "6.0.3",
"typescript-eslint": "^8.65.0",
"vite": "8.1.5",
@@ -165,56 +165,58 @@
}
},
"node_modules/@asamuzakjp/css-color": {
"version": "5.1.11",
"resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-5.1.11.tgz",
"integrity": "sha512-KVw6qIiCTUQhByfTd78h2yD1/00waTmm9uy/R7Ck/ctUyAPj+AEDLkQIdJW0T8+qGgj3j5bpNKK7Q3G+LedJWg==",
"version": "6.0.5",
"resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-6.0.5.tgz",
"integrity": "sha512-mbhpPMmnw/kwW19aRNmSUl1QzLbdGo1SCuE49BT98MNwqF6zaHb3o2owssFc/PEO/4t2UjqtCNwocuDtJornzA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@asamuzakjp/generational-cache": "^1.0.1",
"@csstools/css-calc": "^3.2.0",
"@csstools/css-color-parser": "^4.1.0",
"@csstools/css-calc": "^3.2.1",
"@csstools/css-color-parser": "^4.1.9",
"@csstools/css-parser-algorithms": "^4.0.0",
"@csstools/css-tokenizer": "^4.0.0"
"@csstools/css-tokenizer": "^4.0.0",
"lru-cache": "^11.5.2"
},
"engines": {
"node": "^20.19.0 || ^22.12.0 || >=24.0.0"
"node": "^22.13.0 || >=24.0.0"
}
},
"node_modules/@asamuzakjp/css-color/node_modules/lru-cache": {
"version": "11.5.2",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.2.tgz",
"integrity": "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==",
"dev": true,
"license": "BlueOak-1.0.0",
"engines": {
"node": "20 || >=22"
}
},
"node_modules/@asamuzakjp/dom-selector": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-7.1.1.tgz",
"integrity": "sha512-67RZDnYRc8H/8MLDgQCDE//zoqVFwajkepHZgmXrbwybzXOEwOWGPYGmALYl9J2DOLfFPPs6kKCqmbzV895hTQ==",
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-8.3.0.tgz",
"integrity": "sha512-UJLfKXBhrc8i1vH2eJXuYQMwlsLKWFw3O+CPqXSuVEiikeAim3UgrfWX0k4tA/X8cRFM8iZ7OaqBokFGbYusdg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@asamuzakjp/generational-cache": "^1.0.1",
"@asamuzakjp/nwsapi": "^2.3.9",
"bidi-js": "^1.0.3",
"css-tree": "^3.2.1",
"is-potential-custom-element-name": "^1.0.1"
"is-potential-custom-element-name": "^1.0.1",
"lru-cache": "^11.5.2"
},
"engines": {
"node": "^20.19.0 || ^22.12.0 || >=24.0.0"
"node": "^22.13.0 || >=24.0.0"
}
},
"node_modules/@asamuzakjp/generational-cache": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@asamuzakjp/generational-cache/-/generational-cache-1.0.1.tgz",
"integrity": "sha512-wajfB8KqzMCN2KGNFdLkReeHncd0AslUSrvHVvvYWuU8ghncRJoA50kT3zP9MVL0+9g4/67H+cdvBskj9THPzg==",
"node_modules/@asamuzakjp/dom-selector/node_modules/lru-cache": {
"version": "11.5.2",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.2.tgz",
"integrity": "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==",
"dev": true,
"license": "MIT",
"license": "BlueOak-1.0.0",
"engines": {
"node": "^20.19.0 || ^22.12.0 || >=24.0.0"
"node": "20 || >=22"
}
},
"node_modules/@asamuzakjp/nwsapi": {
"version": "2.3.9",
"resolved": "https://registry.npmjs.org/@asamuzakjp/nwsapi/-/nwsapi-2.3.9.tgz",
"integrity": "sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==",
"dev": true,
"license": "MIT"
},
"node_modules/@babel/code-frame": {
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz",
@@ -1384,9 +1386,9 @@
}
},
"node_modules/@hookform/resolvers": {
"version": "5.4.3",
"resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-5.4.3.tgz",
"integrity": "sha512-jtS1DEvkT1ql8ImIDQL+UmkhEnDmt3Bp7Yt4q5XQpc0JiQ8b8+I7yT/KQze4gw9Ocmi9xa9ef6zxifizPgdp3A==",
"version": "5.5.7",
"resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-5.5.7.tgz",
"integrity": "sha512-CyPCYV8/KlXfEXLWj8HHHhVsR/IZ6Ckm3b/a4fWtO/lRnRK1huqncb8LlAWrmpPRsse5glF5aVuDRMHEr3UGag==",
"license": "MIT",
"dependencies": {
"@standard-schema/utils": "^0.3.0"
@@ -1413,7 +1415,7 @@
"react-hook-form": "^7.55.0",
"superstruct": ">=0.12.0",
"typanion": "^3.3.2",
"valibot": "^1.0.0 || ^1.0.0-beta.4 || ^1.0.0-rc",
"valibot": ">=0.31.0 || ^1.0.0-beta.4 || ^1.0.0-rc",
"vest": ">=3.0.0",
"yup": "^1.0.0",
"zod": "^3.25.0 || ^4.0.0"
@@ -3631,9 +3633,9 @@
"license": "MIT"
},
"node_modules/@storybook/addon-a11y": {
"version": "10.5.4",
"resolved": "https://registry.npmjs.org/@storybook/addon-a11y/-/addon-a11y-10.5.4.tgz",
"integrity": "sha512-UWdZtB7Dh1GjqxTPOrisUNDhDGF5pKGzZdzW9DSSHMBcAOx2dsTmXGzLSFprAz4LTT0OHCtKhxNqKK0JZJ0Y8g==",
"version": "10.5.5",
"resolved": "https://registry.npmjs.org/@storybook/addon-a11y/-/addon-a11y-10.5.5.tgz",
"integrity": "sha512-nsMnSRe7pzepXIkUUqI/rL7sp8juXOluyypU4Dz0UuYHhw/cKaxfzuO+3WJN5EtEr/gcnKYb4awxH/duPGavUw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3645,20 +3647,20 @@
"url": "https://opencollective.com/storybook"
},
"peerDependencies": {
"storybook": "^10.5.4"
"storybook": "^10.5.5"
}
},
"node_modules/@storybook/addon-docs": {
"version": "10.5.4",
"resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-10.5.4.tgz",
"integrity": "sha512-2Z/x2pKEmXOCQjmttYzPuQBu9aWeMly8uEs3msrCTBLiHs/F7IlBFnMu0Z+T2Qvk0LEy8O93AlcPSP76aCcKjw==",
"version": "10.5.5",
"resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-10.5.5.tgz",
"integrity": "sha512-0YpKlimS4XE0kQ8Maa5coeefQxdyDrBHg1wOP3WTPuBe4FolFSCDveR0ge2+vuUBk+fZfn2+l+3Q2jmAWaRGDg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@mdx-js/react": "^3.0.0",
"@storybook/csf-plugin": "10.5.4",
"@storybook/csf-plugin": "10.5.5",
"@storybook/icons": "^2.0.2",
"@storybook/react-dom-shim": "10.5.4",
"@storybook/react-dom-shim": "10.5.5",
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
"ts-dedent": "^2.0.0"
@@ -3669,7 +3671,7 @@
},
"peerDependencies": {
"@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
"storybook": "^10.5.4"
"storybook": "^10.5.5"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -3678,9 +3680,9 @@
}
},
"node_modules/@storybook/addon-vitest": {
"version": "10.5.4",
"resolved": "https://registry.npmjs.org/@storybook/addon-vitest/-/addon-vitest-10.5.4.tgz",
"integrity": "sha512-5lr81sgrbK3Tjjbstieg/yYj3jdtQYP70ihpOiN1TwogvFATY2/9eMT46FE5ioKtEFcfJRDcgJ2wSlmJKE+kZw==",
"version": "10.5.5",
"resolved": "https://registry.npmjs.org/@storybook/addon-vitest/-/addon-vitest-10.5.5.tgz",
"integrity": "sha512-Ymq9ErkSkYiIDuqpJ2+hE5GCQ5J6TCLOWhutqArvwaeAO+HAibM82XNExpJ1/kvPqk9y961GDPkv2W15I88JIw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3695,7 +3697,7 @@
"@vitest/browser": "^3.0.0 || ^4.0.0",
"@vitest/browser-playwright": "^4.0.0",
"@vitest/runner": "^3.0.0 || ^4.0.0",
"storybook": "^10.5.4",
"storybook": "^10.5.5",
"vitest": "^3.0.0 || ^4.0.0"
},
"peerDependenciesMeta": {
@@ -3714,13 +3716,13 @@
}
},
"node_modules/@storybook/builder-vite": {
"version": "10.5.4",
"resolved": "https://registry.npmjs.org/@storybook/builder-vite/-/builder-vite-10.5.4.tgz",
"integrity": "sha512-eXdgow+brSzZrG3CnG18YwxZwEYNAZIh2G5qKwNoZf0uk2ZCPgLRQwtVAcd7BiiEDGnXUHm9pycAS+UiF4F4Mg==",
"version": "10.5.5",
"resolved": "https://registry.npmjs.org/@storybook/builder-vite/-/builder-vite-10.5.5.tgz",
"integrity": "sha512-dQoJ7gUl8y0z5rV9cE0mz6qTBNmN9R4GOLIZk98rJ8CwduNJOb9eGZXusDzzvnYcp8TnNkqDtyx4tXQSUDInPQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@storybook/csf-plugin": "10.5.4",
"@storybook/csf-plugin": "10.5.5",
"ts-dedent": "^2.0.0"
},
"funding": {
@@ -3728,14 +3730,14 @@
"url": "https://opencollective.com/storybook"
},
"peerDependencies": {
"storybook": "^10.5.4",
"storybook": "^10.5.5",
"vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0"
}
},
"node_modules/@storybook/csf-plugin": {
"version": "10.5.4",
"resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-10.5.4.tgz",
"integrity": "sha512-DSp5Z/eZlRnKq0KrKLJE6uoYf/Ysc+FP0Z5DVTGnOrie+z3tC0lNi9I4RB++EXkJeUDS9/4dxvJZVSWjhLlXxw==",
"version": "10.5.5",
"resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-10.5.5.tgz",
"integrity": "sha512-/euibhRFqklYCZqUseokojmfYcQpXshVY2QmA1qCuxMz9SzVFD3iSTw+aFLTxpsJGGdcZJk8fnm/rEthLzZ9jA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3748,7 +3750,7 @@
"peerDependencies": {
"esbuild": "*",
"rollup": "*",
"storybook": "^10.5.4",
"storybook": "^10.5.5",
"vite": "*",
"webpack": "*"
},
@@ -3785,14 +3787,14 @@
}
},
"node_modules/@storybook/react": {
"version": "10.5.4",
"resolved": "https://registry.npmjs.org/@storybook/react/-/react-10.5.4.tgz",
"integrity": "sha512-tOxfVgbYcaVsArN8XTDkJfdsnsnHh1LxjRHVpJ/N+VEkz4FveK/XH3jOLV0YqgrG8yXza7+CteDP4FfPVQY/mw==",
"version": "10.5.5",
"resolved": "https://registry.npmjs.org/@storybook/react/-/react-10.5.5.tgz",
"integrity": "sha512-T2Xj0ey7a9RHU6coYLC0L5lhjcdyhLCs9wNv15FvHvgmrRobkynEV72kq5vGW8tFkahNWI1X9+GZPQ6r8Nm38w==",
"dev": true,
"license": "MIT",
"dependencies": {
"@storybook/global": "^5.0.0",
"@storybook/react-dom-shim": "10.5.4",
"@storybook/react-dom-shim": "10.5.5",
"react-docgen": "^8.0.2",
"react-docgen-typescript": "^2.2.2"
},
@@ -3805,7 +3807,7 @@
"@types/react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
"storybook": "^10.5.4",
"storybook": "^10.5.5",
"typescript": ">= 4.9.x"
},
"peerDependenciesMeta": {
@@ -3821,9 +3823,9 @@
}
},
"node_modules/@storybook/react-dom-shim": {
"version": "10.5.4",
"resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-10.5.4.tgz",
"integrity": "sha512-YdlppEOReg8MvTECRNuf79gu2zL83JqKDHIR/65eS0M6y+ue9pkpfjYo7hZVIcyOcRd9npBDXMdt2kC92bCuaA==",
"version": "10.5.5",
"resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-10.5.5.tgz",
"integrity": "sha512-PIk7N3LLrZIxfNxmkvmQN1d5UQ70XEedT8n0GhBiXnM6XL09xPGB8n8TZXeJBRYluKhDQcAyQeT0/OZmcDVQJg==",
"dev": true,
"license": "MIT",
"funding": {
@@ -3835,7 +3837,7 @@
"@types/react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
"storybook": "^10.5.4"
"storybook": "^10.5.5"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -3847,16 +3849,16 @@
}
},
"node_modules/@storybook/react-vite": {
"version": "10.5.4",
"resolved": "https://registry.npmjs.org/@storybook/react-vite/-/react-vite-10.5.4.tgz",
"integrity": "sha512-iw7EAA98n30vpf+ZSy2Ll4Ne7oyZ/lS6W22u5Sp5UOI2oAkYuklxIWjRIKGqpY0BHP+GqaGYtUGMZQnBqgul2g==",
"version": "10.5.5",
"resolved": "https://registry.npmjs.org/@storybook/react-vite/-/react-vite-10.5.5.tgz",
"integrity": "sha512-Uy7VV72kVSkw6aDTAPQupXUeZX5LF6e4zqNvTZ+36qxsXAkaFgw7HPEm7L1tsaRfiV+s9anU7UvX47tfJpYGuQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@joshwooding/vite-plugin-react-docgen-typescript": "^0.7.0",
"@rollup/pluginutils": "^5.0.2",
"@storybook/builder-vite": "10.5.4",
"@storybook/react": "10.5.4",
"@storybook/builder-vite": "10.5.5",
"@storybook/react": "10.5.5",
"empathic": "^2.0.0",
"magic-string": "^0.30.0",
"react-docgen": "^8.0.2",
@@ -3870,7 +3872,7 @@
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
"storybook": "^10.5.4",
"storybook": "^10.5.5",
"typescript": ">= 4.9.x",
"vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0"
},
@@ -7165,7 +7167,7 @@
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"devOptional": true,
"dev": true,
"license": "MIT"
},
"node_modules/fast-json-patch": {
@@ -7531,9 +7533,9 @@
}
},
"node_modules/globals": {
"version": "17.7.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-17.7.0.tgz",
"integrity": "sha512-Czmyns5dUsq4seFBR/Kdydhmo8y9kC79hiSkPn0YcGtNnYWnrgt0vjrSjx9tspoDGWm2CMarffRuLjM4xUz8xg==",
"version": "17.8.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-17.8.0.tgz",
"integrity": "sha512-Zz/LMDZScFmkakeL2cTHzf+PbWKdpU3uclqkZT7TjDG58j5WPt0PpA+n9uPI24fZtlw07q0OtEi84K+umsRzqQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -8525,39 +8527,39 @@
}
},
"node_modules/jsdom": {
"version": "29.1.1",
"resolved": "https://registry.npmjs.org/jsdom/-/jsdom-29.1.1.tgz",
"integrity": "sha512-ECi4Fi2f7BdJtUKTflYRTiaMxIB0O6zfR1fX0GXpUrf6flp8QIYn1UT20YQqdSOfk2dfkCwS8LAFoJDEppNK5Q==",
"version": "30.0.1",
"resolved": "https://registry.npmjs.org/jsdom/-/jsdom-30.0.1.tgz",
"integrity": "sha512-52v7mUVUfNQVYYqE1lcdaymWL0njO7lTLUog6ZvW2U5KsbiLk/GnZlVJ+qx0xfNJZ6Gn+KSpPNE52vurbxZwrA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@asamuzakjp/css-color": "^5.1.11",
"@asamuzakjp/dom-selector": "^7.1.1",
"@asamuzakjp/css-color": "^6.0.5",
"@asamuzakjp/dom-selector": "^8.3.0",
"@bramus/specificity": "^2.4.2",
"@csstools/css-syntax-patches-for-csstree": "^1.1.3",
"@exodus/bytes": "^1.15.0",
"@csstools/css-syntax-patches-for-csstree": "^1.1.7",
"@exodus/bytes": "^1.15.1",
"css-tree": "^3.2.1",
"data-urls": "^7.0.0",
"decimal.js": "^10.6.0",
"html-encoding-sniffer": "^6.0.0",
"is-potential-custom-element-name": "^1.0.1",
"lru-cache": "^11.3.5",
"lru-cache": "^11.5.2",
"parse5": "^8.0.1",
"saxes": "^6.0.0",
"symbol-tree": "^3.2.4",
"tough-cookie": "^6.0.1",
"undici": "^7.25.0",
"tough-cookie": "^6.0.2",
"undici": "^8.9.0",
"w3c-xmlserializer": "^5.0.0",
"webidl-conversions": "^8.0.1",
"whatwg-mimetype": "^5.0.0",
"whatwg-url": "^16.0.1",
"whatwg-url": "^17.1.0",
"xml-name-validator": "^5.0.0"
},
"engines": {
"node": "^20.19.0 || ^22.13.0 || >=24.0.0"
"node": "^22.22.2 || ^24.15.0 || >=26.0.0"
},
"peerDependencies": {
"canvas": "^3.0.0"
"canvas": "^3.2.3"
},
"peerDependenciesMeta": {
"canvas": {
@@ -8575,6 +8577,21 @@
"node": "20 || >=22"
}
},
"node_modules/jsdom/node_modules/whatwg-url": {
"version": "17.1.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-17.1.0.tgz",
"integrity": "sha512-3GeworPmc2ZfEEHP7lEbUfBX/L75wdEsi0rLNhXcXxnoN5jyq0SL5gCy06SGW2cyTIZdTvWIDQNQoza++vKeaw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@exodus/bytes": "^1.15.1",
"tr46": "^6.0.0",
"webidl-conversions": "^8.0.1"
},
"engines": {
"node": "^22.14.0 || >=24.0.0"
}
},
"node_modules/jsesc": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
@@ -10420,7 +10437,7 @@
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
"integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
"devOptional": true,
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@@ -10967,9 +10984,9 @@
}
},
"node_modules/storybook": {
"version": "10.5.4",
"resolved": "https://registry.npmjs.org/storybook/-/storybook-10.5.4.tgz",
"integrity": "sha512-bmLxPsxVSPnbeiZqYQpozyNOiJXfk+pf7WfHZflvPkwT6Y+rvYz3Cj/D6H4Kf2jHpuDNiMXBKO3yawLN2OWirg==",
"version": "10.5.5",
"resolved": "https://registry.npmjs.org/storybook/-/storybook-10.5.5.tgz",
"integrity": "sha512-UscBIBJDloUeqntukHOhP1a5W/vouePDJbzPSxj466WK801FZtzQiMffMtkjzJiWSuj20wfaYlB2QQKh9aOYAg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -10989,7 +11006,7 @@
"recast": "^0.23.5",
"semver": "^7.7.3",
"use-sync-external-store": "^1.5.0",
"ws": "^8.18.0"
"ws": "^8.21.1"
},
"bin": {
"storybook": "dist/bin/dispatcher.js"
@@ -11760,13 +11777,13 @@
}
},
"node_modules/undici": {
"version": "7.29.0",
"resolved": "https://registry.npmjs.org/undici/-/undici-7.29.0.tgz",
"integrity": "sha512-IDxfleLmmbSskfWSUATiN1nfn2rDuvnMOqb5CWR92iIfojA0Ud+ulOAAEQ57LPr9rWmsreUyf5lwyao+7GNNVw==",
"version": "8.9.0",
"resolved": "https://registry.npmjs.org/undici/-/undici-8.9.0.tgz",
"integrity": "sha512-aWZpUj7XoGonMClx4gdDRfgBjqeA+F473aDmROQQbM9n6PRfK/u1q/a0X4wMTgcHfT8H6fpbt98PFuDUwFg2YA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=20.18.1"
"node": ">=22.19.0"
}
},
"node_modules/undici-types": {
+9 -9
View File
@@ -1,7 +1,7 @@
{
"name": "3x-ui-frontend",
"private": true,
"version": "0.4.3",
"version": "0.6.0",
"type": "module",
"description": "3x-ui panel frontend (React 19 + Ant Design 6 + Vite 8).",
"engines": {
@@ -30,7 +30,7 @@
"@ant-design/icons": "^6.3.2",
"@codemirror/lang-json": "^6.0.2",
"@codemirror/theme-one-dark": "^6.1.3",
"@hookform/resolvers": "^5.4.3",
"@hookform/resolvers": "^5.5.7",
"@noble/hashes": "^2.2.0",
"@tanstack/react-query": "^5.101.4",
"@tanstack/react-query-devtools": "^5.101.4",
@@ -51,10 +51,10 @@
},
"devDependencies": {
"@eslint/js": "^10.0.1",
"@storybook/addon-a11y": "^10.5.4",
"@storybook/addon-docs": "^10.5.4",
"@storybook/addon-vitest": "^10.5.4",
"@storybook/react-vite": "^10.5.4",
"@storybook/addon-a11y": "^10.5.5",
"@storybook/addon-docs": "^10.5.5",
"@storybook/addon-vitest": "^10.5.5",
"@storybook/react-vite": "^10.5.5",
"@testing-library/dom": "^10.4.1",
"@testing-library/react": "^16.3.2",
"@types/react": "^19.2.17",
@@ -66,13 +66,13 @@
"eslint": "^10.8.0",
"eslint-plugin-jsx-a11y": "^6.10.2",
"eslint-plugin-react-hooks": "^7.1.1",
"globals": "^17.7.0",
"globals": "^17.8.0",
"husky": "^9.1.7",
"jsdom": "^29.1.1",
"jsdom": "^30.0.1",
"lint-staged": "^17.2.0",
"msw": "^2.15.0",
"playwright": "^1.62.0",
"storybook": "^10.5.4",
"storybook": "^10.5.5",
"typescript": "6.0.3",
"typescript-eslint": "^8.65.0",
"vite": "8.1.5",
+1 -1
View File
@@ -47,7 +47,7 @@ export default function DnsTab({ templateSettings, setTemplateSettings }: DnsTab
const lastWrittenHostsRef = useRef<string | null>(null);
useEffect(() => {
if (!dns) {
if (!dnsEnabled) {
lastWrittenHostsRef.current = '{}';
setHostsList([]);
return;
+4 -4
View File
@@ -13,14 +13,14 @@ require (
github.com/google/uuid v1.6.0
github.com/gorilla/websocket v1.5.3
github.com/joho/godotenv v1.5.1
github.com/mattn/go-sqlite3 v1.14.48
github.com/mattn/go-sqlite3 v1.14.49
github.com/mymmrac/telego v1.11.1
github.com/nicksnyder/go-i18n/v2 v2.6.1
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
github.com/robfig/cron/v3 v3.0.1
github.com/shirou/gopsutil/v4 v4.26.6
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
github.com/valyala/fasthttp v1.72.0
github.com/valyala/fasthttp v1.73.0
github.com/xlzd/gotp v0.1.0
github.com/xtls/xray-core v1.260327.1-0.20260728075948-5ca6f4b7d4dc
go.uber.org/atomic v1.11.0
@@ -99,7 +99,7 @@ require (
go.mongodb.org/mongo-driver/v2 v2.8.0 // indirect
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect
golang.org/x/arch v0.29.0 // indirect
golang.org/x/exp v0.0.0-20260718201538-764159d718ef // indirect
golang.org/x/exp v0.0.0-20260727155853-b88d891fe743 // indirect
golang.org/x/mod v0.38.0 // indirect
golang.org/x/net v0.57.0
golang.org/x/sync v0.22.0 // indirect
@@ -108,7 +108,7 @@ require (
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
golang.zx2c4.com/wireguard v0.0.0-20260522210424-ecfc5a8d5446 // indirect
golang.zx2c4.com/wireguard/windows v1.0.1 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260724162435-b2f20204f0df // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260729162451-8efbd57d26e0 // indirect
google.golang.org/protobuf v1.36.11
gvisor.dev/gvisor v0.0.0-20260122175437-89a5d21be8f0 // indirect
lukechampine.com/blake3 v1.4.1 // indirect
+8 -8
View File
@@ -129,8 +129,8 @@ github.com/lufia/plan9stats v0.0.0-20260627054121-477a66015f15 h1:YkjVPl/YH5XlJ+
github.com/lufia/plan9stats v0.0.0-20260627054121-477a66015f15/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg=
github.com/mattn/go-isatty v0.0.24 h1:tGZZoVgT/KiqK1c8ocVLeDS8BSWMRd47J3Lbz7vsReI=
github.com/mattn/go-isatty v0.0.24/go.mod h1:nMCL3Zebbrt45jsMDgnfIwz6ydEQApk5oEI3HqDio6A=
github.com/mattn/go-sqlite3 v1.14.48 h1:7XHIgl0a8HwOaiK4E47ozLkST78rR9+OtNGx27D/TFs=
github.com/mattn/go-sqlite3 v1.14.48/go.mod h1:6JTjA44L93a0QCyJef5YvlPoKXntQPjzWv5gtm9sB6w=
github.com/mattn/go-sqlite3 v1.14.49 h1:B8jBHC3xhxZgxztrgruTuLucebnULQnx4W7cF7SAE9w=
github.com/mattn/go-sqlite3 v1.14.49/go.mod h1:6JTjA44L93a0QCyJef5YvlPoKXntQPjzWv5gtm9sB6w=
github.com/miekg/dns v1.1.72 h1:vhmr+TF2A3tuoGNkLDFK9zi36F2LS+hKTRW0Uf8kbzI=
github.com/miekg/dns v1.1.72/go.mod h1:+EuEPhdHOsfk6Wk5TT2CzssZdqkmFhf8r+aVyDEToIs=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -204,8 +204,8 @@ github.com/ugorji/go/codec v1.3.1 h1:waO7eEiFDwidsBN6agj1vJQ4AG7lh2yqXyOXqhgQuyY
github.com/ugorji/go/codec v1.3.1/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.72.0 h1:R7kYdoWhn1ye1fVpP+cDHDJwYm3NkwLliwgzJ/Abg7M=
github.com/valyala/fasthttp v1.72.0/go.mod h1:zsbLTYqcpIktdQytlVBwIjY9La5d6bs990nBxWg8efk=
github.com/valyala/fasthttp v1.73.0 h1:ocTOORnBWtJ+P8t/6wAjdkchMzdfHmWx2VD/DPbgZ7s=
github.com/valyala/fasthttp v1.73.0/go.mod h1:EtXQDHaR+5P18p8wqDRFpUhxr108Ga9mXvVJXHRrN2k=
github.com/valyala/fastjson v1.6.10 h1:/yjJg8jaVQdYR3arGxPE2X5z89xrlhS0eGXdv+ADTh4=
github.com/valyala/fastjson v1.6.10/go.mod h1:e6FubmQouUNP73jtMLmcbxS6ydWIpOfhz34TSfO3JaE=
github.com/vishvananda/netlink v1.3.1 h1:3AEMt62VKqz90r0tmNhog0r/PpWKmrEShJU0wJW6bV0=
@@ -250,8 +250,8 @@ golang.org/x/arch v0.29.0 h1:8sSET5wB0+exBm0FGmOtdHMqjlRdV2DRD3/IV6OZgho=
golang.org/x/arch v0.29.0/go.mod h1:0X+GdSIP+kL5wPmpK7sdkEVTt2XoYP0cSjQSbZBwOi8=
golang.org/x/crypto v0.54.0 h1:YLIA59K4fiNzHzjnZt2tUJQjQtUWfWbeHBqKtk3eScw=
golang.org/x/crypto v0.54.0/go.mod h1:KWL8ny2AZdGR2cWmzeHrp2azQPGogOv+HeQaVEXC2dk=
golang.org/x/exp v0.0.0-20260718201538-764159d718ef h1:LkZ48HFgy/TvhTI0bcWkjgFkgLyKUwcTbDjS0DUjw+A=
golang.org/x/exp v0.0.0-20260718201538-764159d718ef/go.mod h1:EdfpwwqSu+0Li0mzskwHU6FWDV3t9Q+RZDo3QMUtL3Q=
golang.org/x/exp v0.0.0-20260727155853-b88d891fe743 h1:ex206bKw+v3K0dm3andkrIF+ijyQKJG1pLgwQ2PYdQM=
golang.org/x/exp v0.0.0-20260727155853-b88d891fe743/go.mod h1:EdfpwwqSu+0Li0mzskwHU6FWDV3t9Q+RZDo3QMUtL3Q=
golang.org/x/mod v0.38.0 h1:MECBjubtXD7yj4HrhIUcywNaGeNVUdfVnxmPajOk4yk=
golang.org/x/mod v0.38.0/go.mod h1:V6Xz0pq8TQ3dGqVQ1FVHuelZpAL0uNhSkk9ogYP3c40=
golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE=
@@ -279,8 +279,8 @@ golang.zx2c4.com/wireguard/windows v1.0.1 h1:eOxiDVbywPC+ZQqvdCK7x+ZwWXKbYv50TtH
golang.zx2c4.com/wireguard/windows v1.0.1/go.mod h1:+fbT3FFdX4zzYDLwJh5+HPEcNN/3HyNdzhNSVsQM+zs=
gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4=
gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260724162435-b2f20204f0df h1:O3ig1i5WDDzsVzRp+cCdgelT9vXnlnOFdlEeFtL4HCc=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260724162435-b2f20204f0df/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260729162451-8efbd57d26e0 h1:mJiOtnGp0k/BcSgdu03G2NwnscCfCH+h2QKUBZr18KI=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260729162451-8efbd57d26e0/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE=
google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA=
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
+1 -1
View File
@@ -35,7 +35,7 @@ func TestBackupSQLiteProducesValidSnapshotDuringWrites(t *testing.T) {
firstWrite := make(chan error, 1)
writesDone := make(chan error, 1)
go func() {
for i := 0; i < 128; i++ {
for i := range 128 {
if err := db.Create(&model.Setting{Key: fmt.Sprintf("backup-write-%d", i), Value: value}).Error; err != nil {
if i == 0 {
firstWrite <- err
+4 -8
View File
@@ -43,11 +43,9 @@ func TestFetchSubscriptionLinksSharesConcurrentRefresh(t *testing.T) {
results := make(chan []string, callers)
var wg sync.WaitGroup
for range callers {
wg.Add(1)
go func() {
defer wg.Done()
wg.Go(func() {
results <- fetchSubscriptionLinks(srv.URL)
}()
})
}
time.Sleep(100 * time.Millisecond)
@@ -123,11 +121,9 @@ func TestFetchSubscriptionLinksSharesStaleResultAfterRefreshFailure(t *testing.T
results := make(chan []string, callers)
var wg sync.WaitGroup
for range callers {
wg.Add(1)
go func() {
defer wg.Done()
wg.Go(func() {
results <- fetchSubscriptionLinks(staleURL)
}()
})
}
time.Sleep(100 * time.Millisecond)
+5 -9
View File
@@ -40,10 +40,6 @@ func setTrustedProxyCIDRs(t *testing.T, value string) {
}
}
func storedAs(value string) *string {
return &value
}
func TestResolveRequest_ForwardedHeaderTrust(t *testing.T) {
tests := []struct {
name string
@@ -65,7 +61,7 @@ func TestResolveRequest_ForwardedHeaderTrust(t *testing.T) {
},
{
name: "empty stored value keeps trusting forwarded headers",
stored: storedAs(""),
stored: new(""),
remoteAddr: "203.0.113.9:51000",
wantScheme: "https",
wantHost: "sub.example.net",
@@ -74,7 +70,7 @@ func TestResolveRequest_ForwardedHeaderTrust(t *testing.T) {
},
{
name: "stored shipped default keeps trusting forwarded headers",
stored: storedAs(service.DefaultTrustedProxyCIDRs),
stored: new(service.DefaultTrustedProxyCIDRs),
remoteAddr: "203.0.113.9:51000",
wantScheme: "https",
wantHost: "sub.example.net",
@@ -83,7 +79,7 @@ func TestResolveRequest_ForwardedHeaderTrust(t *testing.T) {
},
{
name: "declared boundary ignores an origin outside it",
stored: storedAs("10.0.0.0/8"),
stored: new("10.0.0.0/8"),
remoteAddr: "203.0.113.9:51000",
wantScheme: "http",
wantHost: "panel.example.com",
@@ -92,7 +88,7 @@ func TestResolveRequest_ForwardedHeaderTrust(t *testing.T) {
},
{
name: "declared boundary trusts an origin inside it",
stored: storedAs("10.0.0.0/8"),
stored: new("10.0.0.0/8"),
remoteAddr: "10.1.2.3:44000",
wantScheme: "https",
wantHost: "sub.example.net",
@@ -101,7 +97,7 @@ func TestResolveRequest_ForwardedHeaderTrust(t *testing.T) {
},
{
name: "declared boundary ignores an unparsable origin",
stored: storedAs("10.0.0.0/8"),
stored: new("10.0.0.0/8"),
remoteAddr: "not-an-ip",
wantScheme: "http",
wantHost: "panel.example.com",
@@ -8,6 +8,7 @@ import (
"crypto/x509/pkix"
"encoding/json"
"encoding/pem"
"maps"
"math/big"
"os"
"path/filepath"
@@ -256,9 +257,7 @@ func TestGoldenStreamFixturesBuildInXray(t *testing.T) {
case "stream":
stream = fixture
case "security":
for key, value := range fixture {
stream[key] = value
}
maps.Copy(stream, fixture)
case "sockopt":
stream["sockopt"] = fixture
case "finalmask":
+2 -3
View File
@@ -5,6 +5,7 @@ import (
"encoding/json"
"fmt"
"io"
"maps"
"net"
"net/http"
"net/url"
@@ -138,9 +139,7 @@ func panelUser(email string, fields map[string]any) map[string]any {
"preSharedKey": "",
"keepAlive": "",
}
for k, v := range fields {
user[k] = v
}
maps.Copy(user, fields)
return user
}