Files
supabase/knip.jsonc
Mert YEREKAPAN bf31670412 chore(studio): keep useTrackExperimentExposure across experiment gaps (#49765)
## Summary

Adds a narrow knip suppression so
`hooks/misc/useTrackExperimentExposure.ts` isn't flagged as an unused
file when no experiment is currently consuming it.

## Why

Different from the other files #49719 cleaned up. Those were one-off
feature code (specific banners, mutations, table rows) — genuinely dead
when their feature was removed. This hook is **shared experiment
plumbing**: every A/B experiment plugs into it, and we run experiments
frequently. Gaps between experiments are normal.

Deleting and re-adding it each cycle:
- Churns the codebase for no real cleanup value
- Adds review surface to every next experiment PR (has to also add the
hook back)
- Caused a stacked-merge race today — #49719 deleted it, #49534
reintroduced a usage in `plan-presentation.ts`. Both PRs' CI ran green
on their own bases, but merging both broke master's typecheck + Studio
deploy. Fixed in #49763.

## What this changes

One entry in `knip.jsonc` under
`workspaces["apps/studio"].ignoreIssues`:

\`\`\`jsonc
"hooks/misc/useTrackExperimentExposure.ts": ["files"]
\`\`\`

`ignoreIssues` (not `ignore`) is the right knob per the config's own
guidance — it suppresses only the "unused file" issue for this specific
path, while knip still traces the file's imports so anything it depends
on stays honestly tracked.

## Test plan

- [ ] `pnpm knip --workspace apps/studio` still clean
- [ ] With no experiment referencing the hook, knip does not report it
2026-08-31 10:22:56 +00:00

100 lines
4.7 KiB
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/**",
"**/*.mdx",
// skip supabase functions
"supabase/functions/**",
"**/*.test.ts",
// 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"],
"hooks/misc/useTrackExperimentExposure.ts": ["files"],
},
// `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",
],
},
},
}