Contributing
OpenETL accepts contributions through GitHub. This document covers the contribution process, development setup, and code standards.
Getting Started
Thank you for considering contributing to OpenETL! This open-source project benefits from community contributions of all kinds.
Contribution Types
Adapter Development
New adapter implementations for additional data sources (APIs, databases, file systems). See Custom Adapters for the adapter interface specification.
Requirements for new adapters:
- Complete
AdapterInstanceinterface implementation - Unit tests with mocked dependencies
- Security best practices (parameterized queries for databases)
- Documentation including endpoints and configuration
Bug Fixes
Fixes for framework bugs, adapter issues, or documentation errors.
Feature Enhancements
Improvements to existing functionality, optimization, or new framework features.
Documentation
Documentation improvements, corrections, or additions.
Development Setup
Prerequisites
- Node.js 18.0 or higher
- npm or yarn package manager
- Git
Repository Setup
git clone https://github.com/jspreadsheet/openetl.git
cd openetl
npm install
Project Structure
openetl/
├── src/ # Core framework source
│ ├── index.ts # Orchestrator and main exports
│ ├── types.ts # TypeScript type definitions
│ └── utils/ # Utility functions
├── adapters/ # Official adapters
│ ├── postgresql/
│ ├── mysql/
│ ├── mongodb/
│ ├── hubspot/
│ └── ...
├── tests/ # Core framework tests
├── docs/ # Documentation
└── dist/ # Compiled output
Development Workflow
- Create a feature branch from
main - Implement changes with appropriate tests
- Run test suite:
npm test - Ensure TypeScript compilation:
npm run build - Verify linting passes:
npm run lint
Running Tests
# Run all tests
npm test
# Run specific adapter tests
npm test -- --testPathPattern=adapters/postgresql
# Run with coverage
npm test -- --coverage
Pull Request Process
Before Submitting
- Code Quality: Follow TypeScript coding standards
- Tests: Include unit tests for new functionality
- Documentation: Update relevant documentation
- Type Definitions: Ensure TypeScript types are correct
- Security: Follow security best practices (see below)
Submission Steps
- Create Branch:
git checkout -b feature/your-feature-name
- Commit Changes:
git add .
git commit -m "feat: Add feature description"
git push origin feature/your-feature-name
-
Create Pull Request:
- Navigate to GitHub repository
- Create pull request against
mainbranch - Fill out the PR template with description of changes
- Reference related issues (e.g., "Fixes #123")
-
Review Process:
- Address review feedback promptly
- Update pull request with requested changes
- Maintain clean commit history (squash if needed)
Commit Message Format
Use conventional commit format:
feat:New featuresfix:Bug fixesdocs:Documentation changestest:Test additions or fixesrefactor:Code refactoringchore:Build process or auxiliary tool changes
Code Standards
TypeScript
- Use strict TypeScript compilation
- Provide type definitions for all public APIs
- Avoid
anytypes where possible - Use
unknownfor truly unknown types
Security Requirements
For database adapters:
- Always use parameterized queries - Never interpolate values into SQL
- Escape identifiers - Schema, table, column names must be escaped
- Validate operators - Use whitelist for SQL operators
- Never log credentials - Avoid logging auth objects
See Security for detailed security guidelines.
Error Handling
- Use
AdapterErrorclass for adapter errors - Include appropriate error codes
- Set
retryableflag correctly - Provide context for debugging
throw new AdapterError(
'Connection timeout',
'CONNECTION_FAILED',
true, // retryable
{ host: 'example.com', timeout: 30000 }
);
Testing
- Unit tests for all adapter methods
- Integration tests for complete pipelines
- Mock external dependencies
- Test error scenarios
- Test pagination handling
describe('MyAdapter', () => {
it('downloads data with pagination', async () => {
// Arrange
const adapter = createAdapter(connector, auth);
mockApi.mockResolvedValue({ data: [...] });
// Act
const result = await adapter.download({ limit: 10, offset: 0 });
// Assert
expect(result.data).toHaveLength(10);
expect(result.options?.nextOffset).toBeDefined();
});
});
Documentation
- Document public APIs and interfaces
- Include code examples for new features
- Update relevant guide documents
- Add JSDoc comments for exported functions
Adapter Checklist
When contributing a new adapter, ensure:
- [ ] Implements
AdapterInstanceinterface - [ ] Has unit tests with mocked dependencies
- [ ] Uses parameterized queries (database adapters)
- [ ] Validates operators (database adapters)
- [ ] Escapes identifiers (database adapters)
- [ ] Handles pagination correctly
- [ ] Uses
AdapterErrorfor errors - [ ] Includes
getConfig()returning adapter metadata - [ ] Has README with installation and usage
- [ ] Has documentation page in
docs/ - [ ] Package.json follows standard format
Questions?
- Open an issue on GitHub
- Check existing issues for similar questions
- Review documentation for answered questions
License
By contributing to OpenETL, you agree that your contributions will be licensed under the MIT License.