Thank you for your interest in contributing to Snaplet! We're excited to have you join our community of developers working to make database development better for everyone.
- Code of Conduct
- Getting Started
- Development Setup
- Project Structure
- Development Workflow
- Testing
- Submitting Changes
- Code Style Guidelines
- Documentation
- Release Process
- Getting Help
We are committed to providing a welcoming and inclusive experience for everyone. Please read and follow our Code of Conduct:
- Be respectful and inclusive
- Welcome newcomers and help them get started
- Focus on constructive criticism
- Respect differing viewpoints and experiences
- Show empathy towards other community members
- Node.js v18.18.2 or higher
- Yarn 3.5.0 (we use Yarn workspaces)
- PostgreSQL 12+ (for running tests)
- Git
- Fork the repository on GitHub
- Clone your fork locally:
git clone https://github.com/YOUR-USERNAME/snapshot.git
cd snapshot- Add the upstream repository:
git remote add upstream https://github.com/snaplet/snapshot.git# Install Yarn if you haven't already
corepack enable
# Install all dependencies
yarn installCreate a .env file in the root directory:
# Development database for testing
DATABASE_URL=postgresql://localhost:5432/snaplet_dev
# Test database
TEST_DATABASE_URL=postgresql://localhost:5432/snaplet_test
# Optional: Sentry DSN for error tracking
SENTRY_DSN=
# Optional: Debug mode
DEBUG=snaplet:*# Create test databases
createdb snaplet_dev
createdb snaplet_test
# Run initial setup
yarn workspace @snaplet/cli setup:dev# Build all packages
yarn build
# Watch mode for development
yarn devsnapshot/
├── cli/ # Main CLI package (@snaplet/snapshot)
│ ├── src/
│ │ ├── commands/ # CLI command implementations
│ │ ├── components/ # Shared components
│ │ ├── lib/ # Utilities and helpers
│ │ └── testing/ # Test utilities
│ ├── e2e/ # End-to-end tests
│ └── __fixtures__/ # Test fixtures
├── docs/ # Documentation website
├── packages/ # Shared packages
└── scripts/ # Build and deployment scripts
- @snaplet/cli: The main CLI application
- @snaplet/sdk: Core SDK for database operations
- docs: Documentation website (Next.js + Nextra)
# Update your local main branch
git checkout main
git pull upstream main
# Create a new feature branch
git checkout -b feature/your-feature-name- Write clean, well-documented code
- Follow the existing code style
- Add tests for new functionality
- Update documentation as needed
# Run unit tests
yarn test
# Run specific test file
yarn test path/to/test.ts
# Run e2e tests
yarn test:e2e
# Run all tests with coverage
yarn test:coverage# Run linter
yarn lint
# Fix linting issues
yarn lint:fix
# Format code
yarn formatWe use Vitest for unit testing. Tests should be colocated with the code they test:
// src/lib/format.ts
export function formatBytes(bytes: number): string {
// Implementation
}
// src/lib/format.test.ts
import { describe, it, expect } from 'vitest'
import { formatBytes } from './format'
describe('formatBytes', () => {
it('should format bytes correctly', () => {
expect(formatBytes(1024)).toBe('1 KB')
})
})End-to-end tests are located in cli/e2e/. They test the full CLI workflow:
// cli/e2e/capture/e2e.capture.test.ts
import { test, expect } from '@playwright/test'
import { createTestDb, runSnapletCli } from '../testing'
test('should capture a snapshot', async () => {
const dbUrl = await createTestDb()
const result = await runSnapletCli(['snapshot', 'capture'], {
env: { DATABASE_URL: dbUrl }
})
expect(result.exitCode).toBe(0)
expect(result.stdout).toContain('Snapshot captured successfully')
})Test fixtures are located in cli/__fixtures__/. Add new SQL files for testing specific scenarios.
We follow conventional commits specification:
# Format: <type>(<scope>): <subject>
# Examples:
git commit -m "feat(cli): add support for MySQL databases"
git commit -m "fix(capture): handle tables with no primary key"
git commit -m "docs: update installation instructions"
git commit -m "test(e2e): add tests for subset feature"Commit Types:
feat: New featurefix: Bug fixdocs: Documentation changesstyle: Code style changes (formatting, etc.)refactor: Code refactoringtest: Adding or updating testschore: Maintenance tasks
git push origin feature/your-feature-name- Go to GitHub and create a pull request from your fork
- Fill out the PR template with:
- Clear description of changes
- Related issue numbers
- Screenshots (if UI changes)
- Testing instructions
- All PRs require at least one review
- Address review feedback promptly
- Keep PRs focused and atomic
- Ensure all tests pass in CI
- Use TypeScript for all new code
- Prefer interfaces over types for object shapes
- Use explicit return types for public APIs
- Avoid
any- useunknownif type is truly unknown
// Good
interface UserConfig {
name: string
email: string
}
export function validateConfig(config: unknown): UserConfig {
// Validation logic
}
// Avoid
export function validateConfig(config: any) {
// ...
}- Use custom error classes for specific error types
- Include helpful error messages
- Preserve stack traces
export class SnapshotError extends Error {
constructor(
message: string,
public code: string,
public details?: unknown
) {
super(message)
this.name = 'SnapshotError'
}
}
// Usage
throw new SnapshotError(
'Failed to connect to database',
'DB_CONNECTION_ERROR',
{ host, port }
)- Prefer async/await over callbacks or raw promises
- Handle errors properly with try/catch
- Use
Promise.all()for concurrent operations
// Good
async function captureSnapshot(config: Config): Promise<Snapshot> {
try {
const [schema, data] = await Promise.all([
captureSchema(config),
captureData(config)
])
return { schema, data }
} catch (error) {
throw new SnapshotError('Capture failed', 'CAPTURE_ERROR', error)
}
}- Add JSDoc comments for public APIs
- Include examples in comments
- Document complex algorithms
/**
* Captures a snapshot of the database
*
* @param config - The capture configuration
* @returns A promise that resolves to the snapshot metadata
*
* @example
* ```typescript
* const snapshot = await captureSnapshot({
* databaseUrl: 'postgresql://...',
* subset: { enabled: true }
* })
* ```
*/
export async function captureSnapshot(config: CaptureConfig): Promise<Snapshot> {
// Implementation
}- Update relevant documentation in
docs/when adding features - Include code examples
- Add to changelog for significant changes
We use automated releases via GitHub Actions:
- Merge PRs to
mainbranch - CI automatically creates a release PR
- Review and merge the release PR
- CI publishes to npm and creates GitHub release
Version bumps are determined by conventional commits:
fix:→ patch version (0.0.X)feat:→ minor version (0.X.0)BREAKING CHANGE:→ major version (X.0.0)
- 💬 Discord Community - Ask questions and get help
- 📚 Documentation - Official documentation
- 🐛 Issue Tracker - Report bugs
- 📧 Email - For private inquiries
- Use Debug Mode: Set
DEBUG=snaplet:*for verbose logging - Test Fixtures: Use existing fixtures in
__fixtures__/for testing - Local CLI: Run
yarn workspace @snaplet/cli devfor hot-reloading - Database Issues: Ensure PostgreSQL is running and accessible
Yarn Installation Issues
# Clear cache and reinstall
yarn cache clean
rm -rf node_modules
yarn installPostgreSQL Connection Issues
# Check PostgreSQL is running
pg_isready
# Check connection
psql -d postgresql://localhost:5432/snaplet_devBuild Failures
# Clean build artifacts
yarn clean
yarn buildThank you for contributing to Snaplet! Your efforts help make database development better for developers everywhere. We appreciate your time and expertise.
If you have any questions or need help, don't hesitate to reach out on Discord or create an issue.