Skip to content

Schema Definition

surql provides a functional, composable schema builder for SurrealDB. Schemas are defined in TypeScript and used to generate migration SQL.

Tables

Basic Table

import { tableSchema, TableMode } from 'jsr:@oneiriq/surql'

const users = tableSchema('users', TableMode.SCHEMAFULL)

TableMode options:

Mode Description
SCHEMAFULL Only defined fields allowed
SCHEMALESS Any fields allowed (default)

Add Fields

import {
  withFields,
  stringField,
  intField,
  floatField,
  boolField,
  datetimeField,
  arrayField,
  objectField,
  recordField,
  optionalField,
} from 'jsr:@oneiriq/surql'

const users = withFields(
  tableSchema('users', TableMode.SCHEMAFULL),
  stringField('name'),
  stringField('email'),
  intField('age'),
  boolField('active'),
  datetimeField('created_at'),
)

Field Types

Function SurrealDB Type Description
stringField(name) string UTF-8 string
intField(name) int Integer
floatField(name) float Floating point
boolField(name) bool Boolean
datetimeField(name) datetime ISO 8601 datetime
arrayField(name) array Array of values
objectField(name) object Arbitrary object
recordField(name, table) record<table> Record reference
optionalField(field) option<type> Nullable wrapper

Indexes

import { withIndexes, index } from 'jsr:@oneiriq/surql'

const users = withIndexes(
  withFields(tableSchema('users'), stringField('email')),
  index('email_idx', 'email', { unique: true }),
  index('name_idx', 'name'),
)

For MTREE vector indexes:

import { mtreeIndex } from 'jsr:@oneiriq/surql'

const articles = withIndexes(
  withFields(tableSchema('articles'), arrayField('embedding')),
  mtreeIndex('embedding_idx', 'embedding', { dimensions: 1536 }),
)

Permissions

import { withPermissions } from 'jsr:@oneiriq/surql'

const posts = withPermissions(
  tableSchema('posts'),
  {
    select: 'WHERE published = true OR author = $auth.id',
    create: 'WHERE $auth.id != NONE',
    update: 'WHERE author = $auth.id',
    delete: 'WHERE author = $auth.id',
  },
)

Events

import { withEvents, event } from 'jsr:@oneiriq/surql'

const orders = withEvents(
  tableSchema('orders'),
  event('on_create', 'CREATE', 'RETURN $value'),
)

Edges

Edges define graph relationships between tables.

import {
  edgeSchema,
  EdgeMode,
  withFromTable,
  withToTable,
  typedEdge,
} from 'jsr:@oneiriq/surql'

// Relation edge
const authored = typedEdge('authored', 'users', 'posts')

// Or step by step
const likes = withToTable(
  withFromTable(edgeSchema('likes', EdgeMode.RELATION), 'users'),
  'posts',
)

Schema Composition

import type { SchemaDefinition } from 'jsr:@oneiriq/surql'

const schema: SchemaDefinition = {
  tables: [users, posts],
  edges: [authored, likes],
}

Schema Diffing

Generate diffs between two schema states:

import { diffSchemas } from 'jsr:@oneiriq/surql'

const before: SchemaDefinition = { tables: [] }
const after: SchemaDefinition = { tables: [users, posts] }

const diffs = diffSchemas(before, after)
// Returns: SchemaDiff[]

Schema Validation

import { validateSchema } from 'jsr:@oneiriq/surql'

const result = validateSchema(schema)
// result.valid: boolean
// result.issues: { level: 'error' | 'warning', message: string }[]

Schema Introspection

Inspect a live SurrealDB database:

import { introspectSchema } from 'jsr:@oneiriq/surql'

const liveSchema = await introspectSchema(client)

Next Steps