import { spawnSync } from 'node:child_process'; import { existsSync } from 'node:fs'; const FULL_CHECK_FILES = new Set([ 'package.json', 'pnpm-lock.yaml', 'pnpm-workspace.yaml', 'tsconfig.base.json', 'tsconfig.json', ]); const WORKSPACES = [ { filter: '@kt/openapi-parser', prefix: 'packages/openapi-parser/', }, { filter: '@kt/knife4j-vue3-ui', prefix: 'packages/knife4j-vue3-ui/', }, { filter: '@kwitsukasa/knife4j-swagger-vue3', prefix: 'packages/nestjs-knife4j/', }, { filter: '@kt/knife4j-swagger-vue3-playground', prefix: 'apps/playground/', }, ]; function run(command, args) { const result = spawnSync(command, args, { shell: process.platform === 'win32' && command === 'pnpm', stdio: 'inherit', }); if (result.error) { console.error(result.error.message); process.exit(1); } if (result.status !== 0) { process.exit(result.status ?? 1); } } function output(command, args) { const result = spawnSync(command, args, { encoding: 'utf8', shell: false, }); if (result.error) { console.error(result.error.message); process.exit(1); } if (result.status !== 0) { process.exit(result.status ?? 1); } return result.stdout; } function getPnpmCommand() { return 'pnpm'; } function getStagedFiles() { return output('git', [ 'diff', '--cached', '--name-only', '--diff-filter=ACMR', '-z', ]) .split('\0') .map((file) => file.replaceAll('\\', '/')) .filter(Boolean) .filter((file) => existsSync(file)); } const stagedFiles = getStagedFiles(); if (stagedFiles.length === 0) { console.info('[husky] no staged files.'); process.exit(0); } if (stagedFiles.some((file) => FULL_CHECK_FILES.has(file))) { run(getPnpmCommand(), ['-r', '--sort', 'run', 'typecheck']); process.exit(0); } const affectedFilters = new Set(); for (const file of stagedFiles) { for (const workspace of WORKSPACES) { if (file.startsWith(workspace.prefix)) { affectedFilters.add(workspace.filter); } } } if (affectedFilters.size === 0) { console.info('[husky] no staged workspace files need typecheck.'); process.exit(0); } for (const filter of affectedFilters) { run(getPnpmCommand(), ['--filter', filter, 'run', 'typecheck']); }