mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 01:15:03 +03:00
feat(chore): add a lint ratchet for shadcn rules (#51014)
## Problem shadcn lint rules has been soft landed in #50676 and are now on as warnings in every app, but nothing stops a PR from adding new violations linear: FE-4473 ## Solution - moved the ratchet script and its tests from `apps/studio/scripts` to `packages/eslint-config-supabase` so every app runs one copy - added a shared rule list, `packages/eslint-config-supabase/ratchet-rules.json` with the shadcn rules - www, docs, design-system, ui-library and learn get `lint-ratchet.yml` with one job per changed app (triggered by the app, `packages/**` or the lockfile) + a weekly `lint-ratchet-decrease.yml` (as for studio ratchet) - package tests run in `eslint-config-supabase-tests.yml` <!-- ## Preview links If relevant, include links to changed pages for easy review access. Copy the preview base URL from the Vercel bot comment on this PR. Use the following table as an example template. | Site | Live | Preview | Search for | | -------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | ----------------------------- | | WWW | [/blog/your-post](https://supabase.com/blog/your-post) | [/blog/your-post](https://zone-www-dot-com-git-branch-name-supabase.vercel.app/blog/your-post) | unique phrase from the change | | Docs | [/docs/guides/your-page](https://supabase.com/docs/guides/your-page) | [/docs/guides/your-page](https://docs-git-branch-name-supabase.vercel.app/docs/guides/your-page) | unique phrase from the change | | Studio | [/dashboard](https://supabase.com/dashboard) | [/dashboard](https://studio-git-branch-name-supabase.vercel.app/dashboard) | unique phrase from the change | | Design system | [/design-system](https://supabase.com/design-system) | [/design-system](https://design-system-git-branch-name-supabase.vercel.app/design-system) | unique phrase from the change | | UI library | [/library](https://supabase.com/library) | [/library](https://ui-library-git-branch-name-supabase.vercel.app/library) | unique phrase from the change | | Knowledge base | [/kb/guides/your-page](https://supabase.com/kb/guides/your-page) | [/kb/guides/your-page](https://kb-git-branch-name-supabase.vercel.app/kb/guides/your-page) | unique phrase from the change | --> <!-- ## Additional context Optionally add any other context or screenshots. --> ## Review instructions 1. run `pnpm --filter ./apps/www run lint:ratchet` 2. add `p-[13px]` to a `className` in any www component and run it again. it fails with `shadcn/no-arbitrary-values` and the file name with `(+1)` 3. revert change 4. run `pnpm --filter eslint-config-supabase test` and see 6 tests pass 5. in ci, check `Ratchet studio lint checks` and the `ratchet (<app>)` jobs for the apps this pr touches ## Checklist Check all before review: - [x] I have read [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) - [x] If I wrote a new docs topic or edited an existing topic, I used the `/write-the-docs` or `/edit-the-docs` skill, which applies the docs [style guide](https://github.com/supabase/supabase/tree/master/apps/docs/style-guide) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Developer Improvements** * Expanded automated lint checks to cover additional apps and shared package changes. * Added checks for arbitrary Tailwind values, unknown classes, and raw colors across supported apps. * Added automated baseline updates that can open or update a pull request when lint counts change. * Added tests for the lint configuration and support for combining multiple rule files. * Updated Studio lint notifications to exclude Shadcn rules with zero-baseline counts. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
1 parent
73260dfaba
commit
b13d6c2878
23 files changed
+1021
-20
No files matched your search
@@ -0,0 +1,43 @@
|
||||
name: ESLint Config Tests
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: ['master']
|
||||
paths:
|
||||
- 'packages/eslint-config-supabase/**/*'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
sparse-checkout: |
|
||||
packages/eslint-config-supabase
|
||||
patches
|
||||
|
||||
- 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
|
||||
|
||||
- name: Run tests
|
||||
run: pnpm --filter eslint-config-supabase run test
|
||||
@@ -0,0 +1,109 @@
|
||||
name: Decrease lint ratchet baselines
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 0 * * SUN'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
decrease-baselines:
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
sparse-checkout: |
|
||||
apps/www
|
||||
apps/docs
|
||||
apps/design-system
|
||||
apps/ui-library
|
||||
apps/learn
|
||||
packages
|
||||
patches
|
||||
|
||||
- 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
|
||||
|
||||
- name: Generate token
|
||||
id: app-token
|
||||
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
|
||||
with:
|
||||
client-id: ${{ vars.GH_AUTOFIX_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.GH_AUTOFIX_PRIVATE_KEY }}
|
||||
permission-contents: write
|
||||
permission-pull-requests: write
|
||||
|
||||
- name: Decrease ESLint ratchet baselines and open PR
|
||||
env:
|
||||
GH_TOKEN: ${{ steps.app-token.outputs.token }}
|
||||
DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
|
||||
run: |
|
||||
set -eo pipefail
|
||||
DEFAULT_BRANCH=${DEFAULT_BRANCH:-master}
|
||||
|
||||
BRANCH="bot/decrease-lint-ratchet-baselines"
|
||||
|
||||
git fetch origin "$DEFAULT_BRANCH" --depth=1
|
||||
if git ls-remote --exit-code --heads origin "$BRANCH" > /dev/null 2>&1; then
|
||||
git fetch origin "$BRANCH":"$BRANCH" --depth=1
|
||||
git switch "$BRANCH"
|
||||
git reset --hard "origin/$DEFAULT_BRANCH"
|
||||
else
|
||||
git switch --create "$BRANCH" "origin/$DEFAULT_BRANCH"
|
||||
fi
|
||||
|
||||
# Keep going past an app that regressed so the others still get decreased;
|
||||
# the job fails at the end if any app did.
|
||||
failed=""
|
||||
APPS="www docs design-system ui-library learn"
|
||||
for app in $APPS; do
|
||||
pnpm --filter "./apps/$app" run lint:ratchet --decrease-baselines || failed="$failed $app"
|
||||
done
|
||||
|
||||
if git diff --quiet; then
|
||||
echo "No baseline updates detected."
|
||||
if [ -n "$failed" ]; then
|
||||
echo "::error title=Ratchet regressions::New violations on $DEFAULT_BRANCH in:$failed"
|
||||
exit 1
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
git config user.name 'github-actions[bot]'
|
||||
git config user.email 'github-actions[bot]@users.noreply.github.com'
|
||||
|
||||
for app in $APPS; do git add "apps/$app/.github/eslint-rule-baselines.json"; done
|
||||
git commit --message "chore: decrease lint ratchet baselines"
|
||||
git -c credential.helper= push --force "https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" "HEAD:${BRANCH}"
|
||||
|
||||
pr_url=$(gh pr list --state open --head "$BRANCH" --json url --jq '.[0].url // ""' 2>/dev/null || echo "")
|
||||
if [ -z "$pr_url" ]; then
|
||||
gh pr create \
|
||||
--title "[bot] Decrease lint ratchet baselines" \
|
||||
--body "Automated weekly decrease of lint ratchet baselines." \
|
||||
--base "$DEFAULT_BRANCH" \
|
||||
--head "$BRANCH"
|
||||
else
|
||||
gh pr comment "$pr_url" --body "Updated lint ratchet baselines with the latest weekly decreases."
|
||||
fi
|
||||
|
||||
if [ -n "$failed" ]; then
|
||||
echo "::error title=Ratchet regressions::New violations on $DEFAULT_BRANCH in:$failed"
|
||||
exit 1
|
||||
fi
|
||||
@@ -0,0 +1,85 @@
|
||||
name: Ratchet lint checks
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: read
|
||||
|
||||
jobs:
|
||||
changes:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
apps: ${{ steps.filter.outputs.changes }}
|
||||
steps:
|
||||
- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
|
||||
id: filter
|
||||
with:
|
||||
filters: |
|
||||
shared: &shared
|
||||
- 'packages/**'
|
||||
- 'pnpm-lock.yaml'
|
||||
www:
|
||||
- *shared
|
||||
- 'apps/www/**'
|
||||
docs:
|
||||
- *shared
|
||||
- 'apps/docs/**'
|
||||
design-system:
|
||||
- *shared
|
||||
- 'apps/design-system/**'
|
||||
ui-library:
|
||||
- *shared
|
||||
- 'apps/ui-library/**'
|
||||
learn:
|
||||
- *shared
|
||||
- 'apps/learn/**'
|
||||
|
||||
ratchet:
|
||||
needs: changes
|
||||
if: ${{ needs.changes.outputs.apps != '[]' }}
|
||||
# Uses larger hosted runner as it significantly decreases build times
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
app: ${{ fromJSON(needs.changes.outputs.apps) }}
|
||||
exclude:
|
||||
- app: shared
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
sparse-checkout: |
|
||||
apps/${{ matrix.app }}
|
||||
packages
|
||||
patches
|
||||
|
||||
- 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
|
||||
|
||||
# pnpm runs the script from the app directory, which is where the
|
||||
# baselines were generated, so per-file keys line up.
|
||||
- name: Run ratchet script
|
||||
env:
|
||||
APP: ${{ matrix.app }}
|
||||
run: pnpm --filter "./apps/$APP" run lint:ratchet
|
||||
@@ -103,7 +103,7 @@ jobs:
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
zero_rules=$(jq -r '.rules | to_entries | map(select(.value == 0) | .key) | join(", ")' apps/studio/.github/eslint-rule-baselines.json)
|
||||
zero_rules=$(jq -r '.rules | to_entries | map(select(.value == 0 and (.key | startswith("shadcn/") | not)) | .key) | join(", ")' apps/studio/.github/eslint-rule-baselines.json)
|
||||
|
||||
if [ -z "$zero_rules" ]; then
|
||||
echo "No rules dropped to a baseline of 0; nothing to notify."
|
||||
|
||||
@@ -6,6 +6,8 @@ on:
|
||||
- master
|
||||
paths:
|
||||
- 'apps/studio/**'
|
||||
- 'packages/**'
|
||||
- 'pnpm-lock.yaml'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
|
||||
@@ -42,7 +42,7 @@ pnpm api:codegen # platform Management API types → packages/api-ty
|
||||
|
||||
## CI
|
||||
|
||||
Every PR must pass typecheck + lint (one workflow), Prettier, and a typos check. Other checks are path-filtered: Studio unit tests/build and the lint ratchet (ESLint warning count must not increase) run on `apps/studio/**` changes; app-specific test suites run on their own paths.
|
||||
Every PR must pass typecheck + lint (one workflow), Prettier, and a typos check. Other checks are path-filtered: Studio unit tests/build and the lint ratchet (ESLint warning count must not increase) run on `apps/studio/**` changes and the Tailwind class rules (`shadcn/*`) for `www`, `docs`, `design-system`, `ui-library`, and `learn`; app-specific test suites run on their own paths.
|
||||
|
||||
Never hand-edit generated files: `packages/api-types/types/**`, `**/routeTree.gen.ts`, `**/__generated__/**`, `apps/docs/features/docs/generated/**`, `apps/www/.generated/**`, `supabase/functions/common/database-types.ts`, `apps/docs/content/_partials/access-control/scoped_pat_*.mdx` (run `make -C apps/docs/spec generate.partials.access-control`).
|
||||
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"rules": {
|
||||
"shadcn/no-arbitrary-values": 42,
|
||||
"shadcn/no-unknown-classes": 8,
|
||||
"shadcn/no-raw-colors": 22
|
||||
},
|
||||
"ruleFiles": {
|
||||
"shadcn/no-arbitrary-values": {
|
||||
"components/code-block-wrapper.tsx": 1,
|
||||
"components/code-fragment.tsx": 7,
|
||||
"components/color-palette.tsx": 2,
|
||||
"components/command-menu.tsx": 1,
|
||||
"components/component-preview.tsx": 12,
|
||||
"components/mdx-components.tsx": 2,
|
||||
"registry/default/example/admonition-button-split.tsx": 2,
|
||||
"registry/default/example/assistant-chat-commands.tsx": 2,
|
||||
"registry/default/example/button-split-dropdown.tsx": 2,
|
||||
"registry/default/example/chart-tooltip-demo.tsx": 2,
|
||||
"registry/default/example/command-dialog.tsx": 1,
|
||||
"registry/default/example/connect-interstitial-shared.tsx": 2,
|
||||
"registry/default/example/drawer-demo.tsx": 1,
|
||||
"registry/default/example/page-layout-edge-function.tsx": 1,
|
||||
"registry/default/example/toc-demo.tsx": 1,
|
||||
"registry/default/example/toc-single-demo.tsx": 1,
|
||||
"registry/default/example/typography-inline-code.tsx": 2
|
||||
},
|
||||
"shadcn/no-unknown-classes": {
|
||||
"components/code-block-wrapper.tsx": 1,
|
||||
"components/code-fragment.tsx": 1,
|
||||
"components/component-preview.tsx": 1,
|
||||
"components/mdx-components.tsx": 2,
|
||||
"registry/default/example/data-grid-demo.tsx": 1,
|
||||
"registry/default/example/data-grid-empty-state.tsx": 1,
|
||||
"registry/default/example/form-patterns-sidepanel.tsx": 1
|
||||
},
|
||||
"shadcn/no-raw-colors": {
|
||||
"components/code-block-wrapper.tsx": 2,
|
||||
"components/copy-button.tsx": 3,
|
||||
"registry/default/example/calendar-form.tsx": 1,
|
||||
"registry/default/example/calendar-react-hook-form.tsx": 1,
|
||||
"registry/default/example/checkbox-form-multiple.tsx": 1,
|
||||
"registry/default/example/checkbox-form-single.tsx": 1,
|
||||
"registry/default/example/combobox-form.tsx": 1,
|
||||
"registry/default/example/connect-interstitial-shared.tsx": 3,
|
||||
"registry/default/example/date-picker-form.tsx": 1,
|
||||
"registry/default/example/input-form.tsx": 1,
|
||||
"registry/default/example/input-otp-form.tsx": 1,
|
||||
"registry/default/example/radio-group-card-form.tsx": 1,
|
||||
"registry/default/example/radio-group-form.tsx": 1,
|
||||
"registry/default/example/radio-group-stacked-form.tsx": 1,
|
||||
"registry/default/example/select-form.tsx": 1,
|
||||
"registry/default/example/switch-form.tsx": 1,
|
||||
"registry/default/example/textarea-form.tsx": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@
|
||||
"build": "run-p build:registry build:content && pnpm build:next",
|
||||
"start": "next start",
|
||||
"lint": "eslint .",
|
||||
"lint:ratchet": "tsx node_modules/eslint-config-supabase/ratchet-eslint-rules.ts --rules-file node_modules/eslint-config-supabase/ratchet-rules.json",
|
||||
"clean": "rimraf .next .turbo tsconfig.tsbuildinfo .contentlayer .velite __registry__",
|
||||
"typecheck": "run-p build:registry build:content && tsc --noEmit -p tsconfig.json"
|
||||
},
|
||||
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"rules": {
|
||||
"shadcn/no-arbitrary-values": 38,
|
||||
"shadcn/no-unknown-classes": 19,
|
||||
"shadcn/no-raw-colors": 3
|
||||
},
|
||||
"ruleFiles": {
|
||||
"shadcn/no-arbitrary-values": {
|
||||
"app/contributing/ContributingToC.tsx": 1,
|
||||
"components/Feedback/Feedback.tsx": 15,
|
||||
"components/GuidesSidebar.tsx": 1,
|
||||
"components/StepHike/index.tsx": 1,
|
||||
"features/docs/Reference.sections.tsx": 4,
|
||||
"features/docs/Reference.ui.tsx": 4,
|
||||
"features/ui/AgentWatchSchedule.tsx": 2,
|
||||
"features/ui/CodeBlock/CodeBlock.client.tsx": 7,
|
||||
"features/ui/PromptPanel.tsx": 3
|
||||
},
|
||||
"shadcn/no-unknown-classes": {
|
||||
"app/guides/getting-started/ai-skills/AiSkillsIndex.tsx": 1,
|
||||
"app/guides/local-development/cli/config/page.tsx": 1,
|
||||
"components/GithubCard.tsx": 1,
|
||||
"components/Navigation/NavigationMenu/GlobalMobileMenu.tsx": 1,
|
||||
"components/Navigation/NavigationMenu/NavigationMenuCliList.tsx": 2,
|
||||
"components/Navigation/NavigationMenu/NavigationMenuRefListItems.tsx": 2,
|
||||
"components/Navigation/SideBar.tsx": 1,
|
||||
"components/Params.tsx": 1,
|
||||
"components/ProjectConfigVariables/ProjectConfigVariables.tsx": 2,
|
||||
"features/docs/Reference.sections.tsx": 2,
|
||||
"layouts/MainSkeleton.tsx": 1,
|
||||
"layouts/ref/RefSubLayout.tsx": 2,
|
||||
"layouts/ref/RefSubLayoutNonFunc.tsx": 2
|
||||
},
|
||||
"shadcn/no-raw-colors": {
|
||||
"features/ui/CodeBlock/CodeBlock.tsx": 1,
|
||||
"features/ui/PromptPanel.tsx": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,7 @@
|
||||
"last-changed": "tsx scripts/last-changed.ts",
|
||||
"last-changed:reset": "pnpm run last-changed -- --reset",
|
||||
"lint": "eslint .",
|
||||
"lint:ratchet": "tsx node_modules/eslint-config-supabase/ratchet-eslint-rules.ts --rules-file node_modules/eslint-config-supabase/ratchet-rules.json",
|
||||
"postbuild": "pnpm run build:sitemap && ./../../scripts/upload-static-assets.sh",
|
||||
"prebuild": "pnpm run codegen:graphql && pnpm run codegen:references && pnpm run codegen:examples && pnpm build:federated-content && pnpm run build:markdown && pnpm run build:gz-archive",
|
||||
"predev": "pnpm run codegen:graphql && pnpm run codegen:references && pnpm run codegen:examples",
|
||||
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"rules": {
|
||||
"shadcn/no-arbitrary-values": 7,
|
||||
"shadcn/no-unknown-classes": 6,
|
||||
"shadcn/no-raw-colors": 7
|
||||
},
|
||||
"ruleFiles": {
|
||||
"shadcn/no-arbitrary-values": {
|
||||
"components/command-menu.tsx": 2,
|
||||
"components/command.tsx": 2,
|
||||
"components/course-hero.tsx": 1,
|
||||
"components/mdx-components.tsx": 2
|
||||
},
|
||||
"shadcn/no-unknown-classes": {
|
||||
"components/mdx-components.tsx": 5,
|
||||
"components/side-navigation-item.tsx": 1
|
||||
},
|
||||
"shadcn/no-raw-colors": {
|
||||
"components/chapter-completion.tsx": 1,
|
||||
"components/course-hero.tsx": 1,
|
||||
"components/mdx-components.tsx": 2,
|
||||
"components/side-navigation.tsx": 3
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@
|
||||
"internal:sync": "tsx ./scripts/sync-internal-content.mts",
|
||||
"start": "next start",
|
||||
"lint": "eslint .",
|
||||
"lint:ratchet": "tsx node_modules/eslint-config-supabase/ratchet-eslint-rules.ts --rules-file node_modules/eslint-config-supabase/ratchet-rules.json",
|
||||
"clean": "rimraf .next .turbo tsconfig.tsbuildinfo .contentlayer .velite tsconfig.tsbuildinfo",
|
||||
"typecheck": "pnpm build:content && tsc --noEmit"
|
||||
},
|
||||
|
||||
+260
-1
@@ -11,7 +11,10 @@
|
||||
"jsx-a11y/no-redundant-roles": 2,
|
||||
"jsx-a11y/anchor-is-valid": 6,
|
||||
"jsx-a11y/heading-has-content": 2,
|
||||
"valtio/state-snapshot-rule": 1
|
||||
"valtio/state-snapshot-rule": 1,
|
||||
"shadcn/no-arbitrary-values": 212,
|
||||
"shadcn/no-unknown-classes": 151,
|
||||
"shadcn/no-raw-colors": 64
|
||||
},
|
||||
"ruleFiles": {
|
||||
"react-hooks/exhaustive-deps": {
|
||||
@@ -1000,6 +1003,262 @@
|
||||
},
|
||||
"valtio/state-snapshot-rule": {
|
||||
"state/storage-explorer.tsx": 1
|
||||
},
|
||||
"shadcn/no-arbitrary-values": {
|
||||
"components/grid/components/editor/DateTimeEditor.tsx": 2,
|
||||
"components/grid/components/editor/JsonEditor.tsx": 4,
|
||||
"components/grid/components/editor/TextEditor.tsx": 4,
|
||||
"components/grid/components/editor/TruncatedWarningOverlay.tsx": 1,
|
||||
"components/grid/components/header/ExportDialog.tsx": 2,
|
||||
"components/interfaces/Account/AccessTokens/Classic/ExperimentalTokenDropdown.tsx": 2,
|
||||
"components/interfaces/Account/AccessTokens/Scoped/Form/RiskMarker.tsx": 2,
|
||||
"components/interfaces/Account/AuditLogs/AuditLogOverview.tsx": 2,
|
||||
"components/interfaces/Account/Preferences/HotkeyToggle.tsx": 1,
|
||||
"components/interfaces/Auth/EmailTemplates/CustomEmailTemplateRestrictionAdmonition.tsx": 2,
|
||||
"components/interfaces/Compute/RuntimeBadge.tsx": 1,
|
||||
"components/interfaces/ConfigDrift/ConfigurationDriftPage.tsx": 1,
|
||||
"components/interfaces/Database/Policies/PolicyEditorPanel/LockedQuerySection.tsx": 10,
|
||||
"components/interfaces/Database/Policies/PolicyEditorPanel/index.tsx": 6,
|
||||
"components/interfaces/Database/Privileges/PrivilegesHead.tsx": 1,
|
||||
"components/interfaces/Database/Replication/ReplicationPipelineStatus/ReplicationPipelineStatus.tsx": 2,
|
||||
"components/interfaces/Database/Roles/RoleRow.tsx": 1,
|
||||
"components/interfaces/Database/Schemas/DefaultEdge.tsx": 2,
|
||||
"components/interfaces/Database/Schemas/SchemaGraph.tsx": 2,
|
||||
"components/interfaces/Database/Schemas/SchemaTableNode.tsx": 10,
|
||||
"components/interfaces/Database/Tables/ConstraintToken.tsx": 4,
|
||||
"components/interfaces/DiskManagement/DiskManagementReviewAndSubmitDialog/DiskManagementReviewAndSubmitDialog.tsx": 2,
|
||||
"components/interfaces/DiskManagement/fields/StorageTypeField.tsx": 1,
|
||||
"components/interfaces/DiskManagement/ui/DiskSpaceBar.tsx": 1,
|
||||
"components/interfaces/Explorer/ExplorerOnboardingWireframes.tsx": 5,
|
||||
"components/interfaces/Explorer/QueryEditor/QueryRunButton.tsx": 2,
|
||||
"components/interfaces/Functions/EdgeFunctionOverview/EdgeFunctionInvocationsChart.tsx": 1,
|
||||
"components/interfaces/Home/ProjectList/ProjectCard.tsx": 2,
|
||||
"components/interfaces/Integrations/Integration/IntegrationOverviewTabV2/InstallIntegrationSheet/InstallationOverview.tsx": 1,
|
||||
"components/interfaces/Integrations/Marketplace/MarketplaceFeaturedHeroGrid.tsx": 1,
|
||||
"components/interfaces/Integrations/Marketplace/MarketplaceSidebar.tsx": 1,
|
||||
"components/interfaces/Integrations/Queues/QueueTab.tsx": 1,
|
||||
"components/interfaces/Integrations/VercelGithub/ProjectLinker.tsx": 2,
|
||||
"components/interfaces/Integrations/Warehouse/WarehouseTableStatusList.tsx": 1,
|
||||
"components/interfaces/Integrations/Wrappers/WrapperRow.tsx": 2,
|
||||
"components/interfaces/LogDrains/OrgAuditLogDrains.tsx": 2,
|
||||
"components/interfaces/Organization/BillingSettings/Subscription/PaymentMethodSelection.tsx": 1,
|
||||
"components/interfaces/Organization/BillingSettings/Subscription/PlanCard.tsx": 11,
|
||||
"components/interfaces/Organization/CloudMarketplace/AwsMarketplaceOnboarding.components.tsx": 2,
|
||||
"components/interfaces/Organization/Documents/ISO27001.tsx": 1,
|
||||
"components/interfaces/Organization/Documents/SOC2.tsx": 1,
|
||||
"components/interfaces/Organization/HeaderBanner.tsx": 2,
|
||||
"components/interfaces/Organization/OAuthApps/AuthorizeRequesterDetails.tsx": 1,
|
||||
"components/interfaces/ProjectCreation/RegionSelector.tsx": 1,
|
||||
"components/interfaces/ProjectHome/HighAvailabilityBadge.tsx": 5,
|
||||
"components/interfaces/ProjectHome/PlanUsageCard.tsx": 1,
|
||||
"components/interfaces/ProjectHome/ServerLightGrid.tsx": 1,
|
||||
"components/interfaces/QueryInsights/QueryInsightsChart/QueryInsightsChart.tsx": 2,
|
||||
"components/interfaces/QueryInsights/hooks/useQueryInsightsTableColumns.tsx": 2,
|
||||
"components/interfaces/Realtime/Inspector/RealtimeFilterPopover/index.tsx": 1,
|
||||
"components/interfaces/Reports/ReportBlock/ChartBlock.tsx": 2,
|
||||
"components/interfaces/Reports/ReportFilterBar.tsx": 3,
|
||||
"components/interfaces/SQLEditor/DownloadSnippetModal.tsx": 1,
|
||||
"components/interfaces/Settings/General/Infrastructure/RestartServerButton.tsx": 2,
|
||||
"components/interfaces/Settings/General/TransferProjectPanel/TransferProjectButton.tsx": 1,
|
||||
"components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/MapView.tsx": 2,
|
||||
"components/interfaces/Settings/Integrations/VercelIntegration/VercelSection.tsx": 1,
|
||||
"components/interfaces/Settings/Logs/PreviewFilterPanel.tsx": 1,
|
||||
"components/interfaces/Sidebar.tsx": 1,
|
||||
"components/interfaces/SignIn/SignInMfaForm.tsx": 1,
|
||||
"components/interfaces/Storage/AnalyticsBuckets/AnalyticsBucketDetails/CreateTable/CreateTableInstructionsDialog.tsx": 2,
|
||||
"components/interfaces/Storage/AnalyticsBuckets/AnalyticsBucketDetails/NamespaceWithTables/TableRowComponent.tsx": 2,
|
||||
"components/interfaces/Storage/BucketFilePickerDialog/BucketFilePickerHeader.tsx": 2,
|
||||
"components/interfaces/Storage/StorageExplorer/FileExplorerRow.tsx": 2,
|
||||
"components/interfaces/Storage/StorageExplorer/MoveItemsFolderPickerRow.tsx": 2,
|
||||
"components/interfaces/Storage/StoragePolicies/StoragePoliciesEditor.tsx": 1,
|
||||
"components/interfaces/Support/AttachmentUpload.tsx": 1,
|
||||
"components/interfaces/TableGridEditor/GridHeaderActions.tsx": 1,
|
||||
"components/interfaces/TableGridEditor/SidePanelEditor/ForeignKeySelector/ForeignKeySelector.tsx": 4,
|
||||
"components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/JsonEditor/index.tsx": 1,
|
||||
"components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/TextEditor.tsx": 1,
|
||||
"components/interfaces/TableGridEditor/SidePanelEditor/TableEditor/Column.tsx": 1,
|
||||
"components/interfaces/TableGridEditor/SidePanelEditor/TableEditor/ForeignKeysManagement/ForeignKeyRow.tsx": 1,
|
||||
"components/interfaces/UnifiedLogs/ServiceFlow/components/shared/DetailRow.tsx": 1,
|
||||
"components/interfaces/UnifiedLogs/UnifiedLogs.fields.tsx": 5,
|
||||
"components/interfaces/UnifiedLogs/components/Columns.tsx": 3,
|
||||
"components/interfaces/UnifiedLogs/components/LogsList.tsx": 1,
|
||||
"components/interfaces/UnifiedLogs/components/UserLogFilterControl.tsx": 2,
|
||||
"components/layouts/Navigation/FloatingMobileToolbar/FloatingMobileToolbar.tsx": 2,
|
||||
"components/layouts/Navigation/NavigationBar/MobileNavigationBar.tsx": 1,
|
||||
"components/layouts/Navigation/NavigationBar/ProjectBranchSelectorSheetTabTrigger.tsx": 2,
|
||||
"components/layouts/ProjectLayout/LogicalBackupCliInstructions.tsx": 1,
|
||||
"components/layouts/SignInLayout/SignInLayout.tsx": 1,
|
||||
"components/ui/AIEditor/AskAIWidget.tsx": 1,
|
||||
"components/ui/AiAssistantDropdown.tsx": 2,
|
||||
"components/ui/BannerStack/Banners/BannerExplorer.tsx": 3,
|
||||
"components/ui/BannerStack/Banners/BannerSelect2026.tsx": 13,
|
||||
"components/ui/Charts/BarChart.tsx": 1,
|
||||
"components/ui/Charts/ComposedChart.utils.tsx": 2,
|
||||
"components/ui/DataTable/DataTableFilters/DataTableFilterCheckbox.tsx": 2,
|
||||
"components/ui/DataTable/DataTableFilters/DataTableFilterCheckboxAsync.tsx": 1,
|
||||
"components/ui/DataTable/DataTableFilters/DataTableFilterResetButton.tsx": 1,
|
||||
"components/ui/DataTable/primitives/InputWithAddons.tsx": 1,
|
||||
"components/ui/DataTable/primitives/Kbd.tsx": 1,
|
||||
"components/ui/EntityTypeIcon.tsx": 1,
|
||||
"components/ui/ErrorCodeTooltip/ErrorCodeTooltip.tsx": 1,
|
||||
"components/ui/GlobalShortcuts/ShortcutsReferenceSheet.tsx": 1,
|
||||
"components/ui/ShortcutBadge.tsx": 1,
|
||||
"components/ui/ShortcutTooltip.tsx": 1,
|
||||
"pages/project/[ref]/settings/infrastructure/replica/[replicaId].tsx": 1,
|
||||
"pages/project/[ref]/settings/log-drains.tsx": 2,
|
||||
"state/shortcuts/useDynamicShortcut.tsx": 1,
|
||||
"state/shortcuts/useShortcut.tsx": 1
|
||||
},
|
||||
"shadcn/no-unknown-classes": {
|
||||
"components/grid/SupabaseGrid.tsx": 1,
|
||||
"components/grid/components/editor/JsonEditor.tsx": 1,
|
||||
"components/grid/components/editor/TextEditor.tsx": 1,
|
||||
"components/grid/components/grid/ColumnHeader.tsx": 6,
|
||||
"components/grid/components/grid/ColumnOverlayItem.tsx": 5,
|
||||
"components/grid/components/grid/Grid.tsx": 1,
|
||||
"components/grid/components/grid/SelectColumn.tsx": 5,
|
||||
"components/interfaces/App/FeaturePreview/FeaturePreviewModal.tsx": 1,
|
||||
"components/interfaces/Auth/AuthProvidersForm/FormField.tsx": 1,
|
||||
"components/interfaces/Auth/AuthProvidersForm/index.tsx": 1,
|
||||
"components/interfaces/Auth/CustomAuthProviders/CreateOrUpdateCustomProviderSheet.tsx": 1,
|
||||
"components/interfaces/Auth/CustomAuthProviders/CustomAuthProvidersList.tsx": 1,
|
||||
"components/interfaces/Auth/OAuthApps/CreateOrUpdateOAuthAppSheet.tsx": 1,
|
||||
"components/interfaces/Auth/OAuthApps/OAuthAppsList.tsx": 1,
|
||||
"components/interfaces/Auth/Overview/OverviewLearnMore.tsx": 1,
|
||||
"components/interfaces/Auth/Users/UserPanel.tsx": 1,
|
||||
"components/interfaces/Auth/Users/UsersGridComponents.tsx": 3,
|
||||
"components/interfaces/Billing/Payment/AddNewPaymentMethodModal.tsx": 1,
|
||||
"components/interfaces/BranchManagement/ConnectToGitHub.tsx": 1,
|
||||
"components/interfaces/ConnectSheet/content/steps/direct-connection/IPv4StatusPanel.tsx": 1,
|
||||
"components/interfaces/Database/EnumeratedTypes/CreateEnumeratedTypeSidePanel.tsx": 1,
|
||||
"components/interfaces/Database/EnumeratedTypes/EditEnumeratedTypeSidePanel.tsx": 1,
|
||||
"components/interfaces/Database/Functions/FunctionsList/FunctionList.tsx": 1,
|
||||
"components/interfaces/Database/Hooks/EditHookPanel.tsx": 1,
|
||||
"components/interfaces/Database/Policies/PolicyEditorPanel/PolicyEditorPanelHeader.tsx": 1,
|
||||
"components/interfaces/Database/Policies/PolicyEditorPanel/PolicyTemplates.tsx": 1,
|
||||
"components/interfaces/Database/Replication/ReplicationDiagram/Edges.tsx": 2,
|
||||
"components/interfaces/Database/Replication/ReplicationDiagram/index.tsx": 1,
|
||||
"components/interfaces/Database/Schemas/SchemaGraph.tsx": 1,
|
||||
"components/interfaces/Database/Schemas/SchemaTableNode.tsx": 2,
|
||||
"components/interfaces/Database/Triggers/ChooseFunctionForm.tsx": 1,
|
||||
"components/interfaces/Database/Triggers/EventTriggersList/EventTriggerList.tsx": 1,
|
||||
"components/interfaces/Database/Triggers/TriggersList/TriggerList.tsx": 1,
|
||||
"components/interfaces/Docs/DocSection.tsx": 1,
|
||||
"components/interfaces/Home/ProjectList/ShimmeringCard.tsx": 2,
|
||||
"components/interfaces/Integrations/CronJobs/CronJobPage.tsx": 1,
|
||||
"components/interfaces/Integrations/CronJobs/CronJobTableCell.tsx": 1,
|
||||
"components/interfaces/Integrations/CronJobs/CronJobsTab.DataGrid.tsx": 1,
|
||||
"components/interfaces/Integrations/CronJobs/PreviousRunsTab.tsx": 2,
|
||||
"components/interfaces/Integrations/Queues/QueuesTab.tsx": 1,
|
||||
"components/interfaces/Integrations/Queues/SingleQueue/QueueDataGrid.tsx": 1,
|
||||
"components/interfaces/Integrations/Vault/Secrets/SecretsManagement.tsx": 1,
|
||||
"components/interfaces/JwtSecrets/jwt-secret-keys-table/action-panel.tsx": 1,
|
||||
"components/interfaces/Organization/BillingSettings/Subscription/UpgradeModal.tsx": 1,
|
||||
"components/interfaces/Organization/ProjectClaim/confirm.tsx": 1,
|
||||
"components/interfaces/Platform/Webhooks/PlatformWebhooksEndpointDetails.tsx": 1,
|
||||
"components/interfaces/ProjectAPIDocs/ContentSnippet.tsx": 4,
|
||||
"components/interfaces/ProjectAPIDocs/ResourceContent.tsx": 4,
|
||||
"components/interfaces/QueryPerformance/IndexAdvisor/IndexSuggestionIcon.tsx": 1,
|
||||
"components/interfaces/QueryPerformance/QueryIndexes.tsx": 2,
|
||||
"components/interfaces/Realtime/Inspector/MessagesTable.tsx": 2,
|
||||
"components/interfaces/Realtime/Inspector/SelectedRealtimeMessagePanel.tsx": 1,
|
||||
"components/interfaces/Reports/ReportBlock/ChartBlock.tsx": 1,
|
||||
"components/interfaces/Reports/ReportBlock/ReportBlockContainer.tsx": 1,
|
||||
"components/interfaces/Reports/ReportPadding.tsx": 1,
|
||||
"components/interfaces/Reports/renderers/ApiRenderers.tsx": 1,
|
||||
"components/interfaces/Settings/API/HardenAPIModal.tsx": 4,
|
||||
"components/interfaces/Settings/Addons/Addons.tsx": 2,
|
||||
"components/interfaces/Settings/Database/DatabaseReadOnlyAlert.tsx": 1,
|
||||
"components/interfaces/Settings/General/CustomDomainConfig/CustomDomainsShimmerLoader.tsx": 2,
|
||||
"components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/DiagramFlow.tsx": 1,
|
||||
"components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/Edge.tsx": 2,
|
||||
"components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/HaInstanceConfiguration.tsx": 1,
|
||||
"components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/InstanceConfiguration.tsx": 1,
|
||||
"components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/MapView.tsx": 1,
|
||||
"components/interfaces/Settings/Integrations/VercelIntegration/VercelSection.tsx": 1,
|
||||
"components/interfaces/Settings/Logs/LogTable.tsx": 3,
|
||||
"components/interfaces/Settings/Logs/LogsFormatters.tsx": 4,
|
||||
"components/interfaces/Storage/BucketFilePickerDialog/BucketFilePickerExplorer.tsx": 1,
|
||||
"components/interfaces/Storage/BucketFilePickerDialog/BucketFilePickerRow.tsx": 1,
|
||||
"components/interfaces/Storage/StorageBucketsError.tsx": 1,
|
||||
"components/interfaces/Storage/StorageExplorer/FileExplorer.tsx": 1,
|
||||
"components/interfaces/Storage/StorageExplorer/FileExplorerRow.tsx": 2,
|
||||
"components/interfaces/Storage/StorageExplorer/FileExplorerRowEditing.tsx": 2,
|
||||
"components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/ForeignRowSelector/SelectorGrid.tsx": 2,
|
||||
"components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/TextEditor.tsx": 1,
|
||||
"components/interfaces/TableGridEditor/SidePanelEditor/TableEditor/Column.tsx": 1,
|
||||
"components/interfaces/TableGridEditor/SidePanelEditor/TableEditor/ColumnManagement.tsx": 1,
|
||||
"components/interfaces/TableGridEditor/SidePanelEditor/TableEditor/ForeignKeysManagement/ForeignKeyRow.tsx": 1,
|
||||
"components/interfaces/UnifiedLogs/components/LogsListPanel.tsx": 2,
|
||||
"components/layouts/Navigation/FloatingMobileToolbar/FloatingMobileToolbar.tsx": 1,
|
||||
"components/layouts/Navigation/NavigationBar/MobileNavigationBar.tsx": 1,
|
||||
"components/layouts/SQLEditorLayout/SQLEditorNavV2/SQLEditorNav.tsx": 1,
|
||||
"components/layouts/WizardLayout.tsx": 2,
|
||||
"components/ui/AIAssistantPanel/CollapsibleCodeBlock.tsx": 1,
|
||||
"components/ui/AIAssistantPanel/MessageMarkdown.tsx": 1,
|
||||
"components/ui/AIAssistantPanel/SupportAssistantSuccessCardContent.tsx": 1,
|
||||
"components/ui/AIAssistantPanel/elements/Tool.tsx": 1,
|
||||
"components/ui/AutoEnableRLSNotice.tsx": 1,
|
||||
"components/ui/CodeEditor/CodeEditor.tsx": 2,
|
||||
"components/ui/DataGridResults/CellDetailPanel.tsx": 1,
|
||||
"components/ui/DataTable/DataTableInfinite.tsx": 1,
|
||||
"components/ui/EdgeFunctionBlock/EdgeFunctionBlock.tsx": 1,
|
||||
"components/ui/EditorPanel/EditorPanel.tsx": 1,
|
||||
"components/ui/FileExplorerAndEditor/index.tsx": 2,
|
||||
"components/ui/Forms/FormSection.tsx": 2,
|
||||
"components/ui/QueryBlock/QueryBlock.tsx": 3,
|
||||
"components/ui/ShimmerLine.tsx": 1,
|
||||
"components/ui/Shimmers.tsx": 3,
|
||||
"pages/project/[ref]/functions/[functionSlug]/code.tsx": 1,
|
||||
"pages/project/[ref]/storage/vectors/buckets/[bucketId].tsx": 1
|
||||
},
|
||||
"shadcn/no-raw-colors": {
|
||||
"components/interfaces/Advisors/AdvisorRuleItem.tsx": 1,
|
||||
"components/interfaces/Auth/EmailTemplates/TemplateEditor.tsx": 1,
|
||||
"components/interfaces/BranchManagement/BranchPanels.tsx": 1,
|
||||
"components/interfaces/BranchManagement/CreateBranchModal.tsx": 6,
|
||||
"components/interfaces/BranchManagement/DeleteBranchModal.tsx": 1,
|
||||
"components/interfaces/ConnectSheet/content/steps/direct-connection/IPv4StatusPanel.tsx": 1,
|
||||
"components/interfaces/Database/Functions/FunctionsList/FunctionsList.tsx": 2,
|
||||
"components/interfaces/Database/Hooks/DeleteHookModal.tsx": 2,
|
||||
"components/interfaces/Database/Migrations/Migrations.tsx": 1,
|
||||
"components/interfaces/Database/Triggers/DeleteEventTrigger.tsx": 1,
|
||||
"components/interfaces/Database/Triggers/TriggersList/TriggersList.tsx": 2,
|
||||
"components/interfaces/DiskManagement/ui/DiskSpaceBar.tsx": 1,
|
||||
"components/interfaces/Functions/FunctionsEmptyState.tsx": 1,
|
||||
"components/interfaces/Integrations/CronJobs/DeleteCronJob.tsx": 1,
|
||||
"components/interfaces/Integrations/Marketplace/MarketplaceFeaturedHeroGrid.tsx": 2,
|
||||
"components/interfaces/Integrations/Queues/SingleQueue/DeleteQueue.tsx": 1,
|
||||
"components/interfaces/Integrations/Queues/SingleQueue/PurgeQueue.tsx": 1,
|
||||
"components/interfaces/Integrations/VercelGithub/IntegrationPanels.tsx": 1,
|
||||
"components/interfaces/JwtSecrets/jwt-secret-keys-table/signing-key-row.tsx": 1,
|
||||
"components/interfaces/Organization/BillingSettings/BillingBreakdown/BillingMetric.tsx": 2,
|
||||
"components/interfaces/Organization/BillingSettings/Subscription/ExitSurveyModal.tsx": 1,
|
||||
"components/interfaces/Organization/BillingSettings/Subscription/UpgradeModal.tsx": 1,
|
||||
"components/interfaces/Organization/IntegrationSettings/SidePanelVercelProjectLinker.tsx": 1,
|
||||
"components/interfaces/Organization/TeamSettings/MembersView.tsx": 1,
|
||||
"components/interfaces/ProjectCreation/ProjectCreationForm.tsx": 1,
|
||||
"components/interfaces/Reports/renderers/ApiRenderers.tsx": 1,
|
||||
"components/interfaces/SQLEditor/UtilityPanel/UtilityActions.tsx": 4,
|
||||
"components/interfaces/Settings/Integrations/IntegrationsSettings.tsx": 1,
|
||||
"components/interfaces/Settings/Logs/Logs.DatePickers.tsx": 1,
|
||||
"components/interfaces/SignIn/ForgotPasswordWizard.tsx": 2,
|
||||
"components/interfaces/Storage/StoragePolicies/PolicyTemplates/TemplatesList.tsx": 1,
|
||||
"components/interfaces/TableGridEditor/SidePanelEditor/OperationQueueSidePanel/DeleteRowOperationItem.tsx": 1,
|
||||
"components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/InputField.tsx": 1,
|
||||
"components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/JsonEditor/DrilldownViewer/DrilldownPane.tsx": 2,
|
||||
"components/interfaces/TableGridEditor/SidePanelEditor/SpreadsheetImport/SpreadSheetFileUpload.tsx": 2,
|
||||
"components/interfaces/UnifiedLogs/UnifiedLogs.utils.ts": 1,
|
||||
"components/layouts/AppLayout/EnableBranchingButton/BranchingPITRNotice.tsx": 1,
|
||||
"components/layouts/SQLEditorLayout/SQLEditorNavV2/SQLEditorTreeViewItem.tsx": 2,
|
||||
"components/ui/AIAssistantPanel/Confirm.tsx": 1,
|
||||
"components/ui/AIAssistantPanel/Message.Actions.tsx": 1,
|
||||
"components/ui/AIAssistantPanel/MessagePartQueryLogs.tsx": 1,
|
||||
"components/ui/DatePicker/TimeSplitInput.tsx": 1,
|
||||
"components/ui/EdgeFunctionBlock/EdgeFunctionBlock.tsx": 2,
|
||||
"components/ui/FileExplorerAndEditor/index.tsx": 1,
|
||||
"components/ui/ProjectSettings/ToggleLegacyApiKeys.tsx": 1,
|
||||
"components/ui/SqlWarningAdmonition.tsx": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,7 @@
|
||||
"build:tanstack": "vite build --mode ${MODE:-production}",
|
||||
"start:tanstack": "node --env-file-if-exists=.env --env-file-if-exists=.env.local --env-file-if-exists=.env.${MODE:-production} --env-file-if-exists=.env.${MODE:-production}.local .output/server/index.mjs",
|
||||
"lint": "eslint .",
|
||||
"lint:ratchet": "tsx scripts/ratchet-eslint-rules.ts --rules-file scripts/ratchet-rules.json",
|
||||
"lint:ratchet": "tsx node_modules/eslint-config-supabase/ratchet-eslint-rules.ts --rules-file scripts/ratchet-rules.json --rules-file node_modules/eslint-config-supabase/ratchet-rules.json",
|
||||
"clean": "rimraf .next .turbo tsconfig.tsbuildinfo",
|
||||
"test": "vitest --run --coverage",
|
||||
"test:watch": "vitest watch",
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"rules": {
|
||||
"shadcn/no-arbitrary-values": 36,
|
||||
"shadcn/no-unknown-classes": 11,
|
||||
"shadcn/no-raw-colors": 2
|
||||
},
|
||||
"ruleFiles": {
|
||||
"shadcn/no-arbitrary-values": {
|
||||
"app/example/headless-app/layout.tsx": 3,
|
||||
"app/example/oauth-consent/layout.tsx": 3,
|
||||
"app/example/password-based-auth/layout.tsx": 3,
|
||||
"app/example/social-auth/layout.tsx": 3,
|
||||
"components/catalog-preview.tsx": 5,
|
||||
"components/command-menu.tsx": 2,
|
||||
"components/command.tsx": 2,
|
||||
"components/component-preview.tsx": 7,
|
||||
"components/library-overview.tsx": 3,
|
||||
"components/mdx-components.tsx": 2,
|
||||
"components/tanstack-db-generator/index.tsx": 1,
|
||||
"registry/default/blocks/realtime-flow/components/realtime-flow-overlay.tsx": 1,
|
||||
"registry/default/platform/platform-kit-nextjs/components/supabase-manager/index.tsx": 1
|
||||
},
|
||||
"shadcn/no-unknown-classes": {
|
||||
"app/(app)/docs/[[...slug]]/page.tsx": 2,
|
||||
"components/block-overview-tabs.tsx": 2,
|
||||
"components/block-preview.tsx": 1,
|
||||
"components/component-preview.tsx": 2,
|
||||
"components/mdx-components.tsx": 1,
|
||||
"registry/default/components/ui/popover.tsx": 1,
|
||||
"registry/default/components/ui/select.tsx": 1,
|
||||
"registry/default/components/ui/tooltip.tsx": 1
|
||||
},
|
||||
"shadcn/no-raw-colors": {
|
||||
"components/mdx-components.tsx": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@
|
||||
"test:headless-tools": "tsx scripts/test-headless-tools.mts",
|
||||
"start": "next start",
|
||||
"lint": "eslint .",
|
||||
"lint:ratchet": "tsx node_modules/eslint-config-supabase/ratchet-eslint-rules.ts --rules-file node_modules/eslint-config-supabase/ratchet-rules.json",
|
||||
"clean": "rimraf .next .turbo tsconfig.tsbuildinfo .contentlayer .velite",
|
||||
"typecheck": "run-p build:content build:markdown && next typegen && tsc --noEmit -p tsconfig.json"
|
||||
},
|
||||
|
||||
+277
@@ -0,0 +1,277 @@
|
||||
{
|
||||
"rules": {
|
||||
"shadcn/no-arbitrary-values": 527,
|
||||
"shadcn/no-unknown-classes": 112,
|
||||
"shadcn/no-raw-colors": 212
|
||||
},
|
||||
"ruleFiles": {
|
||||
"shadcn/no-arbitrary-values": {
|
||||
"app/(home)/_components/BuiltWithSupabaseSection.tsx": 2,
|
||||
"app/(products)/auth/_components/FeaturesSection.tsx": 40,
|
||||
"app/(products)/database/_components/FeaturesSection.tsx": 15,
|
||||
"app/(products)/database/_components/Illustrations/SpreadsheetIllustration.tsx": 9,
|
||||
"app/(products)/database/_components/VisualDemo.tsx": 5,
|
||||
"app/(products)/edge-functions/_components/Highlights.tsx": 1,
|
||||
"app/(products)/realtime/_components/FeaturesSection.tsx": 5,
|
||||
"app/(products)/storage/_components/FeaturesSection.tsx": 16,
|
||||
"app/contribute/about/page.tsx": 1,
|
||||
"app/partners/PartnersContent.tsx": 2,
|
||||
"app/state-of-startups/components/StateOfStartupsAuroraHeader.tsx": 2,
|
||||
"app/state-of-startups/components/StateOfStartupsHeader.tsx": 2,
|
||||
"app/state-of-startups/register/RegisterContent.tsx": 12,
|
||||
"components/Blog/BlogGridItem.tsx": 1,
|
||||
"components/BuiltWithSupabaseSection.tsx": 2,
|
||||
"components/Changelog/ChangelogInlineMarkdown.tsx": 1,
|
||||
"components/Changelog/ChangelogLlmMarkdownButton.tsx": 2,
|
||||
"components/Changelog/ChangelogTimelineList.tsx": 2,
|
||||
"components/Contribute/Hero.tsx": 1,
|
||||
"components/Contribute/Icons.tsx": 2,
|
||||
"components/Contribute/UnansweredThreadsTable.tsx": 2,
|
||||
"components/Contribute/UserProfile.tsx": 2,
|
||||
"components/CustomerStories/CutomsersSliderDesktop.tsx": 1,
|
||||
"components/Error404.tsx": 3,
|
||||
"components/Events/new/EventTimeline.tsx": 1,
|
||||
"components/FeaturesMatrix.tsx": 1,
|
||||
"components/Footer/index.tsx": 1,
|
||||
"components/Go/TweetsSection.tsx": 2,
|
||||
"components/LaunchWeek/11/HackathonCallout.tsx": 1,
|
||||
"components/LaunchWeek/11/LW11Day1.tsx": 1,
|
||||
"components/LaunchWeek/11/LW11Meetups.tsx": 1,
|
||||
"components/LaunchWeek/11/LW11Summary.tsx": 1,
|
||||
"components/LaunchWeek/11/LaunchWeekLogoHeader.tsx": 4,
|
||||
"components/LaunchWeek/11/LaunchWeekPrizeSection.tsx": 1,
|
||||
"components/LaunchWeek/11/Releases/BuildStage.tsx": 1,
|
||||
"components/LaunchWeek/11/Releases/components/AdventCard.tsx": 2,
|
||||
"components/LaunchWeek/11/Releases/components/DaySection.tsx": 6,
|
||||
"components/LaunchWeek/12/HackathonCallout.tsx": 1,
|
||||
"components/LaunchWeek/12/LWMeetups.tsx": 1,
|
||||
"components/LaunchWeek/12/LaunchWeekLogoHeader.tsx": 4,
|
||||
"components/LaunchWeek/12/LaunchWeekPrizeSection.tsx": 1,
|
||||
"components/LaunchWeek/12/Releases/BuildStage.tsx": 1,
|
||||
"components/LaunchWeek/12/Releases/Day1.tsx": 1,
|
||||
"components/LaunchWeek/12/Releases/LWHeader.tsx": 1,
|
||||
"components/LaunchWeek/12/Releases/components/BuildCard.tsx": 2,
|
||||
"components/LaunchWeek/12/Releases/components/DaySection.tsx": 2,
|
||||
"components/LaunchWeek/13/Releases/Day1.tsx": 1,
|
||||
"components/LaunchWeek/13/Releases/components/BuildCard.tsx": 2,
|
||||
"components/LaunchWeek/13/Releases/components/DaySection.tsx": 2,
|
||||
"components/LaunchWeek/14/ActionButton.tsx": 6,
|
||||
"components/LaunchWeek/14/Header.tsx": 4,
|
||||
"components/LaunchWeek/14/Releases/components/BuildCard.tsx": 2,
|
||||
"components/LaunchWeek/14/Releases/components/DaySection.tsx": 2,
|
||||
"components/LaunchWeek/15/ActionButton.tsx": 6,
|
||||
"components/LaunchWeek/15/LW15MainStage.tsx": 3,
|
||||
"components/LaunchWeek/7/BlogLinks.tsx": 2,
|
||||
"components/LaunchWeek/7/LabelBadge.tsx": 3,
|
||||
"components/LaunchWeek/7/LaunchSection/LaunchWeekLogoHeader.tsx": 3,
|
||||
"components/LaunchWeek/7/LaunchWeekPrizeCard.tsx": 1,
|
||||
"components/LaunchWeek/7/LaunchWeekPrizeSection.tsx": 3,
|
||||
"components/LaunchWeek/7/Releases/components/index.tsx": 22,
|
||||
"components/LaunchWeek/7/Releases/index.tsx": 6,
|
||||
"components/LaunchWeek/8/LWArchive.tsx": 3,
|
||||
"components/LaunchWeek/8/LaunchWeekLogoHeader.tsx": 4,
|
||||
"components/LaunchWeek/8/LaunchWeekPrizeCard.tsx": 1,
|
||||
"components/LaunchWeek/8/Releases/LWAnnouncement.tsx": 1,
|
||||
"components/LaunchWeek/8/Releases/components/index.tsx": 20,
|
||||
"components/LaunchWeek/8/Releases/index.tsx": 17,
|
||||
"components/LaunchWeek/X/Album/Player.tsx": 2,
|
||||
"components/LaunchWeek/X/LWXMeetups.tsx": 7,
|
||||
"components/LaunchWeek/X/LWXSummary.tsx": 1,
|
||||
"components/LaunchWeek/X/LaunchWeekLogoHeader.tsx": 4,
|
||||
"components/LaunchWeek/X/LaunchWeekPrizeCard.tsx": 2,
|
||||
"components/LaunchWeek/X/LaunchWeekPrizeSection.tsx": 5,
|
||||
"components/LaunchWeek/X/Releases/BuildStage.tsx": 1,
|
||||
"components/LaunchWeek/X/Releases/LWXStickyNav.tsx": 3,
|
||||
"components/LaunchWeek/X/Releases/MainStage.tsx": 4,
|
||||
"components/LaunchWeek/X/Releases/components/AdventCard.tsx": 7,
|
||||
"components/LaunchWeek/X/Releases/components/DaySection.tsx": 9,
|
||||
"components/Nav/ProductDropdown.tsx": 1,
|
||||
"components/Nav/index.tsx": 3,
|
||||
"components/OpenSource/OSSHero.tsx": 1,
|
||||
"components/OpenSource/Sponsorships.tsx": 2,
|
||||
"components/Panel/Panel.tsx": 1,
|
||||
"components/Partners/BackgroundPattern.tsx": 1,
|
||||
"components/Pricing/ComputePricingCalculator.tsx": 1,
|
||||
"components/Pricing/PricingAddons.tsx": 4,
|
||||
"components/Pricing/PricingComparisonTable.tsx": 1,
|
||||
"components/Pricing/PricingComputeAnimation.tsx": 3,
|
||||
"components/Pricing/PricingComputeSection.tsx": 4,
|
||||
"components/Pricing/PricingPlans.tsx": 15,
|
||||
"components/Products/DataAPIsVisual.tsx": 1,
|
||||
"components/Products/Functions/CI.tsx": 1,
|
||||
"components/Products/Functions/RealtimeLogs.tsx": 2,
|
||||
"components/Products/RealtimeVisual.tsx": 10,
|
||||
"components/Products/index.tsx": 1,
|
||||
"components/Regions/RegionTooltip.tsx": 2,
|
||||
"components/Sections/FeaturesSection.tsx": 1,
|
||||
"components/Sections/ParagraphSection.tsx": 1,
|
||||
"components/Sections/ProductHeader2.tsx": 1,
|
||||
"components/Sections/ProductModulesHeader.tsx": 1,
|
||||
"components/Sections/TimedTabsSection.tsx": 2,
|
||||
"components/Sections/TwitterSocialProof.tsx": 2,
|
||||
"components/Solutions/PostGrid.tsx": 1,
|
||||
"components/SurveyResults/StateOfStartupsHeader.tsx": 2,
|
||||
"components/UsersGrowthChart.tsx": 2,
|
||||
"components/Wrapped/Pages/CustomerStories.tsx": 1,
|
||||
"components/Wrapped/Pages/Devs.tsx": 1,
|
||||
"components/Wrapped/Pages/Home.tsx": 1,
|
||||
"components/Wrapped/Pages/ProductAnnouncements.tsx": 1,
|
||||
"components/Wrapped/Pages/SupabaseSelect.tsx": 1,
|
||||
"components/Wrapped/Pages/YearOfAI.tsx": 1,
|
||||
"components/logos.tsx": 2,
|
||||
"data/aws-reinvent-2025.tsx": 5,
|
||||
"data/home/content.tsx": 4,
|
||||
"data/products/functions/page.tsx": 1,
|
||||
"data/solutions/agencies.tsx": 9,
|
||||
"data/solutions/beginners.tsx": 6,
|
||||
"data/solutions/developers.tsx": 9,
|
||||
"data/solutions/firebase.tsx": 9,
|
||||
"data/solutions/hackathon.tsx": 9,
|
||||
"data/solutions/innovation-teams.tsx": 6,
|
||||
"data/solutions/neon.tsx": 9,
|
||||
"data/solutions/no-code.tsx": 5,
|
||||
"data/solutions/postgres-developers.tsx": 9,
|
||||
"data/solutions/startups.tsx": 9,
|
||||
"data/solutions/vibe-coders.tsx": 5,
|
||||
"pages/careers.tsx": 12,
|
||||
"pages/changelog.tsx": 1,
|
||||
"pages/contact-us.tsx": 3,
|
||||
"pages/features.tsx": 5,
|
||||
"pages/ga.tsx": 4,
|
||||
"pages/launch-week/7/index.tsx": 2,
|
||||
"pages/launch-week/8/index.tsx": 1,
|
||||
"pages/support.tsx": 2
|
||||
},
|
||||
"shadcn/no-unknown-classes": {
|
||||
"app/partners/PartnersContent.tsx": 1,
|
||||
"app/state-of-startups/components/ParticipantsCarousel.tsx": 1,
|
||||
"components/AIDemo/DotGrid.tsx": 1,
|
||||
"components/AIDemo/Panel.tsx": 1,
|
||||
"components/Announcement/Badge.tsx": 6,
|
||||
"components/Avatar.tsx": 1,
|
||||
"components/Blog/BlogCollapsible.tsx": 2,
|
||||
"components/Card.tsx": 1,
|
||||
"components/Changelog/ChangelogTimelineList.tsx": 1,
|
||||
"components/CodeBlock/CodeBlock.tsx": 1,
|
||||
"components/CustomerStories/CutomsersSliderDesktop.tsx": 1,
|
||||
"components/Enterprise/CTAForm.tsx": 1,
|
||||
"components/Go/TweetsSection.tsx": 2,
|
||||
"components/LaunchWeek/11/LW11Day1.tsx": 2,
|
||||
"components/LaunchWeek/11/Releases/BuildStage.tsx": 1,
|
||||
"components/LaunchWeek/11/Releases/LW11StickyNav.tsx": 1,
|
||||
"components/LaunchWeek/11/Releases/components/AdventCard.tsx": 1,
|
||||
"components/LaunchWeek/11/Releases/components/DaySection.tsx": 2,
|
||||
"components/LaunchWeek/12/Releases/BuildStage.tsx": 1,
|
||||
"components/LaunchWeek/12/Releases/Day1.tsx": 2,
|
||||
"components/LaunchWeek/12/Releases/LWStickyNav.tsx": 1,
|
||||
"components/LaunchWeek/12/Releases/components/BuildCard.tsx": 1,
|
||||
"components/LaunchWeek/12/Releases/components/DaySection.tsx": 2,
|
||||
"components/LaunchWeek/13/Releases/BuildStage.tsx": 1,
|
||||
"components/LaunchWeek/13/Releases/Day1.tsx": 2,
|
||||
"components/LaunchWeek/13/Releases/LWStickyNav.tsx": 2,
|
||||
"components/LaunchWeek/13/Releases/components/BuildCard.tsx": 1,
|
||||
"components/LaunchWeek/13/Releases/components/DaySection.tsx": 2,
|
||||
"components/LaunchWeek/14/Releases/BuildStage.tsx": 1,
|
||||
"components/LaunchWeek/14/Releases/LWStickyNav.tsx": 2,
|
||||
"components/LaunchWeek/14/Releases/components/BuildCard.tsx": 1,
|
||||
"components/LaunchWeek/14/Releases/components/DaySection.tsx": 2,
|
||||
"components/LaunchWeek/15/LW15BuildStage.tsx": 1,
|
||||
"components/LaunchWeek/15/LW15Hackathon.tsx": 1,
|
||||
"components/LaunchWeek/15/LW15Heading.tsx": 6,
|
||||
"components/LaunchWeek/7/LaunchSection/LaunchWeekLogoHeader.tsx": 1,
|
||||
"components/LaunchWeek/7/Releases/Day5.tsx": 2,
|
||||
"components/LaunchWeek/7/Releases/index.tsx": 1,
|
||||
"components/LaunchWeek/X/Album/Player.tsx": 1,
|
||||
"components/LaunchWeek/X/Releases/BuildStage.tsx": 1,
|
||||
"components/LaunchWeek/X/Releases/LWXStickyNav.tsx": 1,
|
||||
"components/LaunchWeek/X/Releases/components/DaySection.tsx": 2,
|
||||
"components/Nav/MobileMenu.tsx": 1,
|
||||
"components/OpenSource/RepoCard.tsx": 1,
|
||||
"components/OpenSource/Repos.tsx": 2,
|
||||
"components/OpenSource/Sponsorships.tsx": 1,
|
||||
"components/Pricing/CostControlAnimation.tsx": 2,
|
||||
"components/Pricing/PricingComparisonTable.tsx": 1,
|
||||
"components/Pricing/PricingTableRow.tsx": 4,
|
||||
"components/Products/Functions/RealtimeLogs.tsx": 2,
|
||||
"components/Products/RealtimeVisual.tsx": 1,
|
||||
"components/Products/StorageVisual.tsx": 1,
|
||||
"components/Sections/APISection.tsx": 1,
|
||||
"components/Sections/FunctionsUsecases.tsx": 1,
|
||||
"components/Sections/HighlightCards.tsx": 1,
|
||||
"components/Sections/ImageParagraphSection.tsx": 2,
|
||||
"components/Sections/ProductHeader2.tsx": 2,
|
||||
"components/Sections/TwitterSocialProof.tsx": 1,
|
||||
"components/Solutions/CTAForm.tsx": 1,
|
||||
"components/Solutions/FeaturesGrid.tsx": 2,
|
||||
"components/Solutions/TwoColumnsSection.tsx": 2,
|
||||
"components/Tabs/Tabs.tsx": 2,
|
||||
"components/TabsWithHighlights.tsx": 2,
|
||||
"components/VideoWithHighlights.tsx": 2,
|
||||
"components/logos.tsx": 2,
|
||||
"pages/beta.tsx": 2,
|
||||
"pages/careers.tsx": 1,
|
||||
"pages/changelog/[slug].tsx": 1,
|
||||
"pages/contact/sales.tsx": 1,
|
||||
"pages/customers/[slug].tsx": 3,
|
||||
"pages/support.tsx": 2
|
||||
},
|
||||
"shadcn/no-raw-colors": {
|
||||
"app/(home)/_components/logos/FrameworkLogos.tsx": 2,
|
||||
"app/(home)/_components/logos/PublicityLogos.tsx": 12,
|
||||
"app/(products)/auth/_components/FeaturesSection.tsx": 9,
|
||||
"app/(products)/database/_components/FeaturesSection.tsx": 4,
|
||||
"app/(products)/realtime/_components/FeaturesSection.tsx": 4,
|
||||
"app/state-of-startups/StateOfStartups2026Content.tsx": 2,
|
||||
"components/AIDemo/Panel.tsx": 1,
|
||||
"components/CaseStudies/benchmark.tsx": 1,
|
||||
"components/Charts/DeveloperGrowthChart.tsx": 2,
|
||||
"components/ExampleCard.tsx": 3,
|
||||
"components/LaunchWeek/14/ActionButton.tsx": 12,
|
||||
"components/LaunchWeek/14/Header.tsx": 6,
|
||||
"components/LaunchWeek/15/ActionButton.tsx": 12,
|
||||
"components/LaunchWeek/7/LaunchWeekPrizeSection.tsx": 2,
|
||||
"components/LaunchWeek/7/Releases/components/index.tsx": 8,
|
||||
"components/LaunchWeek/7/Releases/index.tsx": 3,
|
||||
"components/LaunchWeek/8/LWArchive.tsx": 1,
|
||||
"components/LaunchWeek/8/Releases/components/index.tsx": 11,
|
||||
"components/LaunchWeek/X/Album/Player.tsx": 1,
|
||||
"components/LaunchWeek/X/Releases/BuildStage.tsx": 1,
|
||||
"components/LaunchWeek/X/Releases/data/lwx_advent_days.tsx": 20,
|
||||
"components/Nav/ProductDropdown.tsx": 1,
|
||||
"components/OpenSource/RepoCard.tsx": 2,
|
||||
"components/Panel/Panel.tsx": 1,
|
||||
"components/Partners/BackgroundPattern.tsx": 1,
|
||||
"components/Pricing/PricingIcons.tsx": 1,
|
||||
"components/Pricing/PricingTableRow.tsx": 1,
|
||||
"components/Products/DatabaseVisual.tsx": 3,
|
||||
"components/Products/Functions/Metrics.tsx": 2,
|
||||
"components/Products/VectorAI/OpenAIImage.tsx": 4,
|
||||
"components/Products/VectorVisual.tsx": 2,
|
||||
"components/Realtime/sandpack.tsx": 1,
|
||||
"components/Sections/CustomerQuotesSection.tsx": 1,
|
||||
"components/SurveyResults/SurveyChart.tsx": 1,
|
||||
"components/code-display.tsx": 5,
|
||||
"data/BetaPage.js": 6,
|
||||
"data/Solutions.tsx": 9,
|
||||
"data/products/database/pipelines-visual.tsx": 19,
|
||||
"data/solutions/agencies.tsx": 1,
|
||||
"data/solutions/ai-builders.tsx": 14,
|
||||
"data/solutions/beginners.tsx": 1,
|
||||
"data/solutions/developers.tsx": 1,
|
||||
"data/solutions/firebase.tsx": 1,
|
||||
"data/solutions/hackathon.tsx": 1,
|
||||
"data/solutions/neon.tsx": 1,
|
||||
"data/solutions/no-code.tsx": 1,
|
||||
"data/solutions/postgres-developers.tsx": 1,
|
||||
"data/solutions/startups.tsx": 1,
|
||||
"data/solutions/vibe-coders.tsx": 1,
|
||||
"pages/assistant.tsx": 2,
|
||||
"pages/beta.tsx": 2,
|
||||
"pages/brand-assets.tsx": 2,
|
||||
"pages/modules/cron.tsx": 1,
|
||||
"pages/modules/queues.tsx": 1,
|
||||
"pages/modules/vector.tsx": 1,
|
||||
"pages/state-of-startups-2025.tsx": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@
|
||||
"export": "next export",
|
||||
"start": "next start",
|
||||
"lint": "eslint .",
|
||||
"lint:ratchet": "tsx node_modules/eslint-config-supabase/ratchet-eslint-rules.ts --rules-file node_modules/eslint-config-supabase/ratchet-rules.json",
|
||||
"clean": "rimraf .next .turbo tsconfig.tsbuildinfo",
|
||||
"pretypecheck": "next typegen",
|
||||
"typecheck": "pnpm run content:build:core && tsc --noEmit",
|
||||
|
||||
+50
-4
@@ -1,13 +1,15 @@
|
||||
import { mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'
|
||||
import { spawnSync } from 'node:child_process'
|
||||
import { mkdtempSync, readFileSync, rmSync, symlinkSync, writeFileSync } from 'node:fs'
|
||||
import { createRequire } from 'node:module'
|
||||
import os from 'node:os'
|
||||
import path from 'node:path'
|
||||
import { afterEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import { runRatchet } from '../ratchet-eslint-rules'
|
||||
|
||||
const studioRoot = path.resolve(__dirname, '../..')
|
||||
const repoRoot = path.resolve(studioRoot, '..', '..')
|
||||
const scriptArgvPlaceholder = path.resolve(studioRoot, 'scripts', 'ratchet-eslint-rules.ts')
|
||||
const packageRoot = path.resolve(__dirname, '..')
|
||||
const repoRoot = path.resolve(packageRoot, '..', '..')
|
||||
const scriptArgvPlaceholder = path.resolve(packageRoot, 'ratchet-eslint-rules.ts')
|
||||
|
||||
const tempDirs: string[] = []
|
||||
|
||||
@@ -83,6 +85,36 @@ describe('ratchet-eslint-rules integration', () => {
|
||||
expect(combinedErrors).toContain(`${relativeToCwd('apps/studio/src/b.ts')} (+1)`)
|
||||
})
|
||||
|
||||
it('combines rule ids from repeated --rules-file flags', () => {
|
||||
const tmp = createTempDir()
|
||||
const metadataPath = path.join(tmp, 'baseline.json')
|
||||
const appRulesPath = path.join(tmp, 'app-rules.json')
|
||||
const sharedRulesPath = path.join(tmp, 'shared-rules.json')
|
||||
writeFileSync(appRulesPath, JSON.stringify(['no-console']))
|
||||
writeFileSync(sharedRulesPath, JSON.stringify(['no-debugger']))
|
||||
|
||||
const eslintResults = buildEslintResults([
|
||||
{ filePath: repoPath('apps/studio/src/a.ts'), rules: { 'no-console': 1, 'no-debugger': 2 } },
|
||||
])
|
||||
|
||||
const result = invokeRatchet(
|
||||
[
|
||||
'--metadata',
|
||||
metadataPath,
|
||||
'--rules-file',
|
||||
appRulesPath,
|
||||
'--rules-file',
|
||||
sharedRulesPath,
|
||||
'--init',
|
||||
],
|
||||
eslintResults
|
||||
)
|
||||
|
||||
expect(result).toBe(0)
|
||||
const baseline = JSON.parse(readFileSync(metadataPath, 'utf8'))
|
||||
expect(baseline.rules).toEqual({ 'no-console': 1, 'no-debugger': 2 })
|
||||
})
|
||||
|
||||
it('reads rule ids from --rules-file', () => {
|
||||
const tmp = createTempDir()
|
||||
const metadataPath = path.join(tmp, 'baseline.json')
|
||||
@@ -137,6 +169,20 @@ describe('ratchet-eslint-rules integration', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('ratchet-eslint-rules CLI', () => {
|
||||
it('runs when invoked through a symlink', () => {
|
||||
const tmp = createTempDir()
|
||||
const link = path.join(tmp, 'ratchet-eslint-rules.ts')
|
||||
symlinkSync(scriptArgvPlaceholder, link)
|
||||
|
||||
const tsxCli = createRequire(import.meta.url).resolve('tsx/cli')
|
||||
const proc = spawnSync(process.execPath, [tsxCli, link], { encoding: 'utf8' })
|
||||
|
||||
expect(proc.status).toBe(2)
|
||||
expect(proc.stderr).toContain('You must provide at least one --rule')
|
||||
})
|
||||
})
|
||||
|
||||
function buildEslintResults(
|
||||
files: Array<{ filePath: string; rules: Record<string, number> }>
|
||||
): unknown[] {
|
||||
@@ -5,7 +5,8 @@
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"preinstall": "npx only-allow pnpm",
|
||||
"clean": "rimraf .turbo tsconfig.tsbuildinfo"
|
||||
"clean": "rimraf .turbo tsconfig.tsbuildinfo",
|
||||
"test": "vitest run"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@shadcn/lint": "0.1.5",
|
||||
@@ -15,6 +16,8 @@
|
||||
"eslint-config-next": "^16.0.0",
|
||||
"eslint-config-prettier": "^10.0.0",
|
||||
"eslint-config-turbo": "^2.5.0",
|
||||
"typescript": "catalog:"
|
||||
"tsx": "catalog:",
|
||||
"typescript": "catalog:",
|
||||
"vitest": "catalog:"
|
||||
}
|
||||
}
|
||||
+18
-10
@@ -4,15 +4,15 @@
|
||||
*
|
||||
* Examples:
|
||||
* # Initialize baselines for two rules
|
||||
* tsx scripts/ratchet-eslint-rules.ts --init \
|
||||
* tsx node_modules/eslint-config-supabase/ratchet-eslint-rules.ts --init \
|
||||
* --rule react-hooks/exhaustive-deps --rule no-console
|
||||
*
|
||||
* # Compare current counts vs baselines
|
||||
* tsx scripts/ratchet-eslint-rules.ts \
|
||||
* tsx node_modules/eslint-config-supabase/ratchet-eslint-rules.ts \
|
||||
* --rule react-hooks/exhaustive-deps --rule no-console
|
||||
*
|
||||
# Decrease baselines when improvements occur
|
||||
* tsx scripts/ratchet-eslint-rules.ts \
|
||||
* tsx node_modules/eslint-config-supabase/ratchet-eslint-rules.ts \
|
||||
* --rule react-hooks/exhaustive-deps --rule no-console \
|
||||
* --decrease-baselines
|
||||
*
|
||||
@@ -32,7 +32,14 @@
|
||||
*/
|
||||
|
||||
import { spawnSync } from 'node:child_process'
|
||||
import { appendFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'
|
||||
import {
|
||||
appendFileSync,
|
||||
existsSync,
|
||||
mkdirSync,
|
||||
readFileSync,
|
||||
realpathSync,
|
||||
writeFileSync,
|
||||
} from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import { pathToFileURL } from 'node:url'
|
||||
|
||||
@@ -43,7 +50,7 @@ interface Args {
|
||||
eslintArgs: string
|
||||
decreaseBaselines: boolean
|
||||
rules: string[]
|
||||
rulesFile?: string
|
||||
rulesFiles: string[]
|
||||
}
|
||||
|
||||
interface ESLintMessage {
|
||||
@@ -103,6 +110,7 @@ function parseArgs(argv: string[]): Args {
|
||||
eslintArgs: '',
|
||||
decreaseBaselines: false,
|
||||
rules: [],
|
||||
rulesFiles: [],
|
||||
}
|
||||
|
||||
for (let i = 2; i < argv.length; i += 1) {
|
||||
@@ -126,7 +134,7 @@ function parseArgs(argv: string[]): Args {
|
||||
)
|
||||
}
|
||||
} else if (a === '--rules-file') {
|
||||
args.rulesFile = argv[++i]
|
||||
args.rulesFiles.push(argv[++i])
|
||||
} else if (a === '--decrease-baselines') {
|
||||
args.decreaseBaselines = true
|
||||
} else {
|
||||
@@ -134,14 +142,14 @@ function parseArgs(argv: string[]): Args {
|
||||
}
|
||||
}
|
||||
|
||||
if (args.rulesFile) {
|
||||
args.rules.push(...readRulesFile(args.rulesFile))
|
||||
for (const rulesFile of args.rulesFiles) {
|
||||
args.rules.push(...readRulesFile(rulesFile))
|
||||
}
|
||||
|
||||
if (args.rules.length === 0) {
|
||||
console.error('Error: You must provide at least one --rule <rule-id> or a --rules-file.')
|
||||
console.error('Example: --rule exhaustive-deps --rule no-console')
|
||||
console.error('Example: --rules-file scripts/ratchet-rules.json')
|
||||
console.error('Example: --rules-file node_modules/eslint-config-supabase/ratchet-rules.json')
|
||||
process.exit(2)
|
||||
}
|
||||
|
||||
@@ -412,7 +420,7 @@ function main(): void {
|
||||
}
|
||||
|
||||
if (process.argv[1]) {
|
||||
const invokedPath = pathToFileURL(path.resolve(process.argv[1])).href
|
||||
const invokedPath = pathToFileURL(realpathSync(path.resolve(process.argv[1]))).href
|
||||
if (import.meta.url === invokedPath) {
|
||||
main()
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
["shadcn/no-arbitrary-values", "shadcn/no-unknown-classes", "shadcn/no-raw-colors"]
|
||||
Generated
+6
@@ -2550,9 +2550,15 @@ importers:
|
||||
eslint-config-turbo:
|
||||
specifier: ^2.5.0
|
||||
version: 2.5.8(eslint@9.37.0(jiti@2.7.0)(supports-color@8.1.1))(turbo@2.9.14)
|
||||
tsx:
|
||||
specifier: 'catalog:'
|
||||
version: 4.22.4
|
||||
typescript:
|
||||
specifier: 'catalog:'
|
||||
version: 6.0.2
|
||||
vitest:
|
||||
specifier: 'catalog:'
|
||||
version: 5.0.0(@opentelemetry/api@1.9.1)(@types/node@22.13.14)(@vitest/coverage-v8@5.0.0)(@vitest/ui@5.0.0)(happy-dom@20.14.5)(jsdom@28.1.0(@noble/hashes@1.8.0)(supports-color@8.1.1))(msw@2.11.3(@types/node@22.13.14)(typescript@6.0.2))(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))
|
||||
|
||||
packages/generator:
|
||||
devDependencies:
|
||||
|
||||
Reference in new issue
Block a user