Skip to content

Oneiriq/surql

Repository files navigation

surql

JSR Version License: MIT SurrealDB

Code-first database toolkit for SurrealDB. Type-safe query builder, schema/migration engine, orchestrator, and surql CLI — all from TypeScript, for Deno and Node.js.

Features

  • Fluent Query Builder — Chainable API for SELECT/INSERT/UPDATE/DELETE with full generics; typeRecord, timeNow, mathSum, countIf, stringLower and friends render inline in both expression and SET contexts.
  • Code-first Schema + MigrationsDEFINE emitters with IF NOT EXISTS, structured schema parser, migration runner, squash, rollback, and drift detection.
  • SurrealDB v3 correctness — Buffered BEGIN ... COMMIT, unrolled GraphQuery depth, v3-valid type::record() everywhere.
  • surql CLImigrate, schema, db, orchestrate, settings subcommands (built on @cliffy/command).
  • Multi-runtime — JSR for Deno, npm for Node.js 18+.
  • Layered settings — env + .env + surql.yaml + surql.toml via loadSettings().
  • Auth & CRUD — Root/Namespace/Database/Scope sign-in, JSON Patch (RFC 6902), merge, upsert, aggregations, pagination.
  • Input sanitisation — Identifier validation, injection prevention, rich error types.

Install

=== "Deno (JSR)"

```ts
import { SurQLClient, query } from 'jsr:@oneiriq/surql'
```

Or via an import map in `deno.json`:

```json
{ "imports": { "surql": "jsr:@oneiriq/surql" } }
```

=== "Node.js (npm)"

```bash
npm install @oneiriq/surql
```

```ts
import { SurQLClient, query } from '@oneiriq/surql'
```

Quick Example

import {
  aggregateRecords,
  count,
  countIf,
  createRecord,
  getRecord,
  mathSum,
  SurQLClient,
  timeNow,
  typeRecord,
  updateRecord,
} from 'jsr:@oneiriq/surql'

const client = new SurQLClient({
  host: 'localhost',
  port: '8000',
  namespace: 'myapp',
  database: 'prod',
  username: 'root',
  password: 'root',
})
await client.signin({ type: 'root', username: 'root', password: 'root' })
const db = await client.getConnection()

// First-class record references — render as type::record('task:abc').
const task = typeRecord('task', 'abc')

// time::now() / math::sum() render inline in SET clauses.
await createRecord(db, 'audit', { at: timeNow(), action: 'start' })
await updateRecord(db, task, { status: 'done', finishedAt: timeNow() })

// typeRecord works for reads too.
const row = await getRecord<Task>(db, task)

// Typed aggregation — no hand-rolled SurrealQL.
const buckets = await aggregateRecords({
  table: 'memory_entry',
  select: {
    total: count(),
    failed: countIf('status = "failed"'),
    strengthSum: mathSum('strength'),
  },
  groupBy: ['network'],
  client: db,
})

await client.close()

surql CLI

# Run from a clone
deno task cli --help

# Apply pending migrations
deno task cli migrate up

# Inspect live schema vs snapshot
deno task cli schema diff --schema db/snapshot.json

# Orchestrate across environments (JSON config)
deno task cli orchestrate deploy --environments staging,production --strategy rolling --batch-size 2

The full reference lives at docs/cli.md (rendered on the docs site).

Documentation

Requirements

  • Deno 2.x or Node.js 18+
  • SurrealDB v3 (integration tests pinned to surrealdb/surrealdb:v3.0.5)

Contributing

Local gating is enforced by .githooks/pre-push (mirrors CI). Enable once per clone:

git config core.hooksPath .githooks

See CONTRIBUTING.md.

License

MIT — see LICENSE.

Python

Looking for SurrealDB tooling in Python? See surql-py — the code-first schema, migration, and query toolkit for SurrealDB built for Python 3.12+.

Support

About

A code-first database toolkit for SurrealDB

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Contributors