madapes

@aurora/schema (0.3.3)

Published 2025-12-27 10:44:40 +00:00 by vlad

Installation

@aurora:registry=
npm install @aurora/schema@0.3.3
"@aurora/schema": "0.3.3"

About this package

@aurora/schema

Schema DSL for defining events, projections, APIs, and authorization rules in Aurora applications.

Overview

Aurora uses a schema-first approach where you define your domain in TypeScript, and the framework generates type-safe code from these definitions.

This package provides:

  • Event Schema DSL - Define domain events with versioning and sharding
  • Projection Schema DSL - Define read models and their storage
  • API Schema DSL - Define REST endpoints with validation and auth
  • Auth Schema DSL - Define authorization rules (RBAC/ABAC)
  • Type Builder - Runtime type system based on Zod

Installation

bun add @aurora/schema

Event Schema DSL

Define domain events with versioning and sharding keys:

import { events } from "@aurora/schema";

export const orderEvents = events.define({
  OrderCreated: {
    version: 1,
    shardingKey: "payload.tenantId",
    payload: (t) => t.object({
      tenantId: t.string(),
      orderId: t.string(),
      userId: t.string(),
      amount: t.number(),
      currency: t.string(),
      createdAt: t.string(),
    }),
  },
  OrderUpdated: {
    version: 1,
    shardingKey: "payload.tenantId",
    payload: (t) => t.object({
      tenantId: t.string(),
      orderId: t.string(),
      amount: t.number().nullable(),
      currency: t.string().nullable(),
    }),
  },
} as const);

Type Builder

The t parameter provides type constructors:

// Primitives
t.string()
t.number()
t.boolean()
t.any()

// Modifiers
t.nullable(inner)
t.optional(inner)

// Complex
t.object({ ... })
t.array(inner)
t.tuple([t1, t2, t3])

// String constraints
.string().min(1)
.string().max(100)
.string().length(10)
.string().email()
.string().url()
.string().uuid()

// Number constraints
.number().min(0)
.number().max(100)

// Enums and literals
t.enum(["active", "inactive"])
t.literal("success")

Projection Schema DSL

Define read models with storage configuration:

import { projections } from "@aurora/schema";
import { orderEvents } from "./events.schema";

export const orderProjections = projections.define(orderEvents, {
  OrderReadModel: (p) => p.hot({
    tenantKey: "tenantId",
    key: (t) => t.object({
      tenantId: t.string(),
      orderId: t.string(),
    }),
    value: (t) => t.object({
      tenantId: t.string(),
      orderId: t.string(),
      userId: t.string(),
      amount: t.number(),
      currency: t.string(),
      status: t.string(),
      createdAt: t.string(),
      updatedAt: t.string().nullable(),
    }),
    hotRetentionDays: 90,
    fromEvents: (e) => ({
      OrderCreated: (ev) => ({
        tenantId: ev.tenantId,
        orderId: ev.orderId,
        userId: ev.userId,
        amount: ev.amount,
        currency: ev.currency,
        status: "pending",
        createdAt: ev.createdAt,
        updatedAt: null,
      }),
      OrderUpdated: (ev, current) => ({
        ...current,
        amount: ev.amount ?? current.amount,
        currency: ev.currency ?? current.currency,
        updatedAt: new Date().toISOString(),
      }),
    }),
  }),
  OrderHistory: (p) => p.history({
    tenantKey: "tenantId",
    aggregateKey: "orderId",
    hotRetentionDays: 365,
    fromEvents: (e) => ({
      "*": (ev) => ({
        eventType: ev.type,
        eventVersion: ev.version,
        eventPayload: ev.payload,
        occurredAt: ev.occurredAt,
      }),
    }),
  }),
} as const);

Projection Types

  • p.hot() - Fast read-optimized storage for current state
  • p.history() - Write-optimized storage for complete event history

API Schema DSL

Define REST endpoints with validation and auth:

import { api } from "@aurora/schema";
import { auth } from "@aurora/schema/auth";

export const routes = api.define({
  rest: (r) => ({
    createOrder: r.post("/api/v1/:tenantId/orders")
      .params((t) => t.object({
        tenantId: t.string(),
      }))
      .body((t) => t.object({
        userId: t.string(),
        amount: t.number().min(0),
        currency: t.string().length(3),
      }))
      .response((t) => t.object({
        orderId: t.string(),
      }))
      .auth(auth.required())
      .auth(auth.requireTenantRole(["admin", "user"])),

    getOrder: r.get("/api/v1/:tenantId/orders/:orderId")
      .params((t) => t.object({
        tenantId: t.string(),
        orderId: t.string(),
      }))
      .response((t) => t.object({
        orderId: t.string(),
        amount: t.number(),
        status: t.string(),
      }))
      .auth(auth.required()),

    listOrders: r.get("/api/v1/:tenantId/orders")
      .params((t) => t.object({
        tenantId: t.string(),
      }))
      .query((t) => t.object({
        status: t.string().optional(),
        limit: t.number().min(1).max(100).optional(),
        offset: t.number().min(0).optional(),
      }))
      .response((t) => t.object({
        orders: t.array(t.object({
          orderId: t.string(),
          amount: t.number(),
          status: t.string(),
        })),
        total: t.number(),
      }))
      .auth(auth.required()),
  }),
} as const);

HTTP Methods

r.get(path)      // GET request
r.post(path)     // POST request
r.put(path)      // PUT request
r.patch(path)    // PATCH request
r.delete(path)   // DELETE request

Auth Rules

import { auth } from "@aurora/schema/auth";

// Authentication
auth.required()   // Require authenticated user
auth.optional()   // Optional authentication
auth.none()       // No authentication required

// Authorization
auth.requireTenantRole(["admin", "user"])
auth.requireTenantPermission(["read:orders", "write:orders"])
auth.requireTenantAttributeIn("tier", ["gold", "platinum"])

Pages Schema DSL

Define SSR pages with validation:

import { pages } from "@aurora/schema";

export const pageRoutes = pages.define({
  dashboard: (p) => p.page("/dashboard/:tenantId")
    .params((t) => t.object({
      tenantId: t.string(),
    }))
    .layout((t) => t.object({
      tenantId: t.string(),
    })),
} as const);

Type Safety

All schemas generate TypeScript types:

import type {
  OrderCreatedPayload,
  OrderReadModelKey,
  OrderReadModelValue,
  CreateOrderParams,
  CreateOrderBody,
  CreateOrderResponse,
} from "./generated/types";

Integration with Codegen

Use with @aurora/codegen to generate:

  • TypeScript types
  • Validators (Zod schemas)
  • Repository interfaces
  • API route handlers
  • Projection workers
bun add @aurora/codegen
aurora codegen

API Reference

See docs/schemas.md for complete schema DSL documentation.

License

MIT

Dependencies

Dependencies

ID Version
zod ^3.22.4
Details
npm
2025-12-27 10:44:40 +00:00
3
latest
11 KiB
Assets (1)
Versions (5) View all
0.3.3 2025-12-27
0.3.2 2025-12-27
0.3.1 2025-12-27
0.3.0 2025-12-27
0.2.0 2025-12-26