ci: add eslint

This commit is contained in:
2026-07-13 10:38:23 +05:00
parent 72f272246f
commit 06e059367e
5 changed files with 1698 additions and 6 deletions
+79
View File
@@ -0,0 +1,79 @@
import { includeIgnoreFile } from "@eslint/compat";
import js from "@eslint/js";
import vitest from "@vitest/eslint-plugin";
import prettier from "eslint-config-prettier";
import { defineConfig } from "eslint/config";
import globals from "globals";
import path from "node:path";
import ts from "typescript-eslint";
const gitignorePath = path.resolve(import.meta.dirname, ".gitignore");
export default defineConfig(
includeIgnoreFile(gitignorePath),
js.configs.recommended,
...ts.configs.recommended,
prettier,
{
languageOptions: { globals: { ...globals.node } },
rules: {
"no-undef": "off",
// base rule is for JS; TS interfaces/ctors need the typed version below
"no-unused-vars": "off",
"no-console": ["error", { allow: ["warn", "error"] }],
"@typescript-eslint/no-magic-numbers": [
"error",
{
enforceConst: true,
ignoreDefaultValues: true,
ignore: [0, 1, 2],
},
],
"@typescript-eslint/no-unused-vars": [
"error",
{
argsIgnorePattern: "^_",
varsIgnorePattern: "^_",
caughtErrorsIgnorePattern: "^_",
},
],
},
},
{
files: ["**/constants.ts", "**/constants/*.ts"],
rules: {
"no-magic-numbers": "off",
"@typescript-eslint/no-magic-numbers": "off",
},
},
{
files: ["scripts/**"],
rules: {
"no-magic-numbers": "off",
"@typescript-eslint/no-magic-numbers": "off",
"no-console": "off",
},
},
{
files: ["src/**/*.test.ts", "src/**/*.spec.ts", "tests/**/*.test.ts"],
plugins: { vitest },
rules: {
...vitest.configs.recommended.rules,
"vitest/no-focused-tests": "error",
"vitest/no-disabled-tests": "warn",
"vitest/expect-expect": "error",
"vitest/no-conditional-expect": "error",
"vitest/require-hook": "warn",
"vitest/consistent-test-it": [
"error",
{ fn: "it", withinDescribe: "it" },
],
"vitest/require-top-level-describe": "error",
"vitest/no-identical-title": "error",
"no-magic-numbers": "off",
"@typescript-eslint/no-magic-numbers": "off",
},
},
);
+1603
View File
File diff suppressed because it is too large Load Diff
+11 -3
View File
@@ -91,18 +91,26 @@
"build": "vite build", "build": "vite build",
"watch": "vite build --watch", "watch": "vite build --watch",
"vscode:prepublish": "npm run build", "vscode:prepublish": "npm run build",
"lint": "npm run lint:app && npm run lint:test", "lint": "eslint .",
"lint:app": "tsc --noEmit -p tsconfig.app.json", "check": "npm run check:app && npm run check:test",
"lint:test": "tsc --noEmit -p tsconfig.test.json", "check:app": "tsc --noEmit -p tsconfig.app.json",
"check:test": "tsc --noEmit -p tsconfig.test.json",
"format": "prettier --write .", "format": "prettier --write .",
"test": "vitest", "test": "vitest",
"test:run": "vitest run" "test:run": "vitest run"
}, },
"devDependencies": { "devDependencies": {
"@eslint/compat": "^2.0.0",
"@eslint/js": "^9.39.0",
"@types/node": "^22.0.0", "@types/node": "^22.0.0",
"@types/uuid": "^10.0.0", "@types/uuid": "^10.0.0",
"@types/vscode": "^1.96.0", "@types/vscode": "^1.96.0",
"@vitest/eslint-plugin": "^1.5.0",
"eslint": "^9.39.0",
"eslint-config-prettier": "^10.1.0",
"globals": "^16.4.0",
"typescript": "^5.7.0", "typescript": "^5.7.0",
"typescript-eslint": "^8.46.0",
"vite": "^8.1.4", "vite": "^8.1.4",
"vitest": "^4.1.10" "vitest": "^4.1.10"
}, },
+2 -2
View File
@@ -42,9 +42,9 @@ describe("FsTaskRepository", () => {
}); });
it("list returns created tasks sorted by updated desc", async () => { it("list returns created tasks sorted by updated desc", async () => {
const a = await repo.create(folder, { ...sampleTask, title: "A" }); await repo.create(folder, { ...sampleTask, title: "A" });
await delay(10); await delay(10);
const b = await repo.create(folder, { ...sampleTask, title: "B" }); await repo.create(folder, { ...sampleTask, title: "B" });
const tasks = await repo.list(folder); const tasks = await repo.list(folder);
expect(tasks).toHaveLength(2); expect(tasks).toHaveLength(2);
+3 -1
View File
@@ -3,6 +3,8 @@ import { IFileSystem, ITaskRepository } from "@/ports";
import { parseTaskFile, serializeTask } from "@/utils/markdown"; import { parseTaskFile, serializeTask } from "@/utils/markdown";
import { generateId } from "@/utils/uuid"; import { generateId } from "@/utils/uuid";
const MAX_SAFE_NAME_LENGTH = 80;
export class FsTaskRepository implements ITaskRepository { export class FsTaskRepository implements ITaskRepository {
constructor( constructor(
private fs: IFileSystem, private fs: IFileSystem,
@@ -93,7 +95,7 @@ export class FsTaskRepository implements ITaskRepository {
.toLowerCase() .toLowerCase()
.replace(/[^a-z0-9\u0400-\u04FF]+/g, "-") .replace(/[^a-z0-9\u0400-\u04FF]+/g, "-")
.replace(/^-|-$/g, "") .replace(/^-|-$/g, "")
.slice(0, 80); .slice(0, MAX_SAFE_NAME_LENGTH);
return this.joinPath(folderPath, `${safeName}${this.fileExtension}`); return this.joinPath(folderPath, `${safeName}${this.fileExtension}`);
} }