Skip to content

Latest commit

 

History

History
374 lines (260 loc) · 12.8 KB

File metadata and controls

374 lines (260 loc) · 12.8 KB

Contributing

Welcome! We're glad you're interested in Drizzle Cube and want to help us make it better.

Drizzle Cube is maintained by Clifton Cunningham and community contributors. All contributions are reviewed and approved by the maintainer.


There are many ways you can contribute to the Drizzle Cube project:

Submitting bug report

To report a bug or issue, please use our issue form "Bug: ".

Submitting feature request

To request a feature, please use our issue form and start the title with "Feature Request: ".

Providing feedback

There are several ways you can provide feedback:

Contribution guidelines

Pre-contribution setup

Installing Node via NVM (if needed)

# https://github.com/nvm-sh/nvm#install--update-script
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
nvm install 22
nvm use 22

Installing npm

Node.js comes with npm by default. We use npm for package management.

Installing Docker

# https://docs.docker.com/get-docker/
# Use Docker's guide to install Docker for your OS.

Cloning the repository

git clone https://github.com/cliftonc/drizzle-cube.git
cd drizzle-cube

Repository structure

  • 📂 src/

    Core library source code

    • 📂 server/ - Server-side semantic layer implementation
    • 📂 client/ - React components and hooks for analytics UI
    • 📂 adapters/ - Framework adapters (Hono, Express, Fastify, Next.js)
  • 📂 tests/

    Comprehensive test suite with multi-database support

  • 📂 dev/

    Development environment with example implementation, so you can test your changes with HMR.

  • 📂 docs/

    Documentation and implementation plans when using tools like Claude Code (we encourage this).

  • 📂 ../drizzle-cube-*/

    Example projects demonstrating different framework integrations are in separate github repositories.

    • drizzle-cube-express/ - Express.js example
    • drizzle-cube-fastify/ - Fastify example
    • drizzle-cube-hono/ - Hono example
    • drizzle-cube-nextjs/ - Next.js example
    • drizzle-cube-try-site/ - Interactive sandbox
    • drizzle-cube-help-site/ - Main documentation site

Building the project

Run the following script from the root folder to build the project:

npm install && npm run build

Setting up for development

The dev environment uses its own PostgreSQL instance (separate from test databases):

npm run dev:setup  # Starts dev PostgreSQL (port 54821), runs migrations, seeds sample data
npm run dev        # Starts concurrent dev servers (server + client with HMR)

To tear down the dev database:

npm run dev:db:down

Setting up for testing

Tests require Docker for PostgreSQL and MySQL. SQLite and DuckDB use in-memory databases and don't need Docker.

npm run test:setup    # Starts test PostgreSQL (port 54333) and MySQL (port 33077) via Docker
npm test              # Run all tests (default: PostgreSQL)
npm run test:teardown # Stop and remove test database containers

Tip

The dev server and test databases use completely separate Docker containers and ports, so you can run npm run dev and npm test at the same time. This is useful for observing your changes in the browser while verifying they pass tests.

No Docker available? If you're working in a container, a sandbox, or any environment where you can't start Docker, run the DB-free suites instead of npm testnpm run test:sqlite, npm run test:client, npm run test:cli, plus npm run lint and npm run typecheck. test:sqlite runs the same server suite against in-process SQLite, so it's a real verification signal rather than a subset. See CLAUDE.md → Testing in a constrained environment.

Commit message guidelines

We have specific rules on how commit messages should be structured.

It's important to make sure your commit messages are clear, concise, and informative to make it easier for others to understand the changes you are making.

All commit messages should follow the pattern below:

<subject>
<BLANK LINE>
<body>

Example:

Add PostgreSQL array support to measures

Enables aggregation functions on PostgreSQL array columns
for more flexible analytics queries

Warning

All commits should be signed before submitting a PR. Please check the documentation on how to sign commits.

Contributing to the core library

Project structure

  • 📂 src/server/

    Server-side semantic layer with type-safe query building, SQL generation, and security

  • 📂 src/client/

    React components, hooks, and utilities for building analytics dashboards

  • 📂 src/adapters/

    Framework-specific adapters that integrate the semantic layer with web frameworks

Running tests

Drizzle Cube has integration tests that run against real databases with different queries and responses. Tests use Docker containers for PostgreSQL and MySQL, and in-memory databases for SQLite and DuckDB.

If you have added additional logic to the core library, make sure that all tests complete without any failures.

Important

Not every test needs a database. vitest.config.ts defines a DB-free cli project (alongside server and client). Logic that never opens a connection or builds SQL — CLI commands, manifest/artifact parsers, code generators, naming and type mapping — goes in tests/cli/, runs with in-memory fixtures, needs no Docker and no globalSetup, and finishes in milliseconds:

npm run test:cli   # DB-free CLI / parser / codegen tests — no containers required

Reserve the server / engine projects for code that actually issues SQL. Decide by the subject under test, not by where its source file lives — see tests/CLAUDE.md and the live project definitions in vitest.config.ts.

Note

If you have added data types, query features, or new functionality, you need to create additional test cases using the new API to ensure it works properly.

Setup test databases via Docker:

npm run test:setup    # Starts PostgreSQL (port 54333) and MySQL (port 33077)

Run server tests (semantic layer, executors, query planning):

# PostgreSQL (default)
npm run test:postgres

# MySQL
npm run test:mysql

# SQLite (no Docker needed)
npm run test:sqlite

# DuckDB (no Docker needed)
npm run test:duckdb

# All databases sequentially
npm run test:all

Run client tests (React components, hooks, stores):

npm run test:client

Run all tests (server + client):

npm test

Watch mode:

npm run test:watch          # All tests
npm run test:server:watch   # Server tests only
npm run test:client:watch   # Client tests only

Coverage reports:

npm run test:coverage           # Server coverage (default DB)
npm run test:client:coverage    # Client coverage
npm run test:coverage:all       # Server coverage across all databases
npm run test:coverage:complete  # Full coverage (all server DBs + client)

Teardown test databases:

npm run test:teardown  # Stop and remove Docker containers

Environment variables:

Variable Default Description
TEST_DB_TYPE postgres Database to test against (postgres, mysql, sqlite, duckdb)
TEST_DATABASE_URL postgresql://test:test@localhost:54333/drizzle_cube_test PostgreSQL connection URL
MYSQL_TEST_DATABASE_URL mysql://test:test@localhost:33077/drizzle_cube_test MySQL connection URL

Warning

All test database URLs must contain "test" as a safety check to prevent accidental use against production databases.

PR guidelines

  1. PR titles should follow the pattern below:

    [<area>]: <subject>
    

    Examples:

    [Server] Add MySQL JSON field support
    [Client] Improve chart type selection UX  
    [Adapters] Add Fastify CORS configuration
    
  2. PRs should contain a detailed description of everything that was changed.

  3. Commit messages should follow the message style guidelines.

  4. PRs should implement:

    • Tests for features that were added.
    • Tests for bugs that were fixed.
    • Type checking with npm run typecheck
    • Linting with npm run lint

Note

To understand how tests should be created and run, please check the Running tests section.

Contributing to examples

Example projects are located in separate github repositories and follow the same contribution guidelines:

When contributing to examples:

  1. Ensure examples use the latest version of the core library
  2. Update documentation if adding new features to examples
  3. Test examples work with multiple databases where applicable
  4. Keep examples simple and focused on demonstrating specific features

Development Workflow

  1. Fork and clone the repository
  2. Create a branch for your feature/fix
  3. Set up development environment:
    npm install
    npm run build
    npm run test:setup   # Start test database containers (PostgreSQL + MySQL)
    npm run dev:setup    # Start dev database, run migrations, seed sample data
  4. Start development servers:
    npm run dev          # Server + client with HMR
  5. Make your changes with appropriate tests
  6. Run the test suite:
    npm run typecheck
    npm run lint
    npm test             # Server + client tests
  7. Create a pull request with a clear description

Architecture Guidelines

Drizzle-First Design: This project is built around Drizzle ORM as the core:

  • All SQL generation must use Drizzle query builder
  • Never use string concatenation for SQL
  • All database operations go through Drizzle
  • Type safety is enforced through Drizzle schema definitions

Security: SQL injection prevention is paramount:

  • Use parameterized queries only
  • Leverage Drizzle's type safety
  • Include security context in all cube definitions
  • Test multi-tenant isolation

Adding a New Chart Type: Chart types are used inside the AnalysisBuilder component. When adding a new chart type, verify it works end-to-end within the AnalysisBuilder — select it from the chart type picker, configure axes via the chart config panel, and confirm it renders correctly with real query results. See src/client/CLAUDE.md for the full registration steps (chart config, lazy loading, ChartLoader).

Getting Help

Thank you for contributing to Drizzle Cube! 🐲