diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 0000000..2312dc5 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1 @@ +npx lint-staged diff --git a/lint-staged.config.mjs b/lint-staged.config.mjs new file mode 100644 index 0000000..825056e --- /dev/null +++ b/lint-staged.config.mjs @@ -0,0 +1,29 @@ +import fs from 'node:fs'; +import path from 'node:path'; + +// ESLint is configured per-package (client/.eslintrc, server/.eslintrc) and +// each package keeps its own plugins in its own node_modules. So we must +// invoke each package's eslint with paths relative to that package, not from +// the repo root. +const eslintInPackage = (pkg) => (files) => { + const pkgRoot = path.resolve(pkg); + const eslintBin = path.join(pkgRoot, 'node_modules', '.bin', 'eslint'); + if (!fs.existsSync(eslintBin)) { + console.warn( + `[lint-staged] skipping eslint in ${pkg}/: run "(cd ${pkg} && npm install)" to enable.`, + ); + return []; + } + const rels = files + .filter((f) => f.startsWith(pkgRoot + path.sep)) + .map((f) => path.relative(pkgRoot, f)); + if (rels.length === 0) return []; + const args = rels.map((f) => JSON.stringify(f)).join(' '); + return `bash -c "cd ${pkg} && ./node_modules/.bin/eslint --fix ${args}"`; +}; + +export default { + '*.{ts,tsx,js,jsx,mjs,cjs,json,md,yaml,yml}': 'prettier --write', + 'client/**/*.{ts,tsx,js,jsx}': eslintInPackage('client'), + 'server/**/*.{ts,tsx,js}': eslintInPackage('server'), +}; diff --git a/package.json b/package.json index 8091bce..24fc20e 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "db:create": "cd db && npm i && NODE_OPTIONS=\"--loader ts-node/esm --require dotenv/config\" node src/index.ts create", "db:drop": "cd db && npm i && NODE_OPTIONS=\"--loader ts-node/esm --require dotenv/config\" node src/index.ts drop", "check:prepush": "cd server && npm run check:prepush && cd ../client && npm run check:prepush", + "typecheck": "cd server && npm run typecheck && cd ../client && npx tsc --noEmit", "format": "prettier --write \"./**/*.{ts,tsx,json}\"", "generate": "graphql-codegen", "generate:watch": "graphql-codegen --watch \"server/graphql/**/**.ts\"", @@ -50,6 +51,5 @@ "prettier": "^3.8.3", "ts-node": "^10.9.2", "typescript": "^5.9.0" - }, - "lint-staged": {} + } }