Skip to content

Codegen

@toride/codegen generates TypeScript type declarations from your Toride policy file. This gives you compile-time safety for resource names, roles, permissions, and relations -- so typos and mismatches are caught before runtime.

Installation

bash
pnpm add -D @toride/codegen
bash
npm install -D @toride/codegen
bash
yarn add -D @toride/codegen

TIP

Install as a dev dependency since codegen only runs at build time, not at runtime.

Quick Start

1. Run the CLI

bash
npx toride-codegen policy.yaml -o src/generated/policy-types.ts

This reads your policy file and writes generated TypeScript types to the output path.

2. Use the Generated Types

The generated file contains type declarations for all resources, roles, permissions, and relations defined in your policy:

typescript
// Auto-generated by @toride/codegen — do not edit

/** All action strings declared across all resources */
export type Actions = "read" | "update" | "delete" | "create_task";

/** All resource type names */
export type Resources = "Project" | "Task";

/** Per-resource role types */
export interface RoleMap {
  Project: "viewer" | "editor" | "admin";
  Task: "viewer" | "editor";
}

/** Per-resource permission types */
export interface PermissionMap {
  Project: "read" | "update" | "delete" | "create_task";
  Task: "read" | "update" | "delete";
}

/** Relation map — resource type -> relation name -> target resource type */
export interface RelationMap {
  Project: {
    org: "Organization";
  };
  Task: {
    project: "Project";
    assignee: "User";
  };
}

/** Per-type resolver map — TypeScript ensures all resource types have resolvers */
export type ResolverMap = {
  [R in Resources]?: (
    ref: { type: R; id: string; attributes?: Record<string, unknown> },
  ) => Promise<Record<string, unknown>>;
};

CLI Reference

Usage: toride-codegen <policy-file> -o <output-file> [--watch]

Arguments:
  policy-file          Path to policy YAML or JSON file

Options:
  -o, --output <path>  Output file path (required)
  --watch              Re-generate on policy file change
  -h, --help           Show this help message

Watch Mode

Use --watch to automatically regenerate types whenever your policy file changes:

bash
npx toride-codegen policy.yaml -o src/generated/policy-types.ts --watch

This is useful during development when you are iterating on your policy.

JSON Policies

The CLI also accepts JSON policy files:

bash
npx toride-codegen policy.json -o src/generated/policy-types.ts

Programmatic API

You can also use the generator programmatically:

typescript
import { generateTypes } from "@toride/codegen";
import { loadYaml } from "toride";
import { readFileSync, writeFileSync } from "node:fs";

const content = readFileSync("policy.yaml", "utf-8");
const policy = loadYaml(content);
const types = generateTypes(policy);

writeFileSync("src/generated/policy-types.ts", types, "utf-8");

The generateTypes() function takes a parsed Policy object and returns a string of TypeScript source code.

Generated Types Reference

TypeDescription
ActionsUnion of all unique permission strings across all resources
ResourcesUnion of all resource type names
RoleMapInterface mapping each resource to its role union type
PermissionMapInterface mapping each resource to its permission union type
RelationMapInterface mapping each resource to an object of relation name to target type
ResolverMapTyped resolver map keyed by resource name

Handling Edge Cases

  • Empty resources: If the policy has no resources, Actions and Resources are typed as never.
  • No relations: Resources without relations get Record<string, never> in the RelationMap.
  • Unsafe identifiers: The generator validates all resource names, roles, permissions, and relation names. If any contain characters outside [A-Za-z_][A-Za-z0-9_]*, it throws an error to prevent code injection.

Adding to Your Build

A common pattern is to add a codegen script to your package.json:

json
{
  "scripts": {
    "codegen": "toride-codegen policy.yaml -o src/generated/policy-types.ts",
    "codegen:watch": "toride-codegen policy.yaml -o src/generated/policy-types.ts --watch",
    "build": "pnpm codegen && tsc"
  }
}

Add the generated file to .gitignore if you prefer to regenerate on each build, or commit it if you want diffs to be visible in pull requests.

What's Next