Anarchitecture Bricks Docs

Repository documentation hub for packages, guides, and generated references.

@anarchitects/auth-ts

TypeScript DTOs and domain models for the Anarchitecture authentication stack. The package bundles:

Use it to validate inbound/outbound payloads, share typings between Angular/Nest bricks, and keep auth-specific logic consistent across tiers.

Migration guidance for the Better Auth realignment lives in the auth migration guide. Migration guidance for the contract-driven auth profile model lives in the auth contract migration guide.

Developer + AI Agent Start Here

Features

Authorization Contract

@anarchitects/auth-ts is the source of truth for serialized auth rule shape, but it does not enforce frontend or backend authorization by itself.

PolicyRule

Serialized RBAC rules use the following contract:

This is the contract emitted by /auth/me, persisted through auth permission mapping, and consumed by Angular/Nest authorization helpers.

RoutePolicy

RoutePolicy is intentionally narrower than PolicyRule:

Use RoutePolicy when a consumer only needs to answer "may this user attempt this kind of work at all?" Concrete ownership or field-sensitive checks still belong to loaded resources and CASL ability evaluation in Angular/Nest layers.

This is the shared contract behind @anarchitects/auth-declarations route metadata and the coarse route-attempt helpers in @anarchitects/auth-angular. It is intentionally not the full resource-authorization contract.

Installation

npm install @anarchitects/auth-ts
# or
yarn add @anarchitects/auth-ts
# or
pnpm add @anarchitects/auth-ts

Entry points

Import path Description
@anarchitects/auth-ts Barrel re-export for core models plus the core/session DTO surface
@anarchitects/auth-ts/contracts Contract profile config, schema factories, compatibility helpers, and payload shaping
@anarchitects/auth-ts/dtos Core/session request-response schemas and DTO types (TypeBox)
@anarchitects/auth-ts/dtos/jwt JWT plugin-specific DTO types and schemas
@anarchitects/auth-ts/models Domain models used for user/session/RBAC composition

Contract Profiles

@anarchitects/auth-ts is the source of truth for contract-driven auth behavior across Nest and Angular.

Use the factory whenever you need a custom auth profile or want one object that drives both runtime validation and UI behavior:

import { DefaultAuthContractConfig, assertContractCompatibility, createAuthContracts } from '@anarchitects/auth-ts';

assertContractCompatibility(DefaultAuthContractConfig, '1.0.0');

const contracts = createAuthContracts(DefaultAuthContractConfig);

contracts.registerRequestSchema;
contracts.registerFormMeta.name.required;
contracts.changePasswordFormMeta.newPassword.minLength;

Custom profiles are built by copying the default profile and overriding only the fields you want to change:

import { type AuthContractConfig, DefaultAuthContractConfig, createAuthContracts } from '@anarchitects/auth-ts';

const productProfile: AuthContractConfig = {
  ...DefaultAuthContractConfig,
  version: '1.0.0',
  register: {
    ...DefaultAuthContractConfig.register,
    name: {
      ...DefaultAuthContractConfig.register.name,
      required: true,
      minLength: 3,
      emptyStringPolicy: 'strip',
    },
  },
  login: {
    ...DefaultAuthContractConfig.login,
    password: {
      ...DefaultAuthContractConfig.login.password,
      minLength: 10,
    },
  },
};

const contracts = createAuthContracts(productProfile);

The static DTO schema exports such as RegisterRequestSchema and LoginRequestSchema remain available as default-profile convenience helpers. When a consumer needs profile customization, switch from those fixed exports to createAuthContracts(...).

Usage

Validating DTO payloads

import { Value } from '@sinclair/typebox/value';
import { LoginRequestSchema, LoginRequestDTO } from '@anarchitects/auth-ts/dtos';

const payload: LoginRequestDTO = {
  credential: 'user@example.com',
  password: 'secret123',
};

const errors = [...Value.Errors(LoginRequestSchema, payload)];
if (errors.length > 0) {
  // handle validation error details
}

Note: TypeBox does not ship built-in email validation. Register the format once in your runtime (for example, during app bootstrap):

import { FormatRegistry } from '@sinclair/typebox';

FormatRegistry.Set('email', (value: unknown): value is string => {
  return typeof value === 'string' && /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
});

Working with domain models

import { User, Role, Permission } from '@anarchitects/auth-ts/models';

function can(user: User, action: string, subject: string): boolean {
  const roles: Role[] = user.roles ?? [];
  return roles.some((role) => (role.permissions ?? []).some((permission: Permission) => permission.action === action && permission.subject === subject));
}

The models include timestamps (createdAt, updatedAt) and bidirectional relationships to support dynamic RBAC composition in persistence layers.

Contract profile versioning

Scripts

Development notes

Snapshot test workflow

Contract profile versioning

Contributing

Auth DTOs are maintained in this package and consumed by Nest presentation routes. Update these schemas first, then regenerate OpenAPI via nx run api-specs:generate so every stack stays in sync.

License

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this package except in compliance with the License. You may obtain a copy of the License at the linked address or in the repository's LICENSE file. Unless required by applicable law or agreed to in writing, distributed code is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Source Links