Thank you for your interest in contributing to Sapatos! This guide will help you understand our development workflow and commit conventions.
-
Clone the repository
git clone https://github.com/architect-eng/sapatos.git cd sapatos -
Install dependencies
npm install
This will automatically set up git hooks via Husky.
-
Run tests and linting
npm run lint # Check code style npm run build # Compile TypeScript npm test # Run test suite
Sapatos follows the Conventional Commits specification. All commit messages are automatically validated using git hooks and CI.
Each commit message consists of a header, an optional body, and an optional footer:
<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
The header is mandatory and must conform to this format:
<type>(<scope>): <subject>
- type: Describes the kind of change (see types below)
- scope (optional): Describes what part of the codebase is affected (e.g.,
db,generate,types) - subject: Short description in imperative mood (e.g., "add feature" not "added feature")
Must be one of the following:
-
feat: A new feature for users
git commit -m "feat(db): add support for composite primary keys" -
fix: A bug fix
git commit -m "fix: correct type inference for array columns" -
docs: Documentation only changes
git commit -m "docs: add migration guide from Zapatos" -
style: Changes that don't affect code meaning (whitespace, formatting)
git commit -m "style: format code with prettier" -
refactor: Code change that neither fixes a bug nor adds a feature
git commit -m "refactor(generate): simplify type generation logic" -
perf: Performance improvement
git commit -m "perf: optimize query compilation for large schemas" -
test: Adding or updating tests
git commit -m "test: add tests for transaction retry logic" -
build: Changes to build system or dependencies
git commit -m "build: update TypeScript to 5.7.2" -
ci: Changes to CI configuration
git commit -m "ci: add Node.js 24 to test matrix" -
chore: Other changes that don't modify src or test files
git commit -m "chore: update .gitignore" -
revert: Reverts a previous commit
git commit -m "revert: feat(db): add composite primary keys"
The scope should describe the area of the codebase affected:
db- Runtime database modulegenerate- Schema generation CLItypes- TypeScript type definitionsshortcuts- Query shortcut functionstransaction- Transaction handlingconditions- WHERE clause buildersconfig- Configuration handlingdeps- Dependencies
Examples:
git commit -m "feat(generate): add support for PostgreSQL domains"
git commit -m "fix(transaction): handle deadlock retry correctly"
git commit -m "docs(shortcuts): improve upsert documentation"The subject line should:
- Use imperative, present tense: "change" not "changed" or "changes"
- Not capitalize the first letter
- Not end with a period (.)
- Be limited to 72 characters or less
✅ Good:
git commit -m "fix: prevent memory leak in connection pool"❌ Bad:
git commit -m "Fixed the memory leak."
git commit -m "Fixes memory leaks in connection pool, also updates docs"The body should:
- Use imperative, present tense
- Include motivation for the change
- Contrast with previous behavior
- Be wrapped at 72 characters
Example:
git commit -m "fix: prevent connection pool exhaustion
The connection pool was not releasing clients after query errors,
causing the pool to be exhausted over time. This adds proper error
handling to ensure clients are always returned to the pool."The footer can contain:
- Breaking Changes: Start with
BREAKING CHANGE:followed by description - Issue References: Reference GitHub issues
Example with breaking change:
git commit -m "feat!: change default isolation level to Serializable
BREAKING CHANGE: The default transaction isolation level has changed
from Read Committed to Serializable. Users who rely on the old behavior
should explicitly set isolationLevel to IsolationLevel.ReadCommitted.
Fixes #123"Breaking changes should be indicated by:
- Adding
!after the type/scope:feat!:orfeat(db)!: - Including
BREAKING CHANGE:in the footer with details
git commit -m "feat(types)!: remove deprecated Jsonable type
BREAKING CHANGE: The Jsonable type has been removed. Use JSONSelectable
instead, which provides better type safety."-
Create a feature branch
git checkout -b feat/my-feature
-
Make your changes
- Write code following existing patterns
- Add tests for new functionality
- Update documentation as needed
-
Commit your changes
git commit -m "feat: add my feature"The git hook will automatically validate your commit message. If it fails:
⧗ input: bad commit message ✖ subject may not be empty [subject-empty] ✖ type may not be empty [type-empty]Fix your commit message and try again.
-
Push your branch
git push origin feat/my-feature
-
Create a Pull Request
- Ensure all commits follow the convention
- CI will validate all commit messages
- Address any review feedback
In rare cases, you may need to bypass the commit message validation:
git commit --no-verify -m "your message"- Keep commits atomic: Each commit should represent a single logical change
- Write meaningful messages: Future you will thank you
- Use the body: Explain why not what (the diff shows what)
- Reference issues: Link to relevant GitHub issues
- Group related changes: Use the scope to organize commits
# Simple feature
git commit -m "feat(db): add support for JSONB operators"
# Bug fix with body
git commit -m "fix(generate): handle enum values with special characters
Enum values containing hyphens or spaces were not being properly
escaped in generated TypeScript. This adds proper quoting for all
enum values.
Fixes #456"
# Breaking change
git commit -m "feat(shortcuts)!: change upsert return type
BREAKING CHANGE: upsert now returns an array instead of a single
object for consistency with other shortcuts. Use upsertOne if you
need the old behavior.
Migration:
- Change: const user = await db.upsert(...)
- To: const [user] = await db.upsert(...)
- Or use: const user = await db.upsertOne(...)"
# Refactoring
git commit -m "refactor(transaction): extract retry logic
Moves the retry logic into a separate function for better testability
and reusability. No behavior changes."
# Documentation
git commit -m "docs: add examples for lateral joins"
# Multiple changes with scope
git commit -m "feat(db): add connection pool monitoring
- Add poolSize and activeConnections getters
- Emit events for pool state changes
- Add debug logging for connection lifecycle"If you have questions about the contribution process or commit conventions, please:
- Check the Conventional Commits specification
- Review existing commits for examples
- Open an issue for discussion
Thank you for contributing to Sapatos! 🚀