Community

Contributing

How to set up the development environment, write tests, and submit pull requests.

Contributions are welcome — bug fixes, documentation improvements, new features, and test coverage. This guide covers the development setup and pull request process.


Development setup

Prerequisites

Clone and install

1
2
3
git clone https://github.com/hassanmubiru/street.git
cd street
npm install

This is an npm workspaces monorepo. npm install at the root installs dependencies for both packages/core and packages/cli.

Build

1
2
3
4
5
6
7
8
# Build both packages
npm run build

# Build only core
npm run build:core

# Build only CLI
npm run build:cli

Run tests

1
2
3
4
5
6
7
8
9
# CLI unit tests (no database needed — fast)
npm run test:cli

# Core integration tests (requires PostgreSQL)
docker compose up -d postgres
npm run test:run

# All system tests
npm run test:system

Project structure

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
street/
├── packages/
│   ├── core/                  # @streetjs/core — framework runtime
│   │   ├── src/               # TypeScript source
│   │   │   ├── cache/         # LRU cache
│   │   │   ├── cli/           # CLI kernel
│   │   │   ├── cluster/       # Cluster coordinator
│   │   │   ├── core/          # DI container, decorators, context
│   │   │   ├── database/      # PostgreSQL wire driver, pool, repository
│   │   │   ├── http/          # HTTP server, router, exceptions, middleware
│   │   │   ├── multipart/     # File upload parser
│   │   │   ├── security/      # JWT, sessions, vault, rate limiter, XSS
│   │   │   ├── telemetry/     # Metrics tracker
│   │   │   ├── webhook/       # Webhook dispatcher
│   │   │   └── websocket/     # WebSocket server, SSE
│   │   └── tests/             # Integration and system tests
│   └── cli/                   # @streetjs/cli — CLI tool
│       ├── src/
│       │   ├── commands/      # create, dev, build, start, test, generate, migrate
│       │   └── tests/         # CLI unit tests
│       ├── bin/               # street.js entry point
│       └── templates/         # .hbs and .sql templates
├── docs/                      # GitHub Pages documentation (Jekyll)
├── scripts/                   # Release and validation scripts
└── .github/
    ├── actions/setup/         # Reusable checkout+install action
    └── workflows/ci-cd.yml    # CI/CD pipeline

Code style

Run the linter:

1
2
npm run lint          # tsc --noEmit on core
npm run lint:workflows  # validate GitHub Actions YAML

Testing requirements

All pull requests must:

  1. Pass the existing test suite (npm run test:cli)
  2. Include tests for new functionality
  3. Not reduce code coverage below the thresholds (85% for CLI, 60% for core)

Writing CLI tests

CLI tests use Node’s built-in node:test runner and operate on temporary directories:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import { describe, it } from 'node:test';
import assert from 'node:assert/strict';
import { mkdtempSync, rmSync } from 'node:fs';
import { join } from 'node:path';
import { tmpdir } from 'node:os';
import { CreateCommand } from '../commands/create.js';

describe('MyNewCommand', () => {
  it('does the right thing', async () => {
    const tmpDir = mkdtempSync(join(tmpdir(), 'street-test-'));
    try {
      // ... test logic
    } finally {
      rmSync(tmpDir, { recursive: true, force: true });
    }
  });
});

Writing core tests

Core tests use the same node:test runner with a live PostgreSQL connection:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import { describe, it, before, after } from 'node:test';
import assert from 'node:assert/strict';
import { PgPool } from '../database/pool.js';

describe('MyFeature', () => {
  let pool: PgPool;

  before(async () => {
    pool = new PgPool({ /* test config */ });
    await pool.initialize();
  });

  after(async () => {
    await pool.close();
  });

  it('works correctly', async () => {
    const result = await pool.query('SELECT 1 AS n');
    assert.equal(result.rows[0]?.['n'], 1);
  });
});

Pull request process

  1. Fork the repository and create a branch from main
  2. Make your changes — keep commits focused and atomic
  3. Run testsnpm run test:cli must pass
  4. Run lintnpm run lint must pass
  5. Update docs — if you changed behaviour, update the relevant page in docs/
  6. Open a PR against main with a clear description of what changed and why

PR title format

1
2
3
4
fix: correct pluralization in generate command log message
feat: add street generate middleware command
docs: add WebSocket authentication example
chore: bump @streetjs/core to 1.0.5

What gets reviewed


Reporting bugs

Open an issue at github.com/hassanmubiru/issues with:


License

By contributing, you agree that your contributions will be licensed under the MIT License.