chore(studio): gate dead code with knip in CI (#49721)

Makes knip a CI gate for Studio so dead files and unused dependencies
fail the PR instead of piling up. Third PR in the stack, on top of
#49719 (dead code) and #49720 (unused deps), which get Studio to a clean
run.

**Changed:**
- knip `pnpx knip@~5.50.0` → root devDependency `knip@6.32.3`, `pnpm
knip` now runs it. The old `pnpx` form was actually broken: it resolved
knip's `typescript` peer to TS 7 and crashed with
`ts.getDefaultLibFilePath is not a function`. (6.33.0 is newer but
blocked by `minimumReleaseAge`.)
- `knip.jsonc` rewritten for v6 with a `workspaces["apps/studio"]`
block. Framework-convention files (`router.tsx`, `start.ts`,
`routes/**`, `compat/**`, `api/server.js`) are `entry` rather than
`ignore` — an ignored file's imports aren't traced, which is how
`ShellFallback.tsx` (only imported from `routes/__root.tsx`) was being
reported as dead. knip 6's Next.js plugin already covers
`instrumentation*.ts`, `proxy.ts`, `pages/**`; its tanstack-router
plugin only looks under `src/`, hence the manual entries. Narrow
`ignoreIssues` for graphql-codegen output and the `CONSTRAINT_TYPE`
enum; `ignoreDependencies` for the five implicit deps from #49720, each
with a comment; `ignoreBinaries: ["vercel"]`.
- `apps/studio/CLAUDE.md`: one bullet on the gate and where framework
files go.

**Added:**
- `.github/workflows/studio-knip.yml` — path-filtered to
`apps/studio/**` + knip/pnpm config, mirrors `studio-lint-ratchet.yml`'s
setup (no sparse checkout: knip needs every workspace's `package.json`
to resolve the graph). Runs `pnpm knip --workspace apps/studio
--reporter symbols --reporter github-actions` so findings show up as
inline PR annotations. ~5s locally.

Scope notes: the gate is Studio-only — the full-monorepo run still has
~400 dead files in `www`/`docs`/`blocks`, which is a separate effort.
`exclude: ["types", "exports"]` is kept, so unused exports aren't gated
yet, but `enumMembers`/`duplicates` are (they caught real things in
#49719).

## To test

- `pnpm knip --workspace apps/studio` exits 0 on this branch
- The `Studio Dead Code (knip)` workflow runs on this PR and is green
- Sanity-check the gate bites: add a throwaway
`apps/studio/lib/unused.ts`, run `pnpm knip --workspace apps/studio` →
reports it and exits 1


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **CI**
* Added automated dead-code and unused-dependency checks for the Studio
workspace on relevant pushes and pull requests.
* Results appear in workflow summaries and as inline pull request
annotations.

* **Maintenance**
  * Improved analysis of framework-convention files and Studio code.
* Standardized the local code-quality check and updated its
configuration support.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
This commit is contained in:
Alaister YoungandAlaister Young authored and GitHub committed 2026-08-31 11:28:55 +08:00
1 parent 3260053e52
commit 2c76bb371b
5 files changed
+460 -23

No files matched your search

+65
View File
@@ -0,0 +1,65 @@
name: Studio Dead Code (knip)
on:
push:
branches:
- master
paths:
- 'apps/studio/**'
- 'knip.jsonc'
- 'package.json'
- 'pnpm-lock.yaml'
- 'pnpm-workspace.yaml'
- '.github/workflows/studio-knip.yml'
# No `branches` filter: stacked PRs target a sibling branch, not master, and
# the gate should still run on them.
pull_request:
paths:
- 'apps/studio/**'
- 'knip.jsonc'
- 'package.json'
- 'pnpm-lock.yaml'
- 'pnpm-workspace.yaml'
- '.github/workflows/studio-knip.yml'
# Cancel old builds on new commit for same workflow + branch/PR
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
knip:
# Uses larger hosted runner as it significantly decreases build times
runs-on: blacksmith-4vcpu-ubuntu-2404
env:
NODE_OPTIONS: --max-old-space-size=6144
steps:
# No sparse-checkout: knip resolves the whole pnpm workspace graph, so it
# needs every workspace's package.json present even when scoped to studio.
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9
name: Install pnpm
with:
run_install: false
- name: Use Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version-file: '.nvmrc'
cache: 'pnpm'
- name: Install deps
run: pnpm install --frozen-lockfile
# `symbols` keeps the readable table in the job log, `github-actions` adds
# the same findings as inline PR annotations.
- name: Run knip
run: pnpm knip --workspace apps/studio --no-progress --reporter symbols --reporter github-actions
+1
View File
@@ -75,6 +75,7 @@ Older Studio code predates some of these conventions. For new or modified code,
## Defaults that differ here
- **ESLint warnings are ratcheted in CI**: the per-rule occurrence count must not increase, so a new `any`, unresolved `exhaustive-deps` warning, or default export fails the build even though it's "only a warning". Check locally with `pnpm --filter studio run lint:ratchet`.
- **Dead files and deps are gated in CI** by knip (`pnpm knip --workspace apps/studio` locally). Framework-convention files nothing imports (routes, Vercel functions, TanStack Start files) belong in `knip.jsonc` under `workspaces["apps/studio"].entry`, not `ignore` — an ignored file's imports aren't traced, so anything only it uses gets reported as dead. There's no inline `knip-ignore` comment; the only per-file opt-out is config. In a PR stack, a file whose first consumer lands in a later PR fails the gate on the earlier one — either add it in the same PR as its first use, or add it to `workspaces["apps/studio"].ignore` with a `used from #NNN` comment and remove it in that PR.
- **Clipboard**: `copyToClipboard` from `'ui'`, and never `await` anything before calling it (Safari requires the write inside the user gesture; lint-enforced) — pass a Promise as the argument instead.
- **`useParams()` comes from `'common'`**, not `next/navigation` — it camelCases keys and returns `string | undefined`.
- **Permissions**: `useAsyncCheckPermissions` from `hooks/misc/useCheckPermissions` (returns `can: true` when self-hosted).
+85 -21
View File
@@ -1,5 +1,7 @@
{
"$schema": "https://unpkg.com/knip@5/schema-jsonc.json",
"$schema": "https://unpkg.com/knip@6/schema-jsonc.json",
// Only files + dependencies are gated in CI for now; the export/type surface
// has too much noise to enforce yet.
"exclude": ["types", "exports"],
"ignore": [
"examples/**",
@@ -7,28 +9,90 @@
// skip supabase functions
"supabase/functions/**",
"**/*.test.ts",
// ignore studio public folder
"apps/studio/public/**",
// ignore studio scripts
"apps/studio/scripts/**",
// ignore studio components that are dynamically imported
"apps/studio/components/interfaces/ConnectSheet/content/**",
"apps/studio/components/interfaces/ConnectSheet/ConnectionParameters.tsx",
"apps/studio/components/interfaces/ConnectSheet/DirectConnectionExamples.tsx",
"apps/studio/components/interfaces/ConnectSheet/useMcpUrl.ts",
// ignore studio data templates
"apps/studio/data/__templates/**",
// ignore studio NextJS to TanStack migration files
"apps/studio/compat/**",
"apps/studio/routes/**",
"apps/studio/router.ts",
"apps/studio/start.ts",
"apps/studio/routeTree.gen.ts",
"apps/studio/styles/fonts.css",
// ignore studio evals used in GH action
"apps/studio/evals/**",
// ignore registry blocks in ui-library
"apps/ui-library/registry/default/**",
"apps/ui-library/contentlayer.config.js",
],
"workspaces": {
"apps/studio": {
// Framework-convention files: nothing in source imports these, the
// framework/host discovers them by path. They are `entry` rather than
// `ignore` so knip still traces what they import — an ignored file's
// imports are invisible, which makes everything only it pulls in look
// dead.
"entry": [
// TanStack Start. knip's tanstack-router plugin only looks under
// `src/`, but vite.config.ts sets `srcDirectory: './'`, so the
// conventional files sit at the workspace root and have to be listed.
// routeTree.gen.ts is deliberately absent: router.tsx imports it, so
// it is traced already.
"router.tsx",
"start.ts",
// Route modules are real entry points. Keeping them as entries (not
// ignores) means components reachable only from the TanStack tree stay
// traced as the Next `pages/**` tree is dismantled.
"routes/**/*.{ts,tsx}",
// Next.js compat shims. Reached only through the `nextShims` aliases in
// vite.config.ts (`next/link` -> compat/next/link.tsx), which knip
// cannot resolve, so they need to be entries in their own right.
"compat/**/*.{ts,tsx}",
// Vercel serverless function. Vercel deploys every file under `api/`
// as a Function by convention; knip's vercel plugin only contributes
// `vercel.ts`, so this one is manual. Listing it also traces its
// runtime `import('../instrument.server.mjs')`, which is why
// instrument.server.mjs needs no entry of its own even though
// scripts/serve.js (its other importer) is ignored below.
"api/server.js",
],
"ignore": [
"public/**",
// one-off build/codegen scripts, run by hand or from package.json
"scripts/**",
// dynamically imported
"components/interfaces/ConnectSheet/content/**",
"components/interfaces/ConnectSheet/DirectConnectionExamples.tsx",
// data layer templates, copied when adding a new query/mutation
"data/__templates/**",
// evals are run from a GitHub action, not from the app
"evals/**",
],
// Narrowly scoped suppressions: one issue type, one path. Preferred over
// `ignore` (which drops the file from the project entirely, hiding the
// imports and dependencies it legitimately uses) and over
// `ignoreMembers` (which matches member names across the whole
// workspace).
"ignoreIssues": {
// graphql-codegen `client` preset output (scripts/codegen.ts,
// regenerated by `pnpm build:graphql-types`). The preset always emits
// the full set, so some of it is unreferenced by design. execute.ts in
// the same directory is hand-written and is NOT listed here.
"data/graphql/{fragment-masking,gql,graphql}.ts": ["files"],
// CONSTRAINT_TYPE mirrors the complete closed set of Postgres
// `pg_constraint.contype` values (c/f/p/u/t/x). The members we don't
// read are documentation of the valid values, not dead code. Scoped to
// this file so `enumMembers` keeps working everywhere else.
"data/database/constraints-query.ts": ["enumMembers"],
},
// `vercel` is a globally installed CLI used by the `deploy:staging` script
"ignoreBinaries": ["vercel"],
// Dependencies that are required implicitly — nothing imports them by a
// specifier knip can follow, but removing them breaks the build or the
// runtime.
"ignoreDependencies": [
// vite.config.ts resolves 'lodash-es/package.json' by string via
// createRequire to build the SSR lodash -> lodash-es alias
"lodash-es",
// named as a webpack/turbopack loader string in next.config.ts
// (`loaders: ['raw-loader']`)
"raw-loader",
// runtime hooks for @sentry/nextjs / OpenTelemetry Node
// instrumentation. Must be direct deps under pnpm's strict isolation
// (#35030).
"import-in-the-middle",
"require-in-the-middle",
// deliberate dependency-resolution pin (#45876), never imported
"@babel/core",
],
},
},
}
+2 -1
View File
@@ -48,7 +48,7 @@
"setup:cli": "supabase start -x studio && supabase status --output json > keys.json && node scripts/generateLocalEnv.js",
"generate:types": "supabase gen types typescript --local > ./supabase/functions/common/database-types.ts",
"api:codegen": "cd packages/api-types && pnpm run codegen",
"knip": "pnpx knip@~5.50.0",
"knip": "knip",
"authorize-vercel-deploys": "tsx scripts/authorizeVercelDeploys.ts"
},
"devDependencies": {
@@ -57,6 +57,7 @@
"@types/node": "catalog:",
"eslint": "^9.0.0",
"jsdom": "^28.1.0",
"knip": "6.32.3",
"prettier": "^3.8.0",
"prettier-plugin-sql-cst": "^0.18.0",
"rimraf": "^6.0.0",
+307 -1
View File
@@ -154,6 +154,9 @@ importers:
jsdom:
specifier: ^28.1.0
version: 28.1.0(@noble/hashes@1.8.0)(supports-color@8.1.1)
knip:
specifier: 6.32.3
version: 6.32.3
prettier:
specifier: ^3.8.0
version: 3.8.1
@@ -3712,15 +3715,24 @@ packages:
'@emnapi/core@1.10.0':
resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==}
'@emnapi/core@1.11.2':
resolution: {integrity: sha512-TC8MkTuZUtcTSiFeuC0ksCh9QIJ5+F21MvZ4Wn4ORfYaFJ/0dsiudv5tVkejgwZlwQ39jL9WWDe2lz8x0WglOA==}
'@emnapi/runtime@0.43.1':
resolution: {integrity: sha512-Q5sMc4Z4gsD4tlmlyFu+MpNAwpR7Gv2errDhVJ+SOhNjWcx8UTqy+hswb8L31RfC8jBvDgcnT87l3xI2w08rAg==}
'@emnapi/runtime@1.10.0':
resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==}
'@emnapi/runtime@1.11.2':
resolution: {integrity: sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA==}
'@emnapi/wasi-threads@1.2.1':
resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==}
'@emnapi/wasi-threads@1.2.2':
resolution: {integrity: sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==}
'@emotion/is-prop-valid@1.4.0':
resolution: {integrity: sha512-QgD4fyscGcbbKwJmqNvUMSE02OsHUa+lAWKdEUIJKgqe5IwRSKd7+KhibEWdaKwgjLj0DRSHA9biAIqGBk05lw==}
@@ -4849,6 +4861,13 @@ packages:
'@emnapi/core': ^1.7.1
'@emnapi/runtime': ^1.7.1
'@napi-rs/wasm-runtime@1.2.3':
resolution: {integrity: sha512-UMduMbqO5s5zF2NkNacMT/yK5Y5QiKvWr2+50bzIIxFDwVJ2h49b+oyjaCGPhJxd2/gC2x39EHv/gHVuu36x2Q==}
engines: {node: ^20.19.0 || ^22.13.0 || >=23.5.0}
peerDependencies:
'@emnapi/core': ^1.7.1 || ^2.0.0-alpha.4
'@emnapi/runtime': ^1.7.1 || ^2.0.0-alpha.4
'@next/bundle-analyzer@15.3.1':
resolution: {integrity: sha512-NqUZrjVruGbdQaPE3OSEXP+ZuULqumeHVTuU9pOX1V0/9BWY9FOck3jgQGFdBtG41nOYuO8+CoHKDQAVIPQJrw==}
@@ -5625,6 +5644,109 @@ packages:
'@oxc-project/types@0.143.0':
resolution: {integrity: sha512-u6JZdLBTLotrNC9Vd6vPssINdzcCzleKAH6EJKImQb7GtYvX5keN2dxkoK44stCc4tffE6QQRtZTXVSzsLUlWA==}
'@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]
'@parcel/watcher-android-arm64@2.5.6':
resolution: {integrity: sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==}
engines: {node: '>= 10.0.0'}
@@ -8304,6 +8426,9 @@ packages:
'@tybys/wasm-util@0.10.1':
resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==}
'@tybys/wasm-util@0.10.3':
resolution: {integrity: sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==}
'@types/acorn@4.0.6':
resolution: {integrity: sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==}
@@ -11563,6 +11688,9 @@ packages:
fbjs@3.0.5:
resolution: {integrity: sha512-ztsSx77JBtkuMrEypfhgc3cI0+0h+svqeie7xHbh1k/IKdcydnvadp/mUaGgjAOXQmQSxsqgaRhS3q9fy+1kxg==}
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'}
@@ -11701,6 +11829,11 @@ packages:
resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==}
engines: {node: '>=0.4.x'}
formatly@0.3.0:
resolution: {integrity: sha512-9XNj/o4wrRFyhSMJOvsuyMwy8aUfBaZ1VrqHVfohyXf0Sw0e+yfKG+xZaY3arGCOMdwFsqObtzVOc1gU9KiT9w==}
engines: {node: '>=18.3.0'}
hasBin: true
formdata-node@4.4.1:
resolution: {integrity: sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==}
engines: {node: '>= 12.20'}
@@ -11884,6 +12017,9 @@ packages:
get-tsconfig@4.10.0:
resolution: {integrity: sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==}
get-tsconfig@4.14.1:
resolution: {integrity: sha512-Dz/6HxkrxgNehhxLVeyv8sad9UzF2xBVeaKBQNDfJ5XiSXmp2gTR0eO0RWiT2NCKS5aGP9jjkOMggTN90qU50A==}
get-value@3.0.1:
resolution: {integrity: sha512-mKZj9JLQrwMBtj5wxi6MH8Z5eSKaERpAwjg43dPtlGI1ZVEgH/qC7T8/6R2OBSUA+zzHBZgICsVJaEIV2tKTDA==}
engines: {node: '>=6.0'}
@@ -13052,6 +13188,11 @@ packages:
resolution: {integrity: sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==}
engines: {node: '>= 8'}
knip@6.32.3:
resolution: {integrity: sha512-wOJ1Av8PwKqFO0wU7F64vzIcUjxhrieA3Tc2lmeK9C9prpxq+TeG2ewNH5tCaBVZwXNPp6lJkrr+IhZ20iqkMA==}
engines: {node: ^20.19.0 || >=22.12.0}
hasBin: true
knitwork@1.3.0:
resolution: {integrity: sha512-4LqMNoONzR43B1W0ek0fhXMsDNW/zxa1NdFAVMY+k28pgZLovR4G3PB5MrpTxCy1QaZCqNoiaKPr5w5qZHfSNw==}
@@ -14672,6 +14813,9 @@ packages:
resolution: {integrity: sha512-ov0NzaDCOInknS7mP1cwKdJERt3utPW8ldjtdUXQ8Ty0GEFD08wk422vCUN0d7pST6kqtV7dxoI9w1Zi0l/9TA==}
engines: {node: ^20.19.0 || >=22.12.0}
oxc-resolver@11.24.2:
resolution: {integrity: sha512-FY91FiDBj7ls5MsFS9jN3tjz2o0/zsdSsymlakySaBwVJZorHhkWyICLZMKxlu1R9vYo+sd3z1jwb4J8x7bNDw==}
oxc-walker@1.1.1:
resolution: {integrity: sha512-Hwd7dq28zu/Er99+bpWp16CGwFrhyalJh0W3JOB7XpPvgWo3MqMi2ksWGKuzzA9zt50mJ2pIUwR5lpAdZ9ACNQ==}
peerDependencies:
@@ -16288,6 +16432,10 @@ packages:
resolution: {integrity: sha512-dWUG8F5sIIARXih1DTaQAX4SsiTXhInKf1buxdY9DIg4ZYPZK5nGM1VRIYmEbDbsHt7USo99xSLFu5Q1IqTmsg==}
engines: {node: '>= 18'}
smol-toml@1.8.0:
resolution: {integrity: sha512-kCZr2V3ch9i00x8zXRhjUNVcjG9ijES5dDudkXvUVCT5QlJNQWElSJdZqyPemffHoLNUYwOcou0Fy+ojN0uHSQ==}
engines: {node: '>= 18'}
snake-case@3.0.4:
resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==}
@@ -16557,6 +16705,10 @@ packages:
resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
engines: {node: '>=8'}
strip-json-comments@5.0.3:
resolution: {integrity: sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==}
engines: {node: '>=14.16'}
strip-literal@4.0.0:
resolution: {integrity: sha512-PaqAvfUZKBwc/SLmNZtHmzK+v19Z4O4eS3cKPeGvbIv/U3pnyEq4Tuw3/4v/FwfM8VQaEawsyCcOQ0P+kpwWWw==}
@@ -17025,6 +17177,10 @@ packages:
un-eval@1.2.0:
resolution: {integrity: sha512-Wlj/pum6dQtGTPD/lclDtoVPkSfpjPfy1dwnnKw/sZP5DpBH9fLhBgQfsqNhe5/gS1D+vkZUuB771NRMUPA5CA==}
unbash@4.0.10:
resolution: {integrity: sha512-b7zoBQvpWp0vuN5q2vK2RRBR2SvuruQAs50DApdDveBSn3eSYd84IaHodFqQIMlvY9K2VnyBUEXgwOBuGU9GBg==}
engines: {node: '>=14'}
unbox-primitive@1.1.0:
resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==}
engines: {node: '>= 0.4'}
@@ -17809,6 +17965,10 @@ packages:
resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==}
engines: {node: '>=18'}
walk-up-path@4.0.0:
resolution: {integrity: sha512-3hu+tD8YzSLGuFYtPRb48vdhKMi0KQV5sn+uWr8+7dMEq/2G/dtLrdDinkLjqq5TIbIBjYJ4Ax/n3YiaW7QM8A==}
engines: {node: 20 || >=22}
warning@4.0.3:
resolution: {integrity: sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==}
@@ -19569,6 +19729,12 @@ snapshots:
tslib: 2.8.1
optional: true
'@emnapi/core@1.11.2':
dependencies:
'@emnapi/wasi-threads': 1.2.2
tslib: 2.8.1
optional: true
'@emnapi/runtime@0.43.1':
dependencies:
tslib: 2.8.1
@@ -19578,11 +19744,21 @@ snapshots:
tslib: 2.8.1
optional: true
'@emnapi/runtime@1.11.2':
dependencies:
tslib: 2.8.1
optional: true
'@emnapi/wasi-threads@1.2.1':
dependencies:
tslib: 2.8.1
optional: true
'@emnapi/wasi-threads@1.2.2':
dependencies:
tslib: 2.8.1
optional: true
'@emotion/is-prop-valid@1.4.0':
dependencies:
'@emotion/memoize': 0.9.0
@@ -20979,6 +21155,13 @@ snapshots:
'@tybys/wasm-util': 0.10.1
optional: true
'@napi-rs/wasm-runtime@1.2.3(@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.3
optional: true
'@next/bundle-analyzer@15.3.1':
dependencies:
webpack-bundle-analyzer: 4.10.1
@@ -21888,6 +22071,67 @@ snapshots:
'@oxc-project/types@0.143.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.3(@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
'@parcel/watcher-android-arm64@2.5.6':
optional: true
@@ -24834,6 +25078,11 @@ snapshots:
tslib: 2.8.1
optional: true
'@tybys/wasm-util@0.10.3':
dependencies:
tslib: 2.8.1
optional: true
'@types/acorn@4.0.6':
dependencies:
'@types/estree': 1.0.5
@@ -28635,6 +28884,10 @@ snapshots:
transitivePeerDependencies:
- encoding
fd-package-json@2.0.0:
dependencies:
walk-up-path: 4.0.0
fdir@6.5.0(picomatch@4.0.4):
optionalDependencies:
picomatch: 4.0.4
@@ -28768,6 +29021,10 @@ snapshots:
format@0.2.2: {}
formatly@0.3.0:
dependencies:
fd-package-json: 2.0.0
formdata-node@4.4.1:
dependencies:
node-domexception: 1.0.0
@@ -28932,6 +29189,10 @@ snapshots:
dependencies:
resolve-pkg-maps: 1.0.0
get-tsconfig@4.14.1:
dependencies:
resolve-pkg-maps: 1.0.0
get-value@3.0.1:
dependencies:
isobject: 3.0.1
@@ -30186,6 +30447,22 @@ snapshots:
klona@2.0.6: {}
knip@6.32.3:
dependencies:
fdir: 6.5.0(picomatch@4.0.5)
formatly: 0.3.0
get-tsconfig: 4.14.1
jiti: 2.7.0
oxc-parser: 0.143.0
oxc-resolver: 11.24.2
picomatch: 4.0.5
smol-toml: 1.8.0
strip-json-comments: 5.0.3
tinyglobby: 0.2.17
unbash: 4.0.10
yaml: 2.9.0
zod: 4.4.3
knitwork@1.3.0: {}
kolorist@1.8.0: {}
@@ -32652,7 +32929,28 @@ snapshots:
'@oxc-parser/binding-win32-arm64-msvc': 0.143.0
'@oxc-parser/binding-win32-ia32-msvc': 0.143.0
'@oxc-parser/binding-win32-x64-msvc': 0.143.0
optional: true
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
oxc-walker@1.1.1(@oxc-project/types@0.143.0)(oxc-parser@0.143.0)(rolldown@1.2.3):
optionalDependencies:
@@ -34637,6 +34935,8 @@ snapshots:
smol-toml@1.6.1: {}
smol-toml@1.8.0: {}
snake-case@3.0.4:
dependencies:
dot-case: 3.0.4
@@ -34938,6 +35238,8 @@ snapshots:
strip-json-comments@3.1.1: {}
strip-json-comments@5.0.3: {}
strip-literal@4.0.0:
dependencies:
js-tokens: 10.0.0
@@ -35412,6 +35714,8 @@ snapshots:
un-eval@1.2.0: {}
unbash@4.0.10: {}
unbox-primitive@1.1.0:
dependencies:
call-bound: 1.0.4
@@ -36268,6 +36572,8 @@ snapshots:
dependencies:
xml-name-validator: 5.0.0
walk-up-path@4.0.0: {}
warning@4.0.3:
dependencies:
loose-envify: 1.4.0