Contributing
Guide for contributing to cenglu
Contributing to Cenglu
Thank you for your interest in contributing to cenglu! This guide will help you get started.
Code of Conduct
We expect all contributors to be respectful and constructive. Please:
- Be welcoming and inclusive
- Respect differing viewpoints
- Accept constructive criticism
- Focus on what's best for the project
Getting Started
Prerequisites
- Node.js 18+ or Bun
- Git
- TypeScript knowledge
Setup
-
Fork the repository
Visit github.com/ayungavis/cenglu and click "Fork"
-
Clone your fork
git clone https://github.com/YOUR_USERNAME/cenglu.git cd cenglu -
Install dependencies
bun install # or npm install -
Create a branch
git checkout -b feature/my-new-feature # or git checkout -b fix/issue-123
Development Workflow
Project Structure
cenglu/
├── src/
│ ├── logger.ts # Core Logger class
│ ├── types.ts # Type definitions
│ ├── context.ts # AsyncLocalStorage context
│ ├── redaction.ts # Redaction logic
│ ├── format/ # Output formatters
│ │ ├── json.ts
│ │ ├── pretty.ts
│ │ ├── ecs.ts
│ │ └── ...
│ ├── middleware/ # Framework middleware
│ │ ├── express.ts
│ │ ├── nestjs.ts
│ │ └── ...
│ ├── plugins/ # Built-in plugins
│ │ ├── sampling.ts
│ │ ├── redaction.ts
│ │ └── ...
│ ├── transports/ # Output transports
│ │ ├── console.ts
│ │ └── file.ts
│ └── index.ts # Main exports
├── tests/ # Test files
├── examples/ # Usage examples
└── docs/ # DocumentationAvailable Scripts
# Development build (watch mode)
bun run dev
# Production build
bun run build
# Run tests
bun run test
# Run tests in watch mode
bun run test:watch
# Run tests with coverage
bun run test:coverage
# Type checking
bun run typecheck
# Linting
bun run lint
# Format code
bun run formatMaking Changes
-
Write code
Make your changes following the Code Style guidelines.
-
Add tests
All new features and bug fixes must include tests. Use the built-in testing utilities:
import { describe, expect, it } from "vitest"; import { createTestLogger } from "../src/testing"; describe("Logger", () => { it("logs at info level", () => { const { logger, transport } = createTestLogger(); logger.info("Test message", { data: 123 }); expect(transport.hasLog("info", "Test message")).toBe(true); expect(transport.last()?.context?.data).toBe(123); }); });For comprehensive testing examples and utilities, see the Testing Guide.
-
Run tests
bun run test -
Check types
bun run typecheck -
Format and lint
bun run format bun run lint
Commit Guidelines
We follow Conventional Commits:
<type>(<scope>): <description>
[optional body]
[optional footer]Types:
feat: New featurefix: Bug fixdocs: Documentation changesstyle: Code style changes (formatting, etc.)refactor: Code refactoringperf: Performance improvementstest: Test changeschore: Build process or auxiliary tool changes
Examples:
git commit -m "feat(middleware): add Fastify middleware"
git commit -m "fix(logger): handle null context values"
git commit -m "docs: update installation guide"
git commit -m "test(redaction): add PCI compliance tests"Opening a Pull Request
-
Push your branch
git push origin feature/my-new-feature -
Create pull request
- Go to your fork on GitHub
- Click "New Pull Request"
- Select your branch
- Fill out the PR template
-
PR checklist
- Tests pass (
bun run test) - Types are correct (
bun run typecheck) - Code is formatted (
bun run format) - Lint passes (
bun run lint) - Documentation updated (if needed)
- Changelog updated (if needed)
- Commit messages follow convention
- Tests pass (
-
Wait for review
Maintainers will review your PR and may request changes.
Code Style
TypeScript
- Use TypeScript strict mode
- Prefer
constoverlet - Use type inference when possible
- Export types explicitly
// Good
export type LogLevel = "trace" | "debug" | "info" | "warn" | "error" | "fatal";
export function createLogger(options?: LoggerOptions): Logger {
const level = options?.level ?? "info";
// ...
}
// Bad
export function createLogger(options?: any) {
let level = options?.level || "info";
// ...
}Formatting
We use Biome for formatting. Run:
bun run formatNaming Conventions
- Classes: PascalCase (
Logger,Redactor) - Functions: camelCase (
createLogger,formatJson) - Constants: UPPER_SNAKE_CASE (
DEFAULT_LEVEL,MAX_DEPTH) - Types: PascalCase (
LogLevel,LogRecord) - Private fields: prefix with
private(private state)
Comments
- Use JSDoc for public APIs
- Add comments for complex logic
- Avoid obvious comments
/**
* Create a logger instance
*
* @param options - Logger configuration options
* @returns Logger instance
*
* @example
* const logger = createLogger({
* service: "my-app",
* level: "info",
* });
*/
export function createLogger(options?: LoggerOptions): Logger {
// ...
}Testing
Test Structure
import { describe, expect, it, beforeEach, afterEach } from "vitest";
import { createTestLogger } from "../src/testing";
describe("Feature", () => {
let logger, transport, reset;
beforeEach(() => {
({ logger, transport, reset } = createTestLogger());
});
afterEach(() => {
reset(); // Clean up between tests
});
it("should do something", () => {
// Arrange & Act
logger.info("test", { key: "value" });
// Assert
expect(transport.hasLog("info", "test")).toBe(true);
expect(transport.last()?.context?.key).toBe("value");
});
});For detailed testing patterns, utilities, and examples, see the Testing Guide.
Test Coverage
We aim for >90% test coverage. Check coverage with:
bun run test:coverageTesting Best Practices
- Use
createTestLogger()fromcenglu/testingfor logger tests - Test public APIs, not implementation details
- Use descriptive test names
- Keep tests isolated (no shared state)
- Mock external dependencies with
MockTimeandMockRandom - Test edge cases and error conditions
- Clean up with
reset()inafterEachhooks
Performance
Performance Guidelines
- Minimize allocations in hot paths
- Use lazy evaluation where possible
- Avoid synchronous I/O
- Cache expensive computations
Documentation
Updating Docs
Documentation is in the docs/ directory using MDX format.
docs/
├── index.mdx
├── getting-started/
│ ├── installation.mdx
│ └── basic-usage.mdx
└── api/
└── logger.mdxDocumentation Style
- Use clear, concise language
- Include code examples
- Add JSDoc comments to public APIs
- Update README if needed
Releases
Releases are handled by maintainers:
- Update version in
package.json - Update
CHANGELOG.md - Create git tag
- Publish to npm
Getting Help
- Issues: github.com/ayungavis/cenglu/issues
- Discussions: GitHub Discussions
- Email: ayungavis@gmail.com
Issue Reporting
Bug Reports
Include:
- cenglu version
- Node.js/Bun version
- Operating system
- Minimal reproduction
- Expected vs actual behavior
Feature Requests
Include:
- Use case
- Proposed API
- Example usage
- Alternatives considered
License
By contributing, you agree that your contributions will be licensed under the MIT License.
Recognition
Contributors are recognized in:
CHANGELOG.md- GitHub contributors page
- Release notes
Thank you for contributing to cenglu! 🎉