.do

.do Primitives

Complete guide to SDK primitives available in the do tool

The do tool provides eight SDK primitives that form the foundation of Business-as-Code on the .do platform.

Architecture

All primitives are available in the execution context:

SDK Primitives Architecture

graph TB subgraph "Semantic Layer" DOLLAR[$<br/>Semantic Types<br/>Schema.org] end subgraph "Data Layer" DB[db<br/>Database Operations<br/>CRUD + Relations] end subgraph "AI Layer" AI[ai<br/>Generate + Embed<br/>Batch Processing] end subgraph "Integration Layer" API[api<br/>HTTP Client<br/>Service Proxy] end subgraph "Event Layer" ON[on<br/>Event Handlers<br/>Subscriptions] SEND[send<br/>Event Publishing<br/>Async Queue] end subgraph "Schedule Layer" EVERY[every<br/>Cron Jobs<br/>Recurring Tasks] end subgraph "Context Layer" USER[user<br/>Auth Context<br/>Permissions] end DOLLAR --> DB DOLLAR --> AI DOLLAR --> ON DOLLAR --> SEND DB --> API AI --> API ON --> SEND SEND --> EVERY USER -.permissions.-> DB USER -.permissions.-> AI USER -.permissions.-> SEND

All primitives are available in the execution context:

// Semantic types
$

// Data operations
db

// AI operations
ai

// HTTP operations
api

// Event handling
on

// Event publishing
send

// Scheduling
every

// User context
user

$ - Semantic Context Proxy

The semantic type system based on Schema.org vocabulary.

Type Signatures

interface $ {
  // Create semantic type
  [Type: string]: (data: object) => SemanticObject

  // Event patterns
  [Type: string]: {
    [predicate: string]: {
      [Object: string]: EventPattern
    }
  }
}

Usage

// Create semantic types
const person = $.Person({
  name: 'Alice',
  email: '[email protected]',
})

const organization = $.Organization({
  name: 'Acme Corp',
  legalName: 'Acme Corporation Inc.',
})

// Event patterns
on($.Order.created, handler)
on($.Payment.succeeded, handler)

// Nested semantics
const order = $.Order({
  customer: $.Person({ name: 'Bob' }),
  seller: $.Organization({ name: 'Acme' }),
  orderDate: new Date(),
})

Key Types

Business

  • $.Person - Individual
  • $.Organization - Company
  • $.Business - Business entity

Commerce

  • $.Product - Product/service
  • $.Order - Purchase order
  • $.Invoice - Billing invoice
  • $.Offer - Product offer
  • $.MonetaryAmount - Price with currency

Events

  • $.Event - Generic event
  • $.Action - Generic action
  • $.Task - Work item

Content

  • $.Article - Blog post
  • $.CreativeWork - Creative content
  • $.WebPage - Web page

Documentation

'$.md' // Request full $ documentation

db - Database Operations

Type-safe database with semantic types.

Type Signatures

interface db {
  list<T>(
    type: string,
    options?: {
      where?: Record<string, any>
      limit?: number
      offset?: number
      sort?: Record<string, 'asc' | 'desc'>
      include?: string[]
    }
  ): Promise<T[]>

  get<T>(type: string, id: string): Promise<T | null>

  create<T>(type: string, data: Partial<T>): Promise<T>

  update<T>(type: string, id: string, data: Partial<T>): Promise<T>

  delete(type: string, id: string): Promise<boolean>

  relate(from: { type: string; id: string }, relation: string, to: { type: string; id: string }): Promise<void>
}

Usage

// List records
const businesses = await db.list('Business')
const orders = await db.list('Order', {
  where: { status: 'pending' },
  limit: 10,
  sort: { createdAt: 'desc' },
})

// Get by ID
const order = await db.get('Order', 'ord_123')

// Create with semantic types
const newOrder = await db.create('Order', {
  customer: $.Person({ name: 'Alice' }),
  items: [$.Product({ name: 'Widget', price: 10 })],
  status: 'pending',
})

// Update
await db.update('Order', 'ord_123', {
  status: 'shipped',
  shippedAt: new Date(),
})

// Delete
await db.delete('Order', 'ord_123')

// Create relationships
await db.relate({ type: 'Order', id: 'ord_123' }, 'customer', { type: 'Person', id: 'per_456' })

Readonly Operations

Anonymous users can only:

  • db.list() - List records
  • db.get() - Get single record

Write operations require authentication.

Documentation

'db.md' // Request full db documentation

ai - AI Operations

AI generation, embeddings, and batch processing.

Type Signatures

interface ai {
  generate<T>(options: { prompt: string; model?: string; schema?: SchemaType; temperature?: number; maxTokens?: number }): Promise<T>

  embed(text: string): Promise<number[]>

  batch(requests: Array<{ type: 'generate'; prompt: string; schema?: SchemaType } | { type: 'embed'; text: string }>): Promise<any[]>
}

Usage

// Generate text
const result = await ai.generate({
  prompt: 'Write a product description for a smart coffee maker',
  model: 'gpt-5',
})

// Generate with schema
const plan = await ai.generate({
  prompt: 'Create a business plan for a coffee shop',
  schema: $.BusinessPlan,
  model: 'claude-sonnet-4.5',
})

// Type-safe access
console.log(plan.executive_summary)

// Embeddings
const embedding = await ai.embed('semantic search text')

// Batch operations
const results = await ai.batch([
  { type: 'generate', prompt: 'Write a slogan' },
  { type: 'generate', prompt: 'Write a tagline' },
  { type: 'embed', text: 'product description' },
])

Supported Models

  • gpt-5 (default)
  • claude-sonnet-4.5
  • llama-4
  • grok-4
  • gemini-2.5-pro

Readonly Mode

AI generation has side effects (token usage, costs), so it requires authentication.

Embeddings are readonly and available to anonymous users:

// ✅ Anonymous
await ai.embed('search text')

// ❌ Requires auth
await ai.generate({ prompt: '...' })

Documentation

'ai.md' // Request full ai documentation

api - HTTP Operations

HTTP client and service proxy.

Type Signatures

interface api {
  fetch(
    url: string,
    options?: {
      method?: string
      headers?: Record<string, string>
      body?: string | object
    }
  ): Promise<Response>

  proxy(
    service: string,
    path: string,
    options?: {
      method?: string
      headers?: Record<string, string>
      body?: string | object
    }
  ): Promise<any>
}

Usage

// Fetch external API
const data = await api.fetch('https://api.example.com/data', {
  method: 'GET',
  headers: { Accept: 'application/json' },
})

// POST request
const result = await api.fetch('https://api.example.com/webhooks', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ event: 'order.created' }),
})

// Proxy to integrated service
const customer = await api.proxy('stripe', '/v1/customers/cus_123')

// Create charge via proxy
const charge = await api.proxy('stripe', '/v1/charges', {
  method: 'POST',
  body: {
    amount: 2000,
    currency: 'usd',
    customer: 'cus_123',
  },
})

Readonly Mode

Anonymous users can only make GET requests:

// ✅ Anonymous
await api.fetch('https://api.example.com/data')

// ❌ Requires auth
await api.fetch('https://api.example.com/data', { method: 'POST' })

Documentation

'api.md' // Request full api documentation

on - Event Handlers

Subscribe to semantic events.

Type Signatures

interface on {
  <Event>(pattern: EventPattern | EventPattern[], handler: (data: Event) => Promise<void> | void): void
}

Usage

// Subscribe to single event
on.Order.created(async (order) => {
  console.log('New order:', order.id)

  send.Email({
    to: order.customer.email,
    subject: 'Order Confirmation',
    body: `Your order #${order.id} has been confirmed`,
  })
})

// Subscribe to multiple events
on([$.Order.created, $.Order.updated], async (order) => {
  db.Orders.update(order.id, {
    lastModified: new Date(),
  })
})

// Event handlers with error handling
on.Payment.succeeded(async (payment) => {
  try {
    db.Orders.update(payment.orderId, {
      status: 'paid',
      paidAt: new Date(),
    })
  } catch (error) {
    console.error('Failed to update order:', error)
    send.Error.occurred({ error, payment })
  }
})

Event Patterns

Use semantic triple patterns:

$.Subject.predicate.Object

// Examples
$.Order.created
$.Payment.succeeded
$.User.email.verified
$.Product.inventory.updated

Readonly Mode

Event handlers require authentication (they create persistent subscriptions).

Documentation

'on.md' // Request full on documentation

send - Event Publishing

Publish events to queues.

Type Signatures

interface send {
  <Event>(pattern: EventPattern, data: Event): Promise<void>
}

Usage

// Send email
send.Email({
  to: '[email protected]',
  subject: 'Welcome!',
  body: 'Thank you for signing up',
  from: '[email protected]'
})

// Publish domain event
send.Order.created({
  orderId: 'ord_123',
  customerId: 'cus_456',
  total: 100,
  createdAt: new Date()
})

// Trigger webhook
send.Webhook.trigger({
  url: 'https://example.com/webhook',
  payload: { event: 'order.created', data: { ... } }
})

// Start background job
send.Job.start({
  type: 'export',
  userId: 'usr_789',
  format: 'csv'
})

Event Delivery

Events are:

  • Queued: Delivered asynchronously
  • Reliable: Retried on failure
  • Ordered: Processed in sequence (per queue)

Readonly Mode

Event publishing requires authentication (side effects).

Documentation

'send.md' // Request full send documentation

every - Scheduled Workflows

Schedule recurring tasks.

Type Signatures

interface every {
  (schedule: string | CronExpression, handler: () => Promise<void> | void): void
}

Usage

// Cron syntax
every('0 * * * *', async () => {
  // Run every hour
  db.Orders.list({
    where: { status: 'pending' },
  }).then((pending) => {
    console.log(`Found ${pending.length} pending orders`)

    for (const order of pending) {
      send.Order.reminder({ orderId: order.id })
    }
  })
})

// Every 6 hours
every('0 */6 * * *', async () => {
  db.Caches.list({
    where: { updatedAt: { lt: Date.now() - 6 * 60 * 60 * 1000 } },
  }).then((staleData) => {
    for (const item of staleData) {
      db.Caches.delete(item.id)
    }
  })
})

// Daily at specific time
every('0 9 * * *', async () => {
  // Run daily at 9 AM
  const report = await generateDailyReport()

  send.Email({
    to: '[email protected]',
    subject: 'Daily Report',
    body: report,
  })
})

// Weekly
every('0 8 * * MON', async () => {
  // Run every Monday at 8 AM
  send.Report.weekly({ date: new Date() })
})

Cron Format

┌───────────── minute (0 - 59)
│ ┌───────────── hour (0 - 23)
│ │ ┌───────────── day of month (1 - 31)
│ │ │ ┌───────────── month (1 - 12)
│ │ │ │ ┌───────────── day of week (0 - 6) (Sunday to Saturday)
│ │ │ │ │
│ │ │ │ │
* * * * *

Common patterns:

  • * * * * * - Every minute
  • 0 * * * * - Every hour
  • 0 0 * * * - Daily at midnight
  • 0 9 * * * - Daily at 9 AM
  • 0 0 * * 0 - Weekly on Sunday
  • 0 0 1 * * - Monthly on 1st

Readonly Mode

Scheduling requires authentication (creates persistent cron jobs).

Documentation

For complete documentation with 10+ examples, see:

'every.md' // Request full every documentation

user - User Context

Access user information and permissions.

Type Signatures

interface user {
  current(): {
    id: string
    email: string
    name?: string
  } | null

  session(): {
    expiresAt: Date
    issuedAt: Date
  } | null

  can(action: string, resource: string): boolean
}

Usage

// Get current user
const currentUser = user.current()
if (currentUser) {
  console.log('User ID:', currentUser.id)
  console.log('User email:', currentUser.email)
  console.log('User name:', currentUser.name)
}

// Get session info
const session = user.session()
if (session) {
  console.log('Session expires:', session.expiresAt)
  console.log('Session issued:', session.issuedAt)
}

// Check permissions
const canCreate = user.can('create', 'Order')
const canDelete = user.can('delete', 'Order')
const canAdmin = user.can('admin', '*')

if (canCreate) {
  await db.create('Order', { ... })
} else {
  throw new Error('Permission denied')
}

// Conditional logic based on user
const currentUser = user.current()
if (currentUser) {
  // Show user's orders
  const orders = await db.list('Order', {
    where: { customerId: currentUser.id }
  })
} else {
  // Show public orders only
  const orders = await db.list('Order', {
    where: { visibility: 'public' }
  })
}

Anonymous Users

When not authenticated:

user.current()  // Returns null
user.session()  // Returns null
user.can(...)   // Always returns false

Documentation

For complete documentation with 12+ examples, see:

'user.md' // Request full user documentation

Composability

All primitives compose naturally:

// Event-driven workflow
on.Order.created(async (order) => {
  // Database operation
  db.People.get(order.customerId).then((customer) => {
    // AI generation
    ai.generate({
      prompt: `Write a personalized thank you email for ${customer.name}`,
      schema: $.Email,
    }).then((emailContent) => {
      // Event publishing
      send.Email({
        to: customer.email,
        subject: emailContent.subject,
        body: emailContent.body,
      })
    })

    // API call
    api.fetch('https://analytics.example.com/track', {
      method: 'POST',
      body: JSON.stringify({
        event: 'order.created',
        userId: customer.id,
      }),
    })
  })
})

Security Model

Readonly Operations (Anonymous)

  • db.list(), db.get()
  • ai.embed()
  • api.fetch() (GET only)

Write Operations (Authenticated)

  • db.create(), db.update(), db.delete(), db.relate()
  • ai.generate()
  • api.fetch() (POST, PUT, DELETE)
  • send()
  • on()
  • every()

Permission Checks

// Check before write operations
if (user.can('create', 'Order')) {
  db.Orders.create({ ... })
}

if (user.can('delete', 'Order')) {
  db.Orders.delete(orderId)
}

Next Steps