madapes

@aurora/codegen (0.3.3)

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

Installation

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

About this package

@aurora/codegen

Code generation engine for Aurora - generates types, validators, repositories, routers, and SDKs from schemas.

Overview

The codegen package transforms schema definitions into production-ready code:

  • TypeScript types from schemas
  • Zod validators
  • Repository interfaces and implementations
  • API route handlers
  • Projection workers
  • Client SDK (TypeScript)
  • React hooks (via @aurora/codegen-react)
  • Zustand stores (via @aurora/codegen-zustand)

Installation

bun add -D @aurora/codegen

Usage

import { codegen } from "@aurora/codegen";
import { loadSchemas } from "@aurora/codegen/loader";

// Load schemas from disk
const schemas = await loadSchemas({
  pattern: "./schemas/**/*.schema.ts",
});

// Generate code
await codegen(schemas, {
  output: "./generated",
  codegen: {
    react: true,
    zustand: false,
    client: true,
  },
});

CLI Integration

Use via @aurora/cli:

aurora codegen

Generated Files

Types

TypeScript types for all schemas:

// generated/types/events.ts
export interface OrderCreatedPayload {
  tenantId: string;
  orderId: string;
  userId: string;
  amount: number;
  currency: string;
}

// generated/types/projections.ts
export interface OrderReadModelKey {
  tenantId: string;
  orderId: string;
}

export interface OrderReadModelValue {
  tenantId: string;
  orderId: string;
  amount: number;
  status: string;
}

// generated/types/api.ts
export interface CreateOrderParams {
  tenantId: string;
}

export interface CreateOrderBody {
  userId: string;
  amount: number;
  currency: string;
}

export interface CreateOrderResponse {
  orderId: string;
}

Validators

Zod validators from type definitions:

// generated/validators/events.ts
export const OrderCreatedSchema = z.object({
  tenantId: z.string(),
  orderId: z.string(),
  userId: z.string(),
  amount: z.number(),
  currency: z.string(),
});

Repositories

Repository interfaces and implementations:

// generated/repositories/OrderRepository.ts
export interface IOrderRepository {
  get(key: OrderReadModelKey): Effect<Env, Error, OrderReadModelValue | null>;
  set(key: OrderReadModelKey, value: OrderReadModelValue): Effect<Env, Error, void>;
  delete(key: OrderReadModelKey): Effect<Env, Error, void>;
}

export class OrderRepository implements IOrderRepository {
  constructor(private storage: Storage) {}
  
  async get(key: OrderReadModelKey) {
    return this.storage.get(key);
  }
  
  async set(key: OrderReadModelKey, value: OrderReadModelValue) {
    return this.storage.set(key, value);
  }
  
  async delete(key: OrderReadModelKey) {
    return this.storage.delete(key);
  }
}

API Handlers

Type-safe HTTP handlers:

// generated/handlers/CreateOrderHandler.ts
export function createOrderHandler(
  deps: Dependencies
): Effect<Dependencies, Error, Response> {
  return async ({ eventLog, logger }) => {
    const { tenantId } = deps.params;
    const { userId, amount, currency } = deps.body;
    
    logger.log(`Creating order for tenant ${tenantId}`);
    
    const event = {
      type: "OrderCreated",
      version: 1,
      tenantId,
      orderId: generateId(),
      userId,
      amount,
      currency,
      createdAt: new Date().toISOString(),
    };
    
    await eventLog.append(event);
    
    return Response.json({ orderId: event.orderId });
  };
}

Projection Workers

Workers that consume from JetStream:

// generated/workers/OrderReadModelWorker.ts
export class OrderReadModelWorker {
  constructor(
    private eventLog: EventLog,
    private storage: Storage,
    private logger: Logger
  ) {}
  
  async start() {
    const stream = this.eventLog.subscribe({
      subjects: ["orders.*.OrderCreated", "orders.*.OrderUpdated"],
    });
    
    await pipe(
      stream,
      supervised(SupervisionStrategies.alwaysRestart(10)),
      run({}, async (event) => {
        await this.processEvent(event);
      })
    );
  }
  
  private async processEvent(event: Event) {
    switch (event.type) {
      case "OrderCreated":
        await this.storage.set(
          { tenantId: event.tenantId, orderId: event.orderId },
          event
        );
        break;
      case "OrderUpdated":
        const current = await this.storage.get(
          { tenantId: event.tenantId, orderId: event.orderId }
        );
        if (current) {
          await this.storage.set(
            { tenantId: event.tenantId, orderId: event.orderId },
            { ...current, ...event.payload }
          );
        }
        break;
    }
  }
}

Client SDK

Type-safe client for frontend:

// generated/client/index.ts
export class AuroraClient {
  constructor(private config: AuroraClientConfig) {}
  
  async createOrder(
    params: CreateOrderParams,
    body: CreateOrderBody
  ): Promise<CreateOrderResponse> {
    const response = await fetch(
      `${this.config.baseUrl}/api/v1/${params.tenantId}/orders`,
      {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "Authorization": `Bearer ${this.config.token}`,
        },
        body: JSON.stringify(body),
      }
    );
    
    if (!response.ok) {
      throw new AuroraClientError(response.status, await response.text());
    }
    
    return response.json();
  }
}

React Hooks

React hooks for frontend (via @aurora/codegen-react):

// generated/hooks/index.ts
export function useCreateOrder(options?: MutationOptions) {
  const { mutate, loading, error } = useMutation(
    async (params: CreateOrderParams, body: CreateOrderBody) => {
      const client = getAuroraClient();
      return client.createOrder(params, body);
    },
    options
  );
  
  return { mutate, loading, error };
}

export function useGetOrder(
  params: GetOrderParams,
  options?: QueryOptions
) {
  const { data, loading, error, refetch } = useQuery(
    async () => {
      const client = getAuroraClient();
      return client.getOrder(params);
    },
    { ...options, enabled: !!params.orderId }
  );
  
  return { data, loading, error, refetch };
}

Options

interface CodegenOptions {
  // Output directory
  output: string;
  
  // What to generate
  codegen: {
    types?: boolean;      // TypeScript types (default: true)
    validators?: boolean; // Zod validators (default: true)
    repositories?: boolean; // Repository interfaces (default: true)
    handlers?: boolean;   // API handlers (default: true)
    workers?: boolean;    // Projection workers (default: true)
    client?: boolean;     // Client SDK (default: true)
    react?: boolean;      // React hooks (default: true)
    zustand?: boolean;   // Zustand stores (default: false)
  };
  
  // Caching
  cache?: {
    enabled?: boolean;   // Enable caching (default: true)
    path?: string;       // Cache file path (default: .codegen-cache.json)
  };
}

Caching

Incremental codegen uses SHA-256 hashing to only regenerate changed files:

// Cache file format
{
  "version": "0.2.0",
  "files": {
    "schemas/events.schema.ts": "abc123...",
    "schemas/projections.schema.ts": "def456..."
  },
  "generated": {
    "generated/types/events.ts": "abc123...",
    "generated/handlers/CreateOrderHandler.ts": "def456..."
  }
}

Disable caching:

await codegen(schemas, {
  output: "./generated",
  cache: { enabled: false },
});

Or use CLI:

aurora codegen --force

Type Generation

The codegen package can generate TypeScript types from runtime schemas:

import { schemaToTypeString } from "@aurora/codegen/type-generator";

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

const schema = t.object({
  name: t.string(),
  age: t.number().min(0),
});

const typeString = schemaToTypeString(schema);
// Output: "{ name: string; age: number; }"

Testing

bun test src/**/*.test.ts

License

MIT

Dependencies

Dependencies

ID Version
@aurora/codegen-eos 0.3.3
@aurora/codegen-react 0.3.3
@aurora/codegen-zustand 0.3.3
@aurora/runtime-effect 0.3.3
@aurora/runtime-http 0.3.3
@aurora/runtime-storage 0.3.3
@aurora/schema 0.3.3
zod ^3.22.4
Details
npm
2025-12-27 10:44:47 +00:00
9
latest
29 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