chore: add knip and remove the dead code it reports (#247)

Adds knip (pnpm knip, knip.ts covering src, scripts, perf and e2e) and runs it in the CI frontend job. Removes what it reported: the unused codemirror and @types/dompurify dependencies, exports and test hooks used nowhere (AppLogo, Tooltip, barrel re-exports, duplicate default exports of lazily loaded settings pages), the unused iterateAll helper, and the zh entry for a deleted notification. rustfmt (used by lint-staged) is ignored as a toolchain binary.

Co-authored-by: jaw52 <53564781+jaw52@users.noreply.github.com>
This commit is contained in:
Jaw
2026-10-29 23:21:56 +08:00
committed by GitHub
parent c3b3534f08
commit 5217f8570b
54 changed files with 588 additions and 351 deletions
+1
View File
@@ -82,6 +82,7 @@ jobs:
- run: pnpm typecheck
- run: pnpm lint
- run: pnpm format:check
- run: pnpm knip
- run: pnpm test
- run: pnpm build
+15
View File
@@ -0,0 +1,15 @@
import type { KnipConfig } from "knip";
const config: KnipConfig = {
// Entries come from the Vite (index.html), Vitest, Playwright and package.json script plugins.
project: ["src/**/*.{ts,tsx,css}", "scripts/**/*.ts", "perf/**/*.ts", "e2e/**/*.ts"],
ignoreExportsUsedInFile: true,
// lint-staged formats Rust files with the toolchain's rustfmt.
ignoreBinaries: ["rustfmt"],
compilers: {
// Fonts come in through `@import` in global.css.
css: (text: string) => [...text.matchAll(/(?<=@)import[^;]+/g)].join("\n"),
},
};
export default config;
+2 -2
View File
@@ -15,6 +15,7 @@
"lint": "oxlint",
"format": "oxfmt",
"format:check": "oxfmt --check",
"knip": "knip",
"typecheck": "tsrs --noEmit && tsrs -p tsconfig.node.json --noEmit && tsrs -p perf --noEmit && tsrs -p scripts --noEmit",
"gen:bindings": "cargo test -p openidea --test export_bindings",
"gen:theme-docs": "node scripts/theme/gen-docs.ts",
@@ -57,7 +58,6 @@
"@xterm/xterm": "^6.0.0",
"anser": "^2.3.5",
"clsx": "^2.1.1",
"codemirror": "^6.0.2",
"dompurify": "^3.4.17",
"emmet": "2.4.11",
"immer": "^11.1.21",
@@ -74,12 +74,12 @@
"@testing-library/jest-dom": "^7.0.1",
"@testing-library/react": "^16.3.3",
"@testing-library/user-event": "^14.6.8",
"@types/dompurify": "^3.2.0",
"@types/node": "^26.6.5",
"@types/react": "^19.1.8",
"@types/react-dom": "^19.1.6",
"@vitejs/plugin-react": "^6.0.2",
"jsdom": "^30.1.3",
"knip": "^6.43.0",
"lint-staged": "^17.6.0",
"oxfmt": "^0.74.0",
"oxlint": "^1.89.0",
+557 -43
View File
@@ -77,9 +77,6 @@ importers:
clsx:
specifier: ^2.1.1
version: 2.1.1
codemirror:
specifier: ^6.0.2
version: 6.0.2
dompurify:
specifier: ^3.4.17
version: 3.4.17
@@ -116,16 +113,13 @@ importers:
version: 2.12.3
'@testing-library/jest-dom':
specifier: ^7.0.1
version: 7.0.1(@testing-library/dom@10.4.2)(vitest@5.0.5(@types/node@26.6.5)(jsdom@30.1.3)(vite@8.3.4(@types/node@26.6.5)(yaml@2.9.1)))
version: 7.0.1(@testing-library/dom@10.4.2)(vitest@5.0.5(@types/node@26.6.5)(jsdom@30.1.3)(vite@8.3.4(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1)))
'@testing-library/react':
specifier: ^16.3.3
version: 16.3.3(@testing-library/dom@10.4.2)(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)
'@testing-library/user-event':
specifier: ^14.6.8
version: 14.6.8(@testing-library/dom@10.4.2)
'@types/dompurify':
specifier: ^3.2.0
version: 3.2.0
'@types/node':
specifier: ^26.6.5
version: 26.6.5
@@ -137,10 +131,13 @@ importers:
version: 19.3.0(@types/react@19.3.0)
'@vitejs/plugin-react':
specifier: ^6.0.2
version: 6.1.2(vite@8.3.4(@types/node@26.6.5)(yaml@2.9.1))
version: 6.1.2(vite@8.3.4(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1))
jsdom:
specifier: ^30.1.3
version: 30.1.3
knip:
specifier: ^6.43.0
version: 6.43.0
lint-staged:
specifier: ^17.6.0
version: 17.6.0
@@ -161,10 +158,10 @@ importers:
version: 6.0.3
vite:
specifier: ^8.0.16
version: 8.3.4(@types/node@26.6.5)(yaml@2.9.1)
version: 8.3.4(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1)
vitest:
specifier: ^5.0.5
version: 5.0.5(@types/node@26.6.5)(jsdom@30.1.3)(vite@8.3.4(@types/node@26.6.5)(yaml@2.9.1))
version: 5.0.5(@types/node@26.6.5)(jsdom@30.1.3)(vite@8.3.4(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1))
packages:
@@ -357,6 +354,15 @@ packages:
'@emmetio/scanner@1.0.4':
resolution: {integrity: sha512-IqRuJtQff7YHHBk4G8YZ45uB9BaAGcwQeVzgj/zj8/UdOhtQpEIupUhSk8dys6spFIWVZVeK20CzGEnqR5SbqA==}
'@emnapi/core@1.11.2':
resolution: {integrity: sha512-TC8MkTuZUtcTSiFeuC0ksCh9QIJ5+F21MvZ4Wn4ORfYaFJ/0dsiudv5tVkejgwZlwQ39jL9WWDe2lz8x0WglOA==}
'@emnapi/runtime@1.11.2':
resolution: {integrity: sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA==}
'@emnapi/wasi-threads@1.2.2':
resolution: {integrity: sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==}
'@exodus/bytes@1.16.0':
resolution: {integrity: sha512-IcpW84uEn3N7ETtNZMlxKhfl6Pec8rUNGOTBtWbK1FKhJxIFAptZyVrvVRVBimAJxJCgc3PxepxkdWWG4DVzfA==}
engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
@@ -461,9 +467,244 @@ packages:
resolution: {integrity: sha512-j37dj/h6p6pots1L7pLPPNuABEEu9WP4OYg9pW1g+nYG331j0+3canE9OagtYdytYvdSAMG+2fKU5cxep6LgjA==}
engines: {node: '>=22.12.0'}
'@napi-rs/wasm-runtime@1.2.6':
resolution: {integrity: sha512-mRyDmEw9/fCDXCGfL1sbgIw/GUK0PVxRW4YwgPN61F3LQ+fSyoBFarJVzgGyhF6kRzEQZ0FejDqm4WLXSeqQmw==}
engines: {node: ^20.19.0 || ^22.13.0 || >=23.5.0}
peerDependencies:
'@emnapi/core': ^1.7.1 || 2.0.0-beta.2
'@emnapi/runtime': ^1.7.1 || 2.0.0-beta.2
'@oxc-parser/binding-android-arm-eabi@0.155.0':
resolution: {integrity: sha512-A6xv7hDtnTm+xlZ7utn6rRQpRMJHRhVr3gjRGqlx0RUX84mNk0pAsy6YN/wWhuOTkaZhRrrzaLxf0NfbH77j2w==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [android]
'@oxc-parser/binding-android-arm64@0.155.0':
resolution: {integrity: sha512-T1wWwH9/JI5g7Z4kEQwDOwhToxdDhRyOTklH+uuNpJ16m3MZFmGl+l2rKc0NHQdbVRG2LTOBsNjpW3h1BWytPA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [android]
'@oxc-parser/binding-darwin-arm64@0.155.0':
resolution: {integrity: sha512-ZoRB3qJxJ8DWA41jHja+YeB0lLfjBy4T+Kr15vnN1k65X3zbJt3rPZftEwN4Ju4tmA4K/T9dWWD7Z8ewQLnrVA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [darwin]
'@oxc-parser/binding-darwin-x64@0.155.0':
resolution: {integrity: sha512-vxtL86BtM+IgrpejA86nbTk5j0HKTIMeuaJ1fQciw6p9RfavPtIPjI7gN34owap0yG9txXBaAWpGdxokNwdqIw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [darwin]
'@oxc-parser/binding-freebsd-x64@0.155.0':
resolution: {integrity: sha512-tN6Ru5e0UVnWaIuiH8jEwnvxuxg7FvhWwSd3oe5oDhOD4ObsSr9/N6WfHLjilUWlPPj65ptwrSDH0Y7lzwTzmw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [freebsd]
'@oxc-parser/binding-linux-arm-gnueabihf@0.155.0':
resolution: {integrity: sha512-h4ozA5n6L6lwolsz9iwunEhKWnIVbmFRots5QxEix0H6nJ5ICpuDa7PuShuhfpIDFe3+Qvyscioyiv+9g+4Syg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [linux]
'@oxc-parser/binding-linux-arm-musleabihf@0.155.0':
resolution: {integrity: sha512-058/+LardpfuUlsKIvBGk/CYoakEVcMgqYx8GgyUZeOxFWTojYLlCc1Gb60/y21v3esDhHidgiY/Zbq9LpBhaQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [linux]
'@oxc-parser/binding-linux-arm64-gnu@0.155.0':
resolution: {integrity: sha512-nrOt2Y3xIAzu+lSPzH0864ieO+iCCXgoo9qFlGANE8Xh0cQ+RP8Wstfp+/wXN2YCyb98cAGzX0VruKYw7it/jw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@oxc-parser/binding-linux-arm64-musl@0.155.0':
resolution: {integrity: sha512-KYAayyN5hQbJPtGKtRxlyc8XYmyntOplyXSQzTDrmbz7l/GCrzQbSswvyJFBTH1LGtsZrbXOAfN52i/Kz6kLKg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
libc: [musl]
'@oxc-parser/binding-linux-ppc64-gnu@0.155.0':
resolution: {integrity: sha512-CSuSY5hfjtsBnHXydOj8jiNfS1qHbdPZuPz1YL1cSgK7VmNYP+QlZIbG0BBYYBgX/vYEgZwbG9mBdW4YairZ5w==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [ppc64]
os: [linux]
libc: [glibc]
'@oxc-parser/binding-linux-riscv64-gnu@0.155.0':
resolution: {integrity: sha512-7KCfOQm+Nz2N8trAXbQkal4TQ5756WVEmhm35y816YHvyFnEfVsICsiV5k0pEszNf/fRm4cm2i6i18SJ6/iCWg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [riscv64]
os: [linux]
libc: [glibc]
'@oxc-parser/binding-linux-riscv64-musl@0.155.0':
resolution: {integrity: sha512-JSlhgoK+/g1TGJI5NuADx2+6syhxnQNLCWLXyO5QLFyetomcr/vIxSdiNlmyAv963YXUzCuwAwRG6npZ5xyJ1A==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [riscv64]
os: [linux]
libc: [musl]
'@oxc-parser/binding-linux-s390x-gnu@0.155.0':
resolution: {integrity: sha512-WFIX+dPokWp64mi434Md3U3lJaTwNxAphvGjpltoyQjGUsdXavOIRrnp9dOS34Hd75HOAwDxAI+YwWOwqmJbtg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [s390x]
os: [linux]
libc: [glibc]
'@oxc-parser/binding-linux-x64-gnu@0.155.0':
resolution: {integrity: sha512-g6xSDC/JpbnVOz5uafMGyK3txBVRFMQTx8opv/yHXGxqV3ZMVl3bf7W8XrSnF68dmy3gM4dgReNryuE53+WkeQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
libc: [glibc]
'@oxc-parser/binding-linux-x64-musl@0.155.0':
resolution: {integrity: sha512-6/4xlxKlZJWrQ0uwDFPc0H9+xLu7068CKhX3vIDW3SbvP/lVgnVuT5v6dyugeWskWpuxqF/WJ4WKwhxjU3pG2w==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
libc: [musl]
'@oxc-parser/binding-openharmony-arm64@0.155.0':
resolution: {integrity: sha512-tltklL0J0XjDxIRTBXWOBhvc2mitcmES45pIxhwDWfxRyqz7Vkeu0NekTZEIxGE4f/lXgq3vZcjjffteQOVorg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [openharmony]
'@oxc-parser/binding-win32-arm64-msvc@0.155.0':
resolution: {integrity: sha512-alAb9TzjatUEsOeoncAziUnfdTDxfyswhalFZ9sC6plUgATIUx2NIZ0+bMn6aJ28AduS1OpG/OAisr/YISn4Ig==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [win32]
'@oxc-parser/binding-win32-ia32-msvc@0.155.0':
resolution: {integrity: sha512-yc5cbSfcGmRv/KpxDFuyk8adEBaWd/9HilWvBbQ4bFbus1V2PUh2mGB2Cfq9rqZTqLeiMT8x0skV+LKp9hOMgQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [ia32]
os: [win32]
'@oxc-parser/binding-win32-x64-msvc@0.155.0':
resolution: {integrity: sha512-8heq6jGq+rfpTDRDjoQiBHw0maQZf3IXkS99pdHQZPoTL5kyF5qyPS0RidUlSdnWDIqxXb5nux7GBD9cT+imUw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [win32]
'@oxc-project/types@0.154.0':
resolution: {integrity: sha512-KYOUGQFlLWR+s4QMV2Q9ko38TZm7EdO87Qm7rvZLqk/webse/cDjtyxKhg/47l0byCbs/k46LT8qc4PKjAikzA==}
'@oxc-project/types@0.155.0':
resolution: {integrity: sha512-SeE8JPwW1xs1tHeNycjUtUBdhorRa8o4jlvjwk49R7/Z291i+4DQa7JJIgOm/TaYQZx+QrPQbVJ/9c8dMIZN8Q==}
'@oxc-resolver/binding-android-arm-eabi@11.24.2':
resolution: {integrity: sha512-y09e0L0SRI2OA2tUIrjBgoV3eH5hvUKXNkJqXmNo5V2WxIjyC7I7aJfRLMEVpA8yi95f90gFDvO0VMgrDw+vwA==}
cpu: [arm]
os: [android]
'@oxc-resolver/binding-android-arm64@11.24.2':
resolution: {integrity: sha512-cl4icWaZFnLdg8m6qtnh5rBMuGbxc/ptStFHLeCNwr+2cZjkjNwQu/jYRS0CHlnPecOJMpuS5M6/BH+0J/YkEg==}
cpu: [arm64]
os: [android]
'@oxc-resolver/binding-darwin-arm64@11.24.2':
resolution: {integrity: sha512-At29QEMF6HajbQvgY8K6OXnHD1x9rad74xBEfmCB6ZqCGsdq75aK7tOYcTbOanMy8qdIBrfL3SMr3p/lfSlb9w==}
cpu: [arm64]
os: [darwin]
'@oxc-resolver/binding-darwin-x64@11.24.2':
resolution: {integrity: sha512-A5Kqr1EUj4oIL5CF4WRssq/o5P0Y11cwoFouMRmQ7YnC/A8V93nv1nb7aSU8HwcgmXropjLNkVTl4MN87cu28Q==}
cpu: [x64]
os: [darwin]
'@oxc-resolver/binding-freebsd-x64@11.24.2':
resolution: {integrity: sha512-R5xkRBRRz7ceH/P5Jrc6G7FmdUdgpLYyESFAUDVTNQ9K0sGPxcp4ljiwEwEqsvNcQ4sYbMRrWcHHBCu7ksAJVw==}
cpu: [x64]
os: [freebsd]
'@oxc-resolver/binding-linux-arm-gnueabihf@11.24.2':
resolution: {integrity: sha512-k/RuYL4L/R58IBn3wT5ma3Wh4k62bp1eYCFRWCmMsasUOqL+H6sW0VGFadEzKWXFFlz+2uIMoeMk9ySSZJHgbg==}
cpu: [arm]
os: [linux]
'@oxc-resolver/binding-linux-arm-musleabihf@11.24.2':
resolution: {integrity: sha512-bnHAak3ujYfH5pKk4NieFNbvYvernfoQDgwLddbZ3OtMYrem87/qjlA+u+aKG0oZcqSLGCful/6/CEA+aeAgaA==}
cpu: [arm]
os: [linux]
'@oxc-resolver/binding-linux-arm64-gnu@11.24.2':
resolution: {integrity: sha512-vDT3KHgzYp47gmtNOqL2VNhCyl5Zv643eyxm//A68J8DeUGXrvD1pZFiaT4jSfe+RInfnn1R2yVHye4enx6RnA==}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@oxc-resolver/binding-linux-arm64-musl@11.24.2':
resolution: {integrity: sha512-+kMlQvbzfyEYtu5FcjE4p+ttBLpKW4d/AsAsuE69BxV6V4twZJeIQZFfD8gh/wqglY0MkPSezWXQH0jBV13MUw==}
cpu: [arm64]
os: [linux]
libc: [musl]
'@oxc-resolver/binding-linux-ppc64-gnu@11.24.2':
resolution: {integrity: sha512-shjfMhmZ3gq9fv/w7bi3PnZlgOPG+2QAOFf0BJF0EgBSIGZ6PMLN2zbGEblTUYB/NKVDRyYhE2ff3dJ1QqNPkA==}
cpu: [ppc64]
os: [linux]
libc: [glibc]
'@oxc-resolver/binding-linux-riscv64-gnu@11.24.2':
resolution: {integrity: sha512-zGelwFR5oRo+b69k8Lrzun86DyUHzfKN6cnjbR9l7Z7NIRznOE/2ZvPa1IUKqAL2PzAXOdwkfVqNvO1H2RlpAw==}
cpu: [riscv64]
os: [linux]
libc: [glibc]
'@oxc-resolver/binding-linux-riscv64-musl@11.24.2':
resolution: {integrity: sha512-qxZ1SWCXJY0eyhAlP6Lmo9F2Nrtx7EkYj9oCgL8apDPCwXwCEDA2U697bbT81JIc2IrVjxO4KX6WU2N+oN9Z4w==}
cpu: [riscv64]
os: [linux]
libc: [musl]
'@oxc-resolver/binding-linux-s390x-gnu@11.24.2':
resolution: {integrity: sha512-sGCecF3cx2DFlH4t/z7ApnOnXqN48p5p5mlHDEnHTAukQa2P+qMVE4CwyWE9W+q/m3QJ7kKfGrIjax31f44oFQ==}
cpu: [s390x]
os: [linux]
libc: [glibc]
'@oxc-resolver/binding-linux-x64-gnu@11.24.2':
resolution: {integrity: sha512-k/VlMMcSzMlahb3/fENM4rTlsJ0s3fFROA0KXPBmKggqmTSaE383sl8F3KCOXPLmVsYfW6hCitMhXCEtNeZxxg==}
cpu: [x64]
os: [linux]
libc: [glibc]
'@oxc-resolver/binding-linux-x64-musl@11.24.2':
resolution: {integrity: sha512-8hbnZyNi97b/8wapYaIF9+t9GmZKBW2vunaOc3h9HGJptH7b7XpvZqOTBSm/MpTjr7H497BlgOaSfLUdhmy2bw==}
cpu: [x64]
os: [linux]
libc: [musl]
'@oxc-resolver/binding-openharmony-arm64@11.24.2':
resolution: {integrity: sha512-MvyGik3a6pVgZ0t/kWlbmFxFLmXQJwgLsY2eYFHLpy0wGwRbfzeIGgDwQ3kXqE30z+kSXennRkCrT7TUvkptNg==}
cpu: [arm64]
os: [openharmony]
'@oxc-resolver/binding-wasm32-wasi@11.24.2':
resolution: {integrity: sha512-vHcssMPwO08RTvj/c0iOBz90attxyG3wQJ0dTcyEQK43LRpcdLWZlV5feBhv6Isn6ahbQIzHbCgfa81+RiML0Q==}
engines: {node: '>=14.0.0'}
cpu: [wasm32]
'@oxc-resolver/binding-win32-arm64-msvc@11.24.2':
resolution: {integrity: sha512-uokJqro2iBqkFvJdKQLP7d8/BUmFwESQFVmIJUQKj1Xn1a/LysJoe1vmeECLF5b3jsV8CAL5sEMJXX6SdK9Nhg==}
cpu: [arm64]
os: [win32]
'@oxc-resolver/binding-win32-x64-msvc@11.24.2':
resolution: {integrity: sha512-UqGPmo56KDfLlfXFAFIrNflHT8tFxWGEivWg3Zeyp4Uy2NlKN1FGPr6/BxcLGG3+kZ6Wp14g5Uj+n71boqZfiw==}
cpu: [x64]
os: [win32]
'@oxfmt/binding-android-arm-eabi@0.74.0':
resolution: {integrity: sha512-xxQwrf5EPI5zxvuCTW8r6tzCTjPQ+h6+HqJ0iRKRy2zS1yBllt/xLVjoIyUc+FnR7g0a5g1SZv2yyDYhTItLbA==}
engines: {node: ^20.19.0 || >=22.12.0}
@@ -999,6 +1240,9 @@ packages:
cpu: [x64]
os: [win32]
'@tybys/wasm-util@0.10.4':
resolution: {integrity: sha512-W3c4gRigFS0T/Ma4qIYF3GDAc5AQdHb1yL5znJT1Zv1YaD9Kitx656wBjvr19qbiosmZT8lWDM5BEMynUqX65A==}
'@types/aria-query@5.0.4':
resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==}
@@ -1101,10 +1345,6 @@ packages:
'@types/deep-eql@4.0.2':
resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==}
'@types/dompurify@3.2.0':
resolution: {integrity: sha512-Fgg31wv9QbLDA0SpTOXO3MaxySc4DKGLi8sna4/Utjo4r3ZRPdCt4UQee8BWr+Q5z21yifghREPJGYaEOEIACg==}
deprecated: This is a stub types definition. dompurify provides its own type definitions, so you do not need this installed.
'@types/estree@1.0.9':
resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==}
@@ -1204,9 +1444,6 @@ packages:
resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
engines: {node: '>=6'}
codemirror@6.0.2:
resolution: {integrity: sha512-VhydHotNW5w1UGK0Qj96BwSk/Zqbp9WbnyK2W/eVMv4QyF41INRGpjUhFJY7/uDNuudSc33a/PKr4iDqRduvHw==}
commander@7.2.0:
resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==}
engines: {node: '>= 10'}
@@ -1443,6 +1680,9 @@ packages:
resolution: {integrity: sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==}
engines: {node: '>=12.0.0'}
fd-package-json@2.0.0:
resolution: {integrity: sha512-jKmm9YtsNXN789RS/0mSzOC1NUq9mkVd65vbSSVsKdjGvYXBuE4oWe2QOEoFeRmJg+lPuZxpmrfFclNhoRMneQ==}
fdir@6.5.0:
resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
engines: {node: '>=12.0.0'}
@@ -1452,11 +1692,19 @@ packages:
picomatch:
optional: true
formatly@0.11.4:
resolution: {integrity: sha512-TeCC10lP8KCgoX+Fe5lryILIT0/Dy+nP0OSVnsuB5CwXoLuOdqxCYlPFF1inR8S/zTy1ec7TjhS2TeRKWzzImA==}
engines: {node: '>=18.14.0'}
hasBin: true
fsevents@2.3.3:
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
os: [darwin]
get-tsconfig@4.14.3:
resolution: {integrity: sha512-++QEw4DIY7WGoukz+/+A/8dGYPT9l9yIadnmSgZ8Rjr3YVSVDipQSO9CdnJo9ePqFqUUqh+wk9uIaoiAwsiPkA==}
hachure-fill@0.5.2:
resolution: {integrity: sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==}
@@ -1488,6 +1736,10 @@ packages:
is-potential-custom-element-name@1.0.1:
resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==}
jiti@2.7.0:
resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==}
hasBin: true
js-tokens@4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
@@ -1507,6 +1759,11 @@ packages:
khroma@2.1.0:
resolution: {integrity: sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==}
knip@6.43.0:
resolution: {integrity: sha512-8l3cCOg/EXoILO0qcSoMra49yQM91+lEIR4fu5Ko8rrArGX8xKdKZiGI9psPiY6rhLmfLERcMfFEByF0wli5CA==}
engines: {node: ^20.19.0 || >=22.12.0}
hasBin: true
layout-base@1.0.2:
resolution: {integrity: sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==}
@@ -1636,6 +1893,13 @@ packages:
resolution: {integrity: sha512-5vvB5+W7ePv+p3uqxi+RcW1XAzLW0/hxt3/4X4Lc4qHudzOhmBiBwOY6DRob4WnanAEGvNcLjF+KNOufrUoEQw==}
engines: {node: '>=12.20.0'}
oxc-parser@0.155.0:
resolution: {integrity: sha512-C/ReSf1JUFukK/zvk6jhcNibSssvas5+ktIzK7fbKVd3CedWe59C3QwHEOrEZj/4Rt9+xg0Jeis/Jv1F/KM1mw==}
engines: {node: ^20.19.0 || >=22.12.0}
oxc-resolver@11.24.2:
resolution: {integrity: sha512-FY91FiDBj7ls5MsFS9jN3tjz2o0/zsdSsymlakySaBwVJZorHhkWyICLZMKxlu1R9vYo+sd3z1jwb4J8x7bNDw==}
oxfmt@0.74.0:
resolution: {integrity: sha512-G4OP7FgwGYZR5ttRpCOOfJdyRsSyvtn34vSXnjDq6Oqed5Dufg5mB44mank+51nAdHOKuTJ0lj0mksY7L+N61A==}
engines: {node: ^20.19.0 || >=22.12.0}
@@ -1735,6 +1999,9 @@ packages:
resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
engines: {node: '>=0.10.0'}
resolve-pkg-maps@1.0.0:
resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
robust-predicates@3.0.3:
resolution: {integrity: sha512-NS3levdsRIUOmiJ8FZWCP7LG3QpJyrs/TE0Zpf1yvZu8cAJJ6QMW92H1c7kWpdIHo8RvmLxN/o2JXTKHp74lUA==}
@@ -1763,6 +2030,10 @@ packages:
resolution: {integrity: sha512-kkTORPAuxQz2g1QUuN0J8yGWT28tjGBfPOdJ4xT7Vbeu30veKUZQIoID2qGgCDAakaQn59UeZJJ4cFGB8PVP2A==}
hasBin: true
smol-toml@1.9.1:
resolution: {integrity: sha512-j7WyPdf0CJoutMzMoPLF/bVXHtKZIT9Rb4eGeEbWw8X2t5oirjPgpL+OpaENZrILYaXqYwnVH+qgUwVbl+pUJQ==}
engines: {node: '>= 18'}
source-map-js@1.2.2:
resolution: {integrity: sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==}
engines: {node: '>=0.10.0'}
@@ -1778,6 +2049,10 @@ packages:
resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==}
engines: {node: '>=8'}
strip-json-comments@5.0.3:
resolution: {integrity: sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==}
engines: {node: '>=14.16'}
style-mod@4.1.4:
resolution: {integrity: sha512-XXWIQt633/EpAFx8aZDOTjBzrCaGmhvEQlQo6MVPfa2OzO2cWo+4hV9h+6UkHYlXGfy+ODXKUdP7Pthmcu5ATw==}
@@ -1819,6 +2094,9 @@ packages:
resolution: {integrity: sha512-JfJeIHke7y2egdGGgRAvpCwYFUsHlM2gPcrVOxFkznt/4uzQ7HFmvE63iFHVLBJNDuyDOQgijDK/tXH/f6Msjg==}
engines: {node: '>=6.10'}
tslib@2.8.1:
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
tsrs@0.20.0-ts7.1.0-beta:
resolution: {integrity: sha512-8NifAn2tcna3t/nluu1yFvp0fYE28vElDpnD4jiWik69+MDjiHgxdjH8sUYUEFmf/2hl6QIE5ExVGpJzQbBDPw==}
engines: {node: '>=16.20.0'}
@@ -1829,6 +2107,10 @@ packages:
engines: {node: '>=14.17'}
hasBin: true
unbash@6.0.1:
resolution: {integrity: sha512-0db9eS5iqybux41zLkX69nk90KTci7F7eZ+gXzEG/Q7E0tAqEBhRh5fkZvk1N7jT7QkGWqq34i8SFGPFEe1V8A==}
engines: {node: '>=14'}
undici-types@8.9.0:
resolution: {integrity: sha512-KTDyRTYX8sWmKXAikPHHSyc63CRPETMctyjKFupcC6OBLXT3xsN0e9aF7m+mIXutFWpUXuedtowG7iLOzp0kQg==}
@@ -1931,6 +2213,10 @@ packages:
resolution: {integrity: sha512-4Nsy8K5Tr6SPDH9jhKJOHf7ChDrc1zufZTVSF7x72hwuEXBqxqk9G6cK+K2NRUtB3iELRJqjXb4JPDMBjMTl2Q==}
engines: {node: ^22.22.2 || ^24.15.0 || >=26.0.0}
walk-up-path@4.0.0:
resolution: {integrity: sha512-3hu+tD8YzSLGuFYtPRb48vdhKMi0KQV5sn+uWr8+7dMEq/2G/dtLrdDinkLjqq5TIbIBjYJ4Ax/n3YiaW7QM8A==}
engines: {node: 20 || >=22}
webidl-conversions@8.0.1:
resolution: {integrity: sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==}
engines: {node: '>=20'}
@@ -1960,6 +2246,9 @@ packages:
engines: {node: '>= 14.6'}
hasBin: true
zod@4.6.7:
resolution: {integrity: sha512-g8W2D2kU6a8untc053fX1uVBKzM7yqAxW/3zwk83+6RyF2+SKOuV+c0wBDhUwzV1PaGapmZH+rmcUzPf+3CGwg==}
zustand@5.0.15:
resolution: {integrity: sha512-MpSEjRiBkA9crSYeOUH32rJC7SVqAbm0Fqcqge/bUi2PPoLcBWKOsG+C8mevmpr8TwXHBVkChbbJiyvkE+i/3A==}
engines: {node: '>=12.20.0'}
@@ -2329,6 +2618,22 @@ snapshots:
'@emmetio/scanner@1.0.4': {}
'@emnapi/core@1.11.2':
dependencies:
'@emnapi/wasi-threads': 1.2.2
tslib: 2.8.1
optional: true
'@emnapi/runtime@1.11.2':
dependencies:
tslib: 2.8.1
optional: true
'@emnapi/wasi-threads@1.2.2':
dependencies:
tslib: 2.8.1
optional: true
'@exodus/bytes@1.16.0': {}
'@floating-ui/core@1.8.0':
@@ -2468,8 +2773,135 @@ snapshots:
dependencies:
'@chevrotain/types': 13.2.0
'@napi-rs/wasm-runtime@1.2.6(@emnapi/core@1.11.2)(@emnapi/runtime@1.11.2)':
dependencies:
'@emnapi/core': 1.11.2
'@emnapi/runtime': 1.11.2
'@tybys/wasm-util': 0.10.4
optional: true
'@oxc-parser/binding-android-arm-eabi@0.155.0':
optional: true
'@oxc-parser/binding-android-arm64@0.155.0':
optional: true
'@oxc-parser/binding-darwin-arm64@0.155.0':
optional: true
'@oxc-parser/binding-darwin-x64@0.155.0':
optional: true
'@oxc-parser/binding-freebsd-x64@0.155.0':
optional: true
'@oxc-parser/binding-linux-arm-gnueabihf@0.155.0':
optional: true
'@oxc-parser/binding-linux-arm-musleabihf@0.155.0':
optional: true
'@oxc-parser/binding-linux-arm64-gnu@0.155.0':
optional: true
'@oxc-parser/binding-linux-arm64-musl@0.155.0':
optional: true
'@oxc-parser/binding-linux-ppc64-gnu@0.155.0':
optional: true
'@oxc-parser/binding-linux-riscv64-gnu@0.155.0':
optional: true
'@oxc-parser/binding-linux-riscv64-musl@0.155.0':
optional: true
'@oxc-parser/binding-linux-s390x-gnu@0.155.0':
optional: true
'@oxc-parser/binding-linux-x64-gnu@0.155.0':
optional: true
'@oxc-parser/binding-linux-x64-musl@0.155.0':
optional: true
'@oxc-parser/binding-openharmony-arm64@0.155.0':
optional: true
'@oxc-parser/binding-win32-arm64-msvc@0.155.0':
optional: true
'@oxc-parser/binding-win32-ia32-msvc@0.155.0':
optional: true
'@oxc-parser/binding-win32-x64-msvc@0.155.0':
optional: true
'@oxc-project/types@0.154.0': {}
'@oxc-project/types@0.155.0': {}
'@oxc-resolver/binding-android-arm-eabi@11.24.2':
optional: true
'@oxc-resolver/binding-android-arm64@11.24.2':
optional: true
'@oxc-resolver/binding-darwin-arm64@11.24.2':
optional: true
'@oxc-resolver/binding-darwin-x64@11.24.2':
optional: true
'@oxc-resolver/binding-freebsd-x64@11.24.2':
optional: true
'@oxc-resolver/binding-linux-arm-gnueabihf@11.24.2':
optional: true
'@oxc-resolver/binding-linux-arm-musleabihf@11.24.2':
optional: true
'@oxc-resolver/binding-linux-arm64-gnu@11.24.2':
optional: true
'@oxc-resolver/binding-linux-arm64-musl@11.24.2':
optional: true
'@oxc-resolver/binding-linux-ppc64-gnu@11.24.2':
optional: true
'@oxc-resolver/binding-linux-riscv64-gnu@11.24.2':
optional: true
'@oxc-resolver/binding-linux-riscv64-musl@11.24.2':
optional: true
'@oxc-resolver/binding-linux-s390x-gnu@11.24.2':
optional: true
'@oxc-resolver/binding-linux-x64-gnu@11.24.2':
optional: true
'@oxc-resolver/binding-linux-x64-musl@11.24.2':
optional: true
'@oxc-resolver/binding-openharmony-arm64@11.24.2':
optional: true
'@oxc-resolver/binding-wasm32-wasi@11.24.2':
dependencies:
'@emnapi/core': 1.11.2
'@emnapi/runtime': 1.11.2
'@napi-rs/wasm-runtime': 1.2.6(@emnapi/core@1.11.2)(@emnapi/runtime@1.11.2)
optional: true
'@oxc-resolver/binding-win32-arm64-msvc@11.24.2':
optional: true
'@oxc-resolver/binding-win32-x64-msvc@11.24.2':
optional: true
'@oxfmt/binding-android-arm-eabi@0.74.0':
optional: true
@@ -2722,7 +3154,7 @@ snapshots:
picocolors: 1.1.1
pretty-format: 27.5.1
'@testing-library/jest-dom@7.0.1(@testing-library/dom@10.4.2)(vitest@5.0.5(@types/node@26.6.5)(jsdom@30.1.3)(vite@8.3.4(@types/node@26.6.5)(yaml@2.9.1)))':
'@testing-library/jest-dom@7.0.1(@testing-library/dom@10.4.2)(vitest@5.0.5(@types/node@26.6.5)(jsdom@30.1.3)(vite@8.3.4(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1)))':
dependencies:
'@adobe/css-tools': 4.5.0
'@testing-library/dom': 10.4.2
@@ -2732,7 +3164,7 @@ snapshots:
picocolors: 1.1.1
redent: 3.0.0
optionalDependencies:
vitest: 5.0.5(@types/node@26.6.5)(jsdom@30.1.3)(vite@8.3.4(@types/node@26.6.5)(yaml@2.9.1))
vitest: 5.0.5(@types/node@26.6.5)(jsdom@30.1.3)(vite@8.3.4(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1))
'@testing-library/react@16.3.3(@testing-library/dom@10.4.2)(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)':
dependencies:
@@ -2769,6 +3201,11 @@ snapshots:
'@tsrs/win32-x64@0.20.0-ts7.1.0-beta':
optional: true
'@tybys/wasm-util@0.10.4':
dependencies:
tslib: 2.8.1
optional: true
'@types/aria-query@5.0.4': {}
'@types/chai@5.2.3':
@@ -2895,10 +3332,6 @@ snapshots:
'@types/deep-eql@4.0.2': {}
'@types/dompurify@3.2.0':
dependencies:
dompurify: 3.4.17
'@types/estree@1.0.9': {}
'@types/geojson@7946.0.16': {}
@@ -2923,19 +3356,19 @@ snapshots:
d3-selection: 3.0.0
d3-transition: 3.0.1(d3-selection@3.0.0)
'@vitejs/plugin-react@6.1.2(vite@8.3.4(@types/node@26.6.5)(yaml@2.9.1))':
'@vitejs/plugin-react@6.1.2(vite@8.3.4(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1))':
dependencies:
'@rolldown/pluginutils': 1.0.1
vite: 8.3.4(@types/node@26.6.5)(yaml@2.9.1)
vite: 8.3.4(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1)
'@vitest/mocker@5.0.5(vite@8.3.4(@types/node@26.6.5)(yaml@2.9.1))':
'@vitest/mocker@5.0.5(vite@8.3.4(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1))':
dependencies:
'@jridgewell/trace-mapping': 0.3.31
'@vitest/spy': 5.0.5
estree-walker: 3.0.3
magic-string: 1.4.3
optionalDependencies:
vite: 8.3.4(@types/node@26.6.5)(yaml@2.9.1)
vite: 8.3.4(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1)
'@vitest/spy@5.0.5': {}
@@ -2975,16 +3408,6 @@ snapshots:
clsx@2.1.1: {}
codemirror@6.0.2:
dependencies:
'@codemirror/autocomplete': 6.20.3
'@codemirror/commands': 6.11.1
'@codemirror/language': 6.13.1
'@codemirror/lint': 6.9.7
'@codemirror/search': 6.7.2
'@codemirror/state': 6.7.6
'@codemirror/view': 6.43.14
commander@7.2.0: {}
commander@8.3.0: {}
@@ -3238,13 +3661,26 @@ snapshots:
expect-type@1.4.0: {}
fd-package-json@2.0.0:
dependencies:
walk-up-path: 4.0.0
fdir@6.5.0(picomatch@4.0.7):
optionalDependencies:
picomatch: 4.0.7
formatly@0.11.4:
dependencies:
fd-package-json: 2.0.0
package-manager-detector: 1.9.0
fsevents@2.3.3:
optional: true
get-tsconfig@4.14.3:
dependencies:
resolve-pkg-maps: 1.0.0
hachure-fill@0.5.2: {}
html-encoding-sniffer@7.0.0:
@@ -3269,6 +3705,8 @@ snapshots:
is-potential-custom-element-name@1.0.1: {}
jiti@2.7.0: {}
js-tokens@4.0.0: {}
jsdom@30.1.3:
@@ -3302,6 +3740,21 @@ snapshots:
khroma@2.1.0: {}
knip@6.43.0:
dependencies:
formatly: 0.11.4
get-tsconfig: 4.14.3
jiti: 2.7.0
oxc-parser: 0.155.0
oxc-resolver: 11.24.2
picomatch: 4.0.7
smol-toml: 1.9.1
strip-json-comments: 5.0.3
tinyglobby: 0.2.17
unbash: 6.0.1
yaml: 2.9.1
zod: 4.6.7
layout-base@1.0.2: {}
layout-base@2.0.1: {}
@@ -3411,6 +3864,52 @@ snapshots:
obug@3.0.0: {}
oxc-parser@0.155.0:
dependencies:
'@oxc-project/types': 0.155.0
optionalDependencies:
'@oxc-parser/binding-android-arm-eabi': 0.155.0
'@oxc-parser/binding-android-arm64': 0.155.0
'@oxc-parser/binding-darwin-arm64': 0.155.0
'@oxc-parser/binding-darwin-x64': 0.155.0
'@oxc-parser/binding-freebsd-x64': 0.155.0
'@oxc-parser/binding-linux-arm-gnueabihf': 0.155.0
'@oxc-parser/binding-linux-arm-musleabihf': 0.155.0
'@oxc-parser/binding-linux-arm64-gnu': 0.155.0
'@oxc-parser/binding-linux-arm64-musl': 0.155.0
'@oxc-parser/binding-linux-ppc64-gnu': 0.155.0
'@oxc-parser/binding-linux-riscv64-gnu': 0.155.0
'@oxc-parser/binding-linux-riscv64-musl': 0.155.0
'@oxc-parser/binding-linux-s390x-gnu': 0.155.0
'@oxc-parser/binding-linux-x64-gnu': 0.155.0
'@oxc-parser/binding-linux-x64-musl': 0.155.0
'@oxc-parser/binding-openharmony-arm64': 0.155.0
'@oxc-parser/binding-win32-arm64-msvc': 0.155.0
'@oxc-parser/binding-win32-ia32-msvc': 0.155.0
'@oxc-parser/binding-win32-x64-msvc': 0.155.0
oxc-resolver@11.24.2:
optionalDependencies:
'@oxc-resolver/binding-android-arm-eabi': 11.24.2
'@oxc-resolver/binding-android-arm64': 11.24.2
'@oxc-resolver/binding-darwin-arm64': 11.24.2
'@oxc-resolver/binding-darwin-x64': 11.24.2
'@oxc-resolver/binding-freebsd-x64': 11.24.2
'@oxc-resolver/binding-linux-arm-gnueabihf': 11.24.2
'@oxc-resolver/binding-linux-arm-musleabihf': 11.24.2
'@oxc-resolver/binding-linux-arm64-gnu': 11.24.2
'@oxc-resolver/binding-linux-arm64-musl': 11.24.2
'@oxc-resolver/binding-linux-ppc64-gnu': 11.24.2
'@oxc-resolver/binding-linux-riscv64-gnu': 11.24.2
'@oxc-resolver/binding-linux-riscv64-musl': 11.24.2
'@oxc-resolver/binding-linux-s390x-gnu': 11.24.2
'@oxc-resolver/binding-linux-x64-gnu': 11.24.2
'@oxc-resolver/binding-linux-x64-musl': 11.24.2
'@oxc-resolver/binding-openharmony-arm64': 11.24.2
'@oxc-resolver/binding-wasm32-wasi': 11.24.2
'@oxc-resolver/binding-win32-arm64-msvc': 11.24.2
'@oxc-resolver/binding-win32-x64-msvc': 11.24.2
oxfmt@0.74.0:
dependencies:
tinypool: 2.2.0
@@ -3517,6 +4016,8 @@ snapshots:
require-from-string@2.0.2: {}
resolve-pkg-maps@1.0.0: {}
robust-predicates@3.0.3: {}
rolldown@1.2.14:
@@ -3559,6 +4060,8 @@ snapshots:
simple-git-hooks@2.14.0: {}
smol-toml@1.9.1: {}
source-map-js@1.2.2: {}
std-env@4.3.0: {}
@@ -3569,6 +4072,8 @@ snapshots:
dependencies:
min-indent: 1.0.1
strip-json-comments@5.0.3: {}
style-mod@4.1.4: {}
stylis@4.4.0: {}
@@ -3600,6 +4105,9 @@ snapshots:
ts-dedent@2.3.0: {}
tslib@2.8.1:
optional: true
tsrs@0.20.0-ts7.1.0-beta:
optionalDependencies:
'@tsrs/darwin-arm64': 0.20.0-ts7.1.0-beta
@@ -3612,13 +4120,15 @@ snapshots:
typescript@6.0.3: {}
unbash@6.0.1: {}
undici-types@8.9.0: {}
undici@8.12.2: {}
uuid@14.0.3: {}
vite@8.3.4(@types/node@26.6.5)(yaml@2.9.1):
vite@8.3.4(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1):
dependencies:
lightningcss: 1.33.0
picomatch: 4.0.7
@@ -3628,12 +4138,13 @@ snapshots:
optionalDependencies:
'@types/node': 26.6.5
fsevents: 2.3.3
jiti: 2.7.0
yaml: 2.9.1
vitest@5.0.5(@types/node@26.6.5)(jsdom@30.1.3)(vite@8.3.4(@types/node@26.6.5)(yaml@2.9.1)):
vitest@5.0.5(@types/node@26.6.5)(jsdom@30.1.3)(vite@8.3.4(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1)):
dependencies:
'@types/chai': 5.2.3
'@vitest/mocker': 5.0.5(vite@8.3.4(@types/node@26.6.5)(yaml@2.9.1))
'@vitest/mocker': 5.0.5(vite@8.3.4(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1))
chai: 6.3.0
es-module-lexer: 2.3.2
expect-type: 1.4.0
@@ -3644,7 +4155,7 @@ snapshots:
tinybench: 6.2.2
tinyexec: 1.3.1
tinyglobby: 0.2.17
vite: 8.3.4(@types/node@26.6.5)(yaml@2.9.1)
vite: 8.3.4(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1)
why-is-node-running: 3.2.1
optionalDependencies:
'@types/node': 26.6.5
@@ -3658,6 +4169,8 @@ snapshots:
dependencies:
xml-name-validator: 5.0.0
walk-up-path@4.0.0: {}
webidl-conversions@8.0.1: {}
whatwg-mimetype@5.0.0: {}
@@ -3676,8 +4189,9 @@ snapshots:
xmlchars@2.2.0: {}
yaml@2.9.1:
optional: true
yaml@2.9.1: {}
zod@4.6.7: {}
zustand@5.0.15(@types/react@19.3.0)(immer@11.1.21)(react@19.3.1):
optionalDependencies:
-5
View File
@@ -528,8 +528,3 @@ let current: DocBackend | null = null;
export function docBackend(): DocBackend {
return (current ??= isTauri() ? ipcBackend : createMemoryBackend());
}
/** Test hook. */
export function _setDocBackend(b: DocBackend | null) {
current = b;
}
-13
View File
@@ -287,8 +287,6 @@ export function nextOccurrence(view: EditorView): "selected" | "added" | "notFou
return "added";
}
export const addCaretNextOccurrence: Command = (view) => nextOccurrence(view) !== "none";
/** ⌃⌘G: select every occurrence of the selection, or of the word at the caret (whole words). */
export const selectAllOccurrences: Command = (view) => {
const { state } = view;
@@ -658,17 +656,6 @@ export function completeStatement(language: string): Command {
};
}
// --- helpers -------------------------------------------------------------------
export function selectRange(view: EditorView, range: SelectionRange | { from: number; to: number }, center = true) {
view.dispatch({
selection: EditorSelection.single(range.from, range.to),
effects: center ? EditorView.scrollIntoView(range.from, { y: "center" }) : undefined,
scrollIntoView: !center,
userEvent: "select",
});
}
// --- comments ------------------------------------------------------------------------
export { commentLine } from "./comments";
+2 -2
View File
@@ -8,8 +8,8 @@ import {
insertTab,
smartBackspace,
smartBackspaceApplies,
tabOut,
tabOutOfScope,
tabOutScopes,
} from "./smartKeys";
/** One unit (2) deeper after a (non-blank) line ending in `{`, one less on a line starting with `}`. */
@@ -137,7 +137,7 @@ describe("smart backspace", () => {
});
describe("tab out of pairs", () => {
const ext = [closeBrackets(), tabOutScopes];
const ext = [closeBrackets(), tabOut];
const type = (v: EditorView, ch: string) => {
const tr = insertBracket(v.state, ch);
if (tr) v.dispatch(tr);
+1 -1
View File
@@ -105,7 +105,7 @@ interface Scope {
const leaveScopes = StateEffect.define<readonly number[]>();
/** Inside each pair the editor inserted itself; Tab at a scope's end steps over the closing character. */
export const tabOutScopes = StateField.define<readonly Scope[]>({
const tabOutScopes = StateField.define<readonly Scope[]>({
create: () => [],
update(scopes, tr) {
for (const e of tr.effects) if (e.is(leaveScopes)) scopes = scopes.filter((s) => !e.value.includes(s.to));
+1 -3
View File
@@ -4,7 +4,7 @@
* backend folding ranges, or from the syntax tree when there are none.
* Clicking a sticky line scrolls to it, the caret where it was clicked.
*/
import { Compartment, EditorSelection, Facet, type EditorState, type Extension } from "@codemirror/state";
import { EditorSelection, Facet, type EditorState, type Extension } from "@codemirror/state";
import { EditorView, ViewPlugin, type ViewUpdate } from "@codemirror/view";
import { foldNodeProp, syntaxTree } from "@codemirror/language";
import { highlightTree } from "@lezer/highlight";
@@ -250,6 +250,4 @@ class StickyScroll {
this.dom.remove();
}
}
export const stickyScrollCompartment = new Compartment();
export const stickyScroll: Extension = ViewPlugin.fromClass(StickyScroll);
-5
View File
@@ -1350,11 +1350,6 @@ export function editorController(): EditorController {
return (controller ??= new EditorController());
}
/** Test hook. */
export function _setEditorController(c: EditorController | null) {
controller = c;
}
/** "Finder" / "Explorer" / "Files", like IDEA's Open In submenu. */
function revealLabel(): string {
const os = usePlatform.getState().os;
-13
View File
@@ -69,11 +69,6 @@ export function paneOf(s: TabsState, paneId: string): Pane {
return p;
}
export function activeTab(s: TabsState, paneId = s.activePane): Tab | null {
const p = s.panes[paneId];
return p?.tabs.find((t) => t.id === p.active) ?? null;
}
export function findTab(s: TabsState, key: string, paneId?: string): { paneId: string; tab: Tab } | null {
const order = paneId ? [paneId, ...paneIds(s).filter((p) => p !== paneId)] : paneIds(s);
for (const id of order) {
@@ -298,14 +293,6 @@ export function closeKey(s: TabsState, key: string): TabsState {
return next;
}
/** Re-keys tabs after a rename / move. */
export function rekey(s: TabsState, fromKey: string, input: EditorInput): TabsState {
const panes: Record<string, Pane> = {};
for (const [id, p] of Object.entries(s.panes))
panes[id] = { ...p, tabs: p.tabs.map((t) => (t.input.key === fromKey ? { ...t, input } : t)) };
return { ...s, panes };
}
export function reopenClosed(s: TabsState): { state: TabsState; tabId: string; paneId: string } | null {
const openNow = openKeys(s);
const closed = [...s.closed];
-3
View File
@@ -14,9 +14,6 @@ export type MarkerKind = "implemented" | "overridden" | "implementing" | "overri
/** Settings › Gutter Icons groups: ↓ markers and ↑ markers. */
export type MarkerGroup = "inheritors" | "supers";
export const markerGroup = (kind: MarkerKind): MarkerGroup =>
kind === "implemented" || kind === "overridden" ? "inheritors" : "supers";
export const MARKER_ICONS: Record<MarkerKind, string> = {
implemented: "gutter-implemented",
overridden: "gutter-overridden",
+1 -14
View File
@@ -1,15 +1,2 @@
/**
* Refactorings: Refactor This and the Refactor menu over LSP code actions,
* Safe Delete, and the syntax-based fallbacks used when the language server
* is not usable (see `@/editor/structure`).
*/
export { introduceFallback, type FallbackReason, type IntroduceKind } from "./introduce";
export { refactorThis, runRefactoring, showNothingHere } from "./refactorThis";
export {
askUsagesDetected,
fileUsages,
safeDelete,
viewUsages,
type FileUsages,
type UsagesAnswer,
} from "./safeDelete";
export { askUsagesDetected, fileUsages, safeDelete, viewUsages } from "./safeDelete";
-3
View File
@@ -43,12 +43,9 @@ export type {
Locals,
LocalSymbol,
NodeAt,
NotLocalReason,
StructuralRanges,
StructureSupport,
SyntaxError,
SyntaxErrors,
SyntaxNode,
} from "@/bindings";
export interface QueryOptions {
-6
View File
@@ -169,9 +169,3 @@ export function installCloseGuard(deps: CloseDeps = defaultDeps): () => void {
unsubs.forEach((u) => u());
};
}
/** Tests only. */
export function _setDirtyForTests(ids: number[]) {
dirtyDocs.clear();
ids.forEach((i) => dirtyDocs.add(i));
}
@@ -21,11 +21,6 @@ function load() {
.finally(() => (loading = false));
}
/** For tests: languages that have a debugger (`null` = unknown, allow everything). */
export function _setDebuggableLanguages(ids: Iterable<string> | null) {
debuggable = ids ? new Set(ids) : null;
}
/** Whether a new breakpoint may be placed in a file of `language`. */
export function canPlaceBreakpoint(language: string): boolean {
if (workflowSettings().debugger.breakpointsAnyFile) return true;
@@ -229,10 +229,3 @@ export function setMuted(muted: boolean) {
persist();
for (const path of Object.keys(useBreakpoints.getState().byFile)) scheduleSync(path);
}
export function allBreakpoints(): Array<{ path: string; bp: BreakpointEntry }> {
const { byFile } = useBreakpoints.getState();
return Object.keys(byFile)
.sort()
.flatMap((path) => byFile[path]!.map((bp) => ({ path, bp })));
}
-6
View File
@@ -62,12 +62,6 @@ export interface ConsoleLine {
spans: Span[];
}
export interface WatchResult {
expression: string;
result: Variable | null;
error: string | null;
}
interface DebugState {
sessions: Record<number, DebugSession>;
/** Session shown in the Debug tool window / title bar. */
@@ -6,8 +6,6 @@
import type { Endpoint } from "./endpoints";
import { allClasses, parseSource, type ClassDecl, type SourceFile } from "./source";
export const DEFAULT_HOST = "http://localhost:8080";
/** Flat `key → value` of a `.properties` file (`=`, `:` or space separated; `#` / `!` comments). */
export function parseProperties(text: string): Map<string, string> {
const out = new Map<string, string>();
-2
View File
@@ -678,5 +678,3 @@ export function PluginsPage() {
</div>
);
}
export default PluginsPage;
-3
View File
@@ -183,6 +183,3 @@ export async function runPluginCommand(pluginId: string, commandId: string, arg:
return null;
}
}
/** Plugins whose contributions are live (enabled and running, or contribution-only). */
export const isLive = (p: PluginInfo) => p.status === "active" || p.status === "static";
-5
View File
@@ -568,8 +568,3 @@ export function dropListings(listings: Map<string, readonly FileEntry[]>, dirs:
if (!dirs.length) return;
for (const key of [...listings.keys()]) if (dirs.some((d) => isSameOrInside(key, d))) listings.delete(key);
}
/** Label for a node path used in dialogs: the file name, or the compacted label. */
export function displayName(node: ProjectNode): string {
return node.root ? node.label : nameOf(node.path);
}
-4
View File
@@ -404,10 +404,6 @@ export function loadDir(path: string, force = false): Promise<void> {
return p;
}
export function isLoading(path: string): boolean {
return inflight.has(path);
}
/** Applies a backend `fsChanged` event: reloads affected loaded folders only. */
export async function applyFsChange(event: { created: string[]; modified: string[]; removed: string[] }) {
const s = get();
-2
View File
@@ -32,8 +32,6 @@ import { blankTemplate, COMPOUND, missingParams, newConfigOfType, templateId, ty
import styles from "./Run.module.css";
import { tx } from "@/platform/i18n";
export { envFromRows } from "./EnvDialog";
export function EditConfigsOverlay() {
const open = useRun((s) => s.editorOpen);
if (!open) return null;
-19
View File
@@ -159,25 +159,6 @@ export function mergeConfigs(detected: readonly RunConfig[], user: readonly RunC
return [...detected.filter((d) => !ids.has(d.id)), ...user];
}
export function configsEqual(a: RunConfig, b: RunConfig): boolean {
return (
a.id === b.id &&
a.name === b.name &&
a.kind === b.kind &&
a.command === b.command &&
a.args.join("\u0000") === b.args.join("\u0000") &&
(a.cwd ?? "") === (b.cwd ?? "") &&
JSON.stringify(sortedEnv(a.env)) === JSON.stringify(sortedEnv(b.env)) &&
a.isTest === b.isTest &&
(a.debugAdapter ?? "") === (b.debugAdapter ?? "") &&
a.detected === b.detected
);
}
function sortedEnv(env: RunConfig["env"]) {
return Object.entries(env).sort(([a], [b]) => a.localeCompare(b));
}
let counter = 0;
export function uid(): string {
const rnd =
-4
View File
@@ -34,7 +34,3 @@ export async function loadGoModules(root: string | null, configs: readonly RunCo
}),
);
}
export function clearGoModules() {
known.clear();
}
-4
View File
@@ -245,10 +245,6 @@ function persistTemporary() {
);
}
export function isTemporary(id: string | null | undefined): boolean {
return !!id && useRun.getState().temporary.includes(id);
}
/**
* Selects the configuration for a gutter / context run: a saved or detected
* configuration with the same id is reused, otherwise `config` becomes a
+2 -2
View File
@@ -7,9 +7,9 @@ import { jvmParser } from "./jvm";
import { pytestParser } from "./pytest";
import type { TestEvent, TestOutputParser } from "./types";
export type { TestEvent, TestOutputParser, TestLocation, TestStatus } from "./types";
export type { TestEvent, TestOutputParser, TestStatus } from "./types";
export { parseDuration } from "./types";
export { TestResults, nodeStatus, type TestNode, type TestCounts } from "./results";
export { TestResults, nodeStatus, type TestNode } from "./results";
export { cargoParser, goParser, jsParser, jvmParser, pytestParser };
/** Runs several parsers side by side (unknown tool: e.g. `make test`). */
+1 -10
View File
@@ -4,12 +4,7 @@
* command line. Other features contribute types with `registerRunConfigType`.
*/
import type { RunConfig } from "@/platform/ipc";
import {
registerRunConfigType,
runConfigTypes,
useRunConfigTypes,
type RunConfigTypeContribution,
} from "@/workbench/contributions";
import { registerRunConfigType, useRunConfigTypes, type RunConfigTypeContribution } from "@/workbench/contributions";
import { formatArgs, parseArgs, uid, uniqueName } from "./configs";
import {
applicationType,
@@ -322,10 +317,6 @@ export function typeFor(kind: string): RunConfigTypeContribution | undefined {
return useRunConfigTypes.getState().types.get(kind);
}
export { runConfigTypes };
export const isCompound = (c: Pick<RunConfig, "kind">) => c.kind === COMPOUND;
/** Only Debug applies to `c` (Remote JVM Debug, Go Remote…): it attaches and launches no process. */
export const isDebugOnly = (c: Pick<RunConfig, "kind">, type = typeFor(c.kind)) => !!type?.debugOnly;
-6
View File
@@ -69,12 +69,6 @@ export function endpointOf(connId: string): DockerEndpoint {
return connections().find((c) => c.id === connId)?.endpoint ?? { kind: "default" };
}
/** The docker executable (for run configurations and terminals), from any snapshot. */
export function dockerExecutable(): string {
for (const c of Object.values(useServices.getState().conns)) if (c.snapshot?.executable) return c.snapshot.executable;
return "docker";
}
function patchConn(id: string, patch: Partial<ConnectionState>) {
useServices.setState((s) => ({ conns: { ...s.conns, [id]: { ...connectionState(id, s), ...patch } } }));
}
-9
View File
@@ -93,12 +93,3 @@ export function addServiceMenu(providers = serviceProviders()): MenuItem[] {
const groups = providers.map((p) => p.addMenu?.() ?? []).filter((g) => g.length > 0);
return groups.flatMap((g, i) => (i === 0 ? g : [{ kind: "separator" } as MenuItem, ...g]));
}
/** The selected node and its provider. */
export function selectedService(): (Located & { contribution: ServiceProviderContribution | undefined }) | null {
const { roots, selectedKey } = useServicesTree.getState();
if (!selectedKey) return null;
const found = indexTree(roots).get(selectedKey);
if (!found) return null;
return { ...found, contribution: serviceProviders().find((p) => p.id === found.provider) };
}
@@ -339,5 +339,3 @@ export function ProjectStructurePage() {
</div>
);
}
export default ProjectStructurePage;
@@ -330,5 +330,3 @@ export function PythonInterpreterPage() {
</div>
);
}
export default PythonInterpreterPage;
-2
View File
@@ -4,8 +4,6 @@ import { useSetting } from "../components/context";
import { KeymapPage, keymapSearchLabels } from "../keymap/KeymapPage";
import { RecognizedFileTypes } from "./FileTypes";
import type { PageSpec } from "./spec";
export { APPEARANCE_GROUP } from "./behavior";
export const EDITOR_GROUP = "Editor";
function ExcludeRow() {
+1 -1
View File
@@ -64,7 +64,7 @@ export const templateDoc = Facet.define<TemplateDocInfo, TemplateDocInfo>({
* The LSP completion uses `override`, so it must merge sources found under
* this key (`state.languageDataAt<CompletionSource>(EXTRA_COMPLETION_KEY, pos)`).
*/
export const EXTRA_COMPLETION_KEY = "openideaCompletion";
const EXTRA_COMPLETION_KEY = "openideaCompletion";
/**
* Language-data key for a lookup restricted to one source: `(state) =>
-2
View File
@@ -24,8 +24,6 @@ import { tagAtCaret, updateTag } from "./emmet/editor";
import { promptAbbreviation, UpdateTagDialogHost } from "./emmet/UpdateTagDialog";
import { tx } from "@/platform/i18n";
export { EXTRA_COMPLETION_KEY } from "./editor";
const EDITOR_WHEN = "textEditorActive && !editorReadOnly && (editorFocus || popupOpen || !toolWindowFocus)";
const MARKUP_PATH = /\.(html?|xhtml|shtml|vue|svelte|xml)$/i;
-9
View File
@@ -65,15 +65,6 @@ export function resetTemplate(id: string) {
commit({ templates, deleted: c.deleted.filter((d) => d !== id) });
}
export function resetAllTemplates() {
commit({
templates: Object.fromEntries(
Object.entries(useLiveTemplates.getState().custom.templates).filter(([id]) => !BUILTIN_IDS.has(id)),
),
deleted: [],
});
}
export function isModifiedBuiltin(id: string): boolean {
return BUILTIN_IDS.has(id) && id in useLiveTemplates.getState().custom.templates;
}
@@ -444,5 +444,3 @@ export function LanguageServersPage() {
</div>
);
}
export default LanguageServersPage;
-4
View File
@@ -468,7 +468,3 @@ export function toggleFavoriteBranch(b: Branch) {
// Favorites last for the session only.
}
}
export function notifyNotGit() {
notifications().notify({ group: "vcs", level: "warning", title: "The project is not under Git version control" });
}
-17
View File
@@ -45,23 +45,6 @@ export const invert = (it: DiffIterable): DiffIterable => create(unchanged(it),
export const createUnchanged = (ranges: readonly Range[], length1: number, length2: number) =>
invert(create(ranges, length1, length2));
/** Both changed and unchanged ranges in order, without empty ones (DiffIterableUtil.iterateAll). */
export function iterateAll(it: DiffIterable): [Range, boolean][] {
const out: [Range, boolean][] = [];
let last1 = 0;
let last2 = 0;
for (const c of it.changes) {
const gap = range(last1, c.start1, last2, c.start2);
if (!isEmptyRange(gap)) out.push([gap, true]);
out.push([c, false]);
last1 = c.end1;
last2 = c.end2;
}
const tail = range(last1, it.length1, last2, it.length2);
if (!isEmptyRange(tail)) out.push([tail, true]);
return out;
}
/** Changes of sequences of keys compared by equality (DiffIterableUtil.diff). */
export const diffSequences = <T>(a: readonly T[], b: readonly T[]): DiffIterable =>
create(diffKeys(a, b), a.length, b.length);
-3
View File
@@ -64,9 +64,6 @@ interface LogState {
generation: number;
}
/** Fixed content tabs of the Git tool window. */
export type GitTab = "changes" | "shelf" | "stashes" | "log" | "console" | "worktrees";
/** A log tab of its own (IDEA's "History: file" / "Log: branch" tabs): its own filters and view. */
export interface LogTab {
id: string;
-11
View File
@@ -78,17 +78,6 @@ export function statusDecorations(status: readonly FileStatus[], propagate = tru
return new Map(entries.map(([p, d]) => [p, d]));
}
/** Short letter for change lists ("M", "A", "D", "R", "U", "C"). */
export const KIND_LETTER: Record<EffectiveKind, string> = {
modified: "M",
renamed: "R",
added: "A",
deleted: "D",
untracked: "U",
ignored: "I",
conflicted: "C",
};
export function relTo(root: string, path: string): string {
return path.startsWith(root + "/") ? path.slice(root.length + 1) : path;
}
-5
View File
@@ -268,11 +268,6 @@ export function themeScheme(
return root.dataset.contrast === "high" || root.dataset.theme === "dark-hc" ? "dark-hc" : "dark";
}
/** Base value of an attribute variable in a scheme. */
export function schemeValue(id: SchemeId, cssVar: string): string | undefined {
return schemeTokens(id).get(cssVar);
}
/** An explicit Bold / regular attribute: the editor's configured bold or main weight. */
export function boldWeight(bold: boolean): string {
return bold ? "var(--fw-code-bold, 700)" : "var(--fw-code, 400)";
-6
View File
@@ -36,8 +36,6 @@ export const DEFAULT_LOCALE = "en";
export const SUPPORTED_LOCALES = ["en", "zh"] as const;
export type Locale = (typeof SUPPORTED_LOCALES)[number];
const LOCALE_NAMES: Record<Locale, string> = { en: "English", zh: "中文" };
const loaders = import.meta.glob<Catalog>(["./locales/*.json", "!./locales/en.json"], { import: "default" });
const textLoaders = import.meta.glob<Catalog>("./locales/text/*.json", { import: "default" });
@@ -65,10 +63,6 @@ export function resolveLocale(input: string | null | undefined): Locale {
return (SUPPORTED_LOCALES as readonly string[]).includes(base) ? (base as Locale) : DEFAULT_LOCALE;
}
export function localeDisplayName(locale: Locale): string {
return LOCALE_NAMES[locale];
}
let fallbackCache: Catalog | null = null;
function fallback(): Catalog {
-10
View File
@@ -157,14 +157,6 @@ export function validateProjectStructure(raw: unknown): ProjectStructureValid {
};
}
/** The "Exclude files" name patterns (`*.log;tmp*`). */
export function excludeFilePatterns(excludeFiles: string): string[] {
return excludeFiles
.split(";")
.map((p) => p.trim())
.filter(Boolean);
}
/** Root kinds, as in IDEA's Project Structure (`ide-workspace::roots::RootKind`). */
export type FolderRole = "source" | "test" | "resources" | "testResources" | "excluded";
@@ -283,8 +275,6 @@ export function restoreDetected(ps: ProjectStructureValid, detected: readonly Ro
return { ...ps, unmarked: ps.unmarked.filter((p) => !detected.some((d) => d.path === folderKey(p))) };
}
export const PROJECT_STRUCTURE_KEY = (role: FolderRole) => `projectStructure.${ROLE_KEYS[role]}`;
/** Settings keys of `ProjectStructureValid`, in a stable order. */
export const PROJECT_STRUCTURE_KEYS = [
"sourceRoots",
-1
View File
@@ -2073,7 +2073,6 @@
"The clipboard does not contain a patch": "剪贴板中没有补丁",
"The patch file is empty": "补丁文件为空",
"The project is not a Git repository.": "该项目不是 Git 仓库。",
"The project is not under Git version control": "项目不受 Git 版本控制",
"The project path is always shown in the status bar navigation bar.": "项目路径始终显示在状态栏导航栏中。",
"The remote contains commits that are not in your branch. Update the branch, then push again.": "远程包含您的分支中没有的提交。请更新分支,然后再次推送。",
"The report covers no files": "报告未覆盖任何文件",
-5
View File
@@ -64,8 +64,3 @@ export function virtualDocument(uri: string): Promise<VirtualDocument> {
}
return p;
}
/** Test hook. */
export function _clearVirtualDocuments() {
cache.clear();
}
-6
View File
@@ -1,6 +0,0 @@
.logo {
flex: none;
display: block;
-webkit-user-drag: none;
user-select: none;
}
-26
View File
@@ -1,26 +0,0 @@
import clsx from "clsx";
import markUrl from "../../src-tauri/icons/source/openidea-mark.svg";
import styles from "./AppLogo.module.css";
export interface AppLogoProps {
/** Rendered edge length in CSS pixels. */
size?: number;
/** Accessible name; omit when the product name is shown next to the logo. */
label?: string;
className?: string;
}
/** The product mark (full-bleed tile variant, legible down to 16px). */
export function AppLogo({ size = 32, label, className }: AppLogoProps) {
return (
<img
className={clsx(styles.logo, className)}
src={markUrl}
width={size}
height={size}
alt={label ?? ""}
aria-hidden={label ? undefined : true}
draggable={false}
/>
);
}
-12
View File
@@ -10,7 +10,6 @@ import {
useRef,
useState,
type KeyboardEvent as ReactKeyboardEvent,
type MouseEvent as ReactMouseEvent,
} from "react";
import clsx from "clsx";
import { create } from "zustand";
@@ -325,17 +324,6 @@ export function hideContextMenu() {
useContextMenuStore.setState({ menu: null });
}
/** Returns an `onContextMenu` handler showing `items` (or the result of `items(e)`). */
export function useContextMenu(items: MenuItem[] | ((e: ReactMouseEvent) => MenuItem[] | null)) {
return (e: ReactMouseEvent) => {
const list = typeof items === "function" ? items(e) : items;
if (!list || !list.length) return;
e.preventDefault();
e.stopPropagation();
showContextMenu(e, list);
};
}
/** Renders the active context menu; mount once (the workbench does). */
export function ContextMenuHost() {
const menu = useContextMenuStore((s) => s.menu);
-3
View File
@@ -6,9 +6,6 @@ import { Group, Panel, Separator, type GroupProps, type PanelProps, type Separat
import clsx from "clsx";
import styles from "./Splitter.module.css";
export type { PanelImperativeHandle, Layout } from "react-resizable-panels";
export { usePanelRef, useGroupRef } from "react-resizable-panels";
export function SplitGroup({ className, ...rest }: GroupProps) {
return <Group className={clsx(styles.group, className)} {...rest} />;
}
+1 -13
View File
@@ -3,7 +3,7 @@
* `data-tooltip-shortcut`) gets one, shown by the single `<TooltipHost/>` after
* 600ms of hover. Hidden on scroll, key press, pointer down or leave.
*/
import { cloneElement, isValidElement, useEffect, useRef, useState, type ReactElement } from "react";
import { useEffect, useRef, useState } from "react";
import { createPortal } from "react-dom";
import { computePosition, flip, offset, shift } from "@floating-ui/react-dom";
import styles from "./Tooltip.module.css";
@@ -19,18 +19,6 @@ export function tooltipAttrs(text: string | undefined, shortcut?: string): Recor
return attrs;
}
export interface TooltipProps {
content: string;
shortcut?: string;
children: ReactElement;
}
/** Attaches a tooltip to its single child element. */
export function Tooltip({ content, shortcut, children }: TooltipProps) {
if (!isValidElement(children)) return children;
return cloneElement(children, tooltipAttrs(content, shortcut));
}
interface Shown {
text: string;
shortcut?: string;
+2 -5
View File
@@ -13,9 +13,7 @@ export {
registerDropTarget,
setDragRequiresAlt,
startPointerDrag,
type DragData,
type DragSession,
type DropTarget,
} from "./pointerDrag";
export * from "./Tree";
export * from "./List";
@@ -26,11 +24,10 @@ export * from "./Splitter";
export * from "./SourcePreview";
export * from "./Feedback";
export * from "./HighlightedText";
export { fuzzyMatch, indexRuns, wordMatch } from "./match";
export { fuzzyMatch, wordMatch } from "./match";
export { badgeKind } from "./symbolKind";
export { acquirePopup, isPopupOpen, openLayer } from "./popupState";
export { acquirePopup, isPopupOpen } from "./popupState";
export * from "./BarButton";
export * from "./AppLogo";
export { lazyComponent, prefetchLazyComponents } from "./lazy";
export { T } from "./T";
export { selectableText, copyMenuFor, copyText } from "./selectableText";
+1 -1
View File
@@ -6,5 +6,5 @@
"allowSyntheticDefaultImports": true,
"types": ["node"]
},
"include": ["vite.config.ts"]
"include": ["vite.config.ts", "knip.ts"]
}