Comprehensive linting solution for code quality and commit messages, powered by Funish.
- 🎯 Staged files linting
- 📝 Commit message validation
- ⚙️ Flexible configuration
- 🔄 Git hooks integration
- 🎨 Multiple linter support
- 🚀 Easy to use CLI
- 💪 TypeScript support
- 📦 Zero configuration defaults
# npm
$ npm install -D @funish/lint
# yarn
$ yarn add -D @funish/lint
# pnpm
$ pnpm add -D @funish/lintCreate a lint.config.ts file:
import { defineLintConfig } from "@funish/lint";
export default defineLintConfig({
// Staged files linting configuration
staged: {
// Lint TypeScript files
"*.ts": "eslint --fix",
// Format other files
"*.{json,md}": "prettier --write",
// Run tests for changed files
"__tests__/**/*.ts": "jest --findRelatedTests",
},
// Commit message validation
commitMsg: {
// Conventional commit types
type: {
enum: ["feat", "fix", "docs", "style", "refactor", "test", "chore"],
rules: ["lowercase"],
},
// Scope validation
scope: {
rules: ["lowercase", "kebabcase"],
},
// Description validation
description: {
rules: ["phrasecase"],
},
},
});Use with @funish/githooks for seamless Git integration:
// githooks.config.ts
import { defineGithooksConfig } from "@funish/githooks";
export default defineGithooksConfig({
hooks: {
// Lint staged files before commit
"pre-commit": "pnpm lint staged",
// Validate commit message
"commit-msg": "pnpm lint commit-msg",
},
});# Lint staged files
$ lint staged
# Validate commit message
$ lint commit-msg
# Show help
$ lint --helpThe staged configuration maps file patterns to lint commands:
{
staged: {
[pattern: string]: string | string[]
}
}- Supports glob patterns
- Can use negation patterns (
!pattern) - Accepts single command or array of commands
- Commands run in sequence for matched files
The commitMsg configuration validates commit messages according to Conventional Commits 1.0.0 specification:
{
commitMsg: {
type?: {
enum?: string[] // Allowed types (e.g., ['feat', 'fix', 'docs'])
rules?: string[] // Validation rules
},
scope?: { // Optional scope validation
rules?: string[] // Validation rules
},
description?: {
rules?: string[] // Validation rules
},
body?: { // Optional body validation
rules?: string[] // Validation rules
}
}
}<type>[optional scope][!]: <description>
[optional body]
[optional footer(s)]
type: The type of change (e.g., feat, fix, docs)scope: Optional scope of the change in parentheses (e.g., parser)!: Optional breaking change indicatordescription: Brief description of the changebody: Optional detailed descriptionfooter: Optional footer (e.g., BREAKING CHANGE: description)
Breaking changes can be indicated in two ways:
- Using the
!character before the colon - Using a
BREAKING CHANGE:orBREAKING-CHANGE:footer
Example:
feat(api)!: change authentication method
BREAKING CHANGE: new authentication method requires token
lowercase: Must be lowercaseuppercase: Must be uppercasecamelcase: Must be camelCasekebabcase: Must be kebab-casesnakecase: Must be snake_casepascalcase: Must be PascalCasesentencecase: Must be Sentence casephrasecase: Must be phrase case
{
commitMsg: {
type: {
enum: ['feat', 'fix', 'docs', 'style', 'refactor', 'perf', 'test', 'build', 'ci', 'chore', 'revert'],
rules: ['lowercase']
},
scope: {
rules: ['lowercase']
},
description: {
rules: ['phrasecase']
},
body: {
rules: ['phrasecase']
}
}
}Creates a type-safe lint configuration.
config(LintConfig): Configuration objectstaged: Staged files configurationcommitMsg: Commit message configurationextends: Base configuration to extend
Validates commit messages against rules.
await commitMsgLint({
type: { enum: ["feat", "fix"] },
});Runs linters on staged files.
await stagedLint({
"*.ts": "eslint --fix",
});Please read our Contributing Guide before submitting a Pull Request to the project.