chore: add typed ESLint checks #18
Frontend security / security (push) Successful in 9s
Frontend verify / verify (push) Failing after 17m37s
Conventional commits / commits (pull_request) Successful in 26s
Frontend security / security (pull_request) Successful in 9s
Frontend verify / verify (pull_request) Failing after 22m42s

Refs WealthLedger/main#18. Keep Biome; add no Prettier dependencies.
This commit is contained in:
2026-09-28 05:52:29 +03:00
parent c1b08735e3
commit 851457e03c
38 changed files with 2914 additions and 155 deletions
+64
View File
@@ -0,0 +1,64 @@
import assert from "node:assert/strict";
import { test } from "node:test";
import { ESLint } from "eslint";
test("ESLint enforces the frontend profile and excludes generated artifacts", async () => {
const eslint = new ESLint();
for (const [filePath, code, rule] of [
[
"src/shared/api/problem-details.ts",
"export function run() { Promise.resolve(); }",
"@typescript-eslint/no-floating-promises",
],
[
"packages/ui/src/EntryCard/EntryCard.tsx",
'import { useState } from "react"; export function Example({ active }: { active: boolean }) { if (active) useState(0); return null; }',
"react-hooks/rules-of-hooks",
],
[
"src/shared/api/problem-details.ts",
"export const values = Array(3).fill({});",
"unicorn/no-array-fill-with-reference-type",
],
[
"src/shared/api/problem-details.ts",
"export default 1;",
"import-x/no-default-export",
],
[
"src/shared/api/client.test.ts",
'import { it } from "vitest"; it.only("focused", () => {});',
"vitest/no-focused-tests",
],
[
"packages/ui/src/EntryCard/EntryCard.test.tsx",
'import { screen } from "@testing-library/react"; screen.findByText("ready");',
"testing-library/await-async-queries",
],
[
"packages/ui/src/EntryCard/EntryCard.tsx",
'import { QueryClient } from "@tanstack/react-query"; export function Example() { const client = new QueryClient(); return <div>{String(client)}</div>; }',
"@tanstack/query/stable-query-client",
],
]) {
const [result] = await eslint.lintText(code, { filePath });
assert.equal(result.fatalErrorCount, 0, filePath);
assert.ok(
result.messages.some((message) => message.ruleId === rule),
rule,
);
}
for (const file of [
"src/shared/api/generated/schema.d.ts",
"packages/ui/dist/index.js",
"storybook-static/index.js",
"coverage/index.js",
])
assert.equal(await eslint.isPathIgnored(file), true, file);
const story = await eslint.calculateConfigForFile(
"src/shared/ui/Button.stories.tsx",
);
assert.equal(story.rules["import-x/no-default-export"][0], 0);
assert.ok(story.rules["storybook/default-exports"][0] > 0);
assert.equal(story.rules["react-refresh/only-export-components"], undefined);
});