Skip to content

Configuration

d1-eloquent is designed to work with zero configuration in most Cloudflare Workers setups. This page covers database binding detection, per-model connections, and test setup.

Zero-Config Setup

Call configure(env) once at Worker startup. The package automatically reads your D1 bindings:

ts
import { configure } from '@orphnet/d1-eloquent'

export default {
  async fetch(req, env) {
    configure(env)
    return app.fetch(req, env)
  }
}

After this, all query methods (get(), first(), save(), delete(), etc.) work without an explicit db argument:

ts
// Before — explicit db required everywhere
const users = await User.query().limit(50).get(env.DB)

// After — db resolved automatically
const users = await User.query().limit(50).get()

Explicit db arguments still work and take priority — no breaking changes.

Binding Name Resolution

configure(env) detects your database in this order:

Binding nameRegistered as
DEFAULT_DB"default" connection
DB (fallback if DEFAULT_DB absent)"default" connection
TEST_DB"test" connection

If both DEFAULT_DB and DB exist in your env, DEFAULT_DB wins.

wrangler.toml example

toml
[[d1_databases]]
binding = "DB"
database_name = "my-app-db"
database_id = "..."

No extra configuration needed — configure(env) picks up DB automatically.

If you want an explicit name:

toml
[[d1_databases]]
binding = "DEFAULT_DB"
database_name = "my-app-db"
database_id = "..."

Per-Model Connections

Override the default connection for a specific model using static connection:

ts
import { BaseModel } from '@orphnet/d1-eloquent'

// Use a direct D1Database binding
class AnalyticsEvent extends BaseModel<AnalyticsAttrs> {
  static table = 'analytics_events'
  static connection = env.ANALYTICS_DB  // set at startup
}

// Or reference a named connection (must be registered via configure())
class AuditLog extends BaseModel<AuditAttrs> {
  static table = 'audit_logs'
  static connection = 'analytics'  // string key
}

Resolution order for any query:

  1. Explicit db argument (highest priority)
  2. Model's static connection (direct binding or named key)
  3. "default" connection from registry

Test Setup

When NODE_ENV=test, d1-eloquent automatically uses the TEST_DB binding instead of DEFAULT_DB/DB. The per-model connection property is bypassed in test mode — all models use TEST_DB.

toml
# vitest.toml or wrangler config used by vitest-pool-workers
[[d1_databases]]
binding = "TEST_DB"
database_name = "test-db"
database_id = "..."
ts
// vitest.config.ts
import { defineWorkersConfig } from '@cloudflare/vitest-pool-workers/config'

export default defineWorkersConfig({
  test: {
    poolOptions: {
      workers: {
        wrangler: { configPath: './wrangler.toml' },
      },
    },
  },
})

Your test setup calls configure(env) the same way as production:

ts
// test setup or beforeAll
configure(env)  // env.TEST_DB is registered automatically

Or continue passing db explicitly — that always works regardless of mode.

Timestamps Auto-Casting

When timestamps = true (the default), created_at and updated_at are automatically cast to Date via the datetime cast. When softDeletes = true, deleted_at is also auto-cast. You can override these by declaring them in static casts. See Attribute Casting for details.

Error Messages

If no database can be resolved, you'll see a descriptive error:

No database configured. Call configure(env) at Worker startup,
or pass db explicitly to query methods.

If NODE_ENV=test but no TEST_DB binding is configured:

No 'test' database configured. Call configure(env) with an env that includes TEST_DB.

If a model's static connection references an unknown string key:

Unknown connection: "analytics". Register it via configure(env) or check the binding name.

Released under the MIT License.