Rystem.RepositoryFramework.TypescriptGenerator
10.0.9
dotnet tool install --global Rystem.RepositoryFramework.TypescriptGenerator --version 10.0.9
dotnet new tool-manifest
dotnet tool install --local Rystem.RepositoryFramework.TypescriptGenerator --version 10.0.9
#tool dotnet:?package=Rystem.RepositoryFramework.TypescriptGenerator&version=10.0.9
nuke :add-package Rystem.RepositoryFramework.TypescriptGenerator --version 10.0.9
Rystem.RepositoryFramework.TypescriptGenerator
Rystem.RepositoryFramework.TypescriptGenerator is a .NET CLI tool that inspects C# Repository Framework models and emits a TypeScript client layer for rystem.repository.client.
It generates:
- TypeScript model files
- raw/clean mappers when JSON names or date types require them
- transformers for models and complex keys
bootstrap/repositorySetup.tsservices/repositoryLocator.ts
Installation
# global
dotnet tool install -g Rystem.RepositoryFramework.TypescriptGenerator
# local
dotnet new tool-manifest
dotnet tool install Rystem.RepositoryFramework.TypescriptGenerator
The tool command name is:
rystem-ts
Prerequisites
- .NET 10 SDK
- the frontend package
rystem.repository.client
npm install rystem.repository.client
What the tool actually does
The generator builds your target project, loads the produced assembly, analyzes the requested model and key types with reflection, then writes TypeScript files to the destination folder.
Practical consequence:
- generation is not metadata-only
- your target project must build successfully
Command
rystem-ts generate --dest <destination> --models <definitions> [options]
Options
| Option | Alias | Required | Notes |
|---|---|---|---|
--dest |
-d |
yes | Output folder |
--models |
-m |
yes | Repository definitions |
--project |
-p |
recommended | Path to the .csproj to build |
--overwrite |
no | Defaults to true |
|
--include-deps |
no | Also scan built dependencies in the output folder | |
--deps-prefix |
no | Filter dependency loading by prefix when --include-deps is enabled |
Model definition format
"{Model,Key,Type[,Factory[,BackendFactory]]},{Model2,Key2,Type2,...}"
Fields:
Model: C# model type name, simple or fully qualifiedKey: C# key type name or primitive likestring,Guid,intType:Repository,Query, orCommandFactory: optional client-side registration name; defaults toModelBackendFactory: optional server factory segment appended to the generated API path
Legacy bracket form like [{...},{...}] is also accepted.
Examples
rystem-ts generate \
--project ./src/MyApi/MyApi.csproj \
--dest ./src/generated/repository \
--models "{User,Guid,Repository,users}"
rystem-ts generate \
--project ./src/MyApi/MyApi.csproj \
--dest ./src/generated/repository \
--models "{Calendar,LeagueKey,Repository,serieA,serieA},{Team,Guid,Query,teams}" \
--include-deps \
--deps-prefix "MyCompany."
Output structure
The generator writes these folders:
<destination>/
types/
DateMappers.ts
<lowercase-model-file>.ts
index.ts
transformers/
<ModelName>Transformer.ts
index.ts # only when transformers are emitted
bootstrap/
repositorySetup.ts
services/
repositoryLocator.ts
Notes:
- model filenames are lowercase base names, not necessarily exact CLR names
transformers/index.tsis written only when there are transformers to export
Generated TypeScript model shape
Depending on the analyzed type, each types/*.ts file can contain:
- TypeScript
enums - raw interfaces that match wire JSON names
- clean interfaces with camel-cased property names
- raw/clean mapper functions
- helper classes for nested arrays and dictionaries
The generator emits raw + clean models only when it needs them, mainly for:
System.Text.Json[JsonPropertyName]differencesDateTime,DateTimeOffset, orDateOnly
Type mapping behavior
Important mappings from the current implementation:
string,char→string- numeric primitives and
decimal→number bool→booleanGuid→stringDateTime,DateTimeOffset,DateOnly→ rawstring, cleanDateTimeSpan,TimeOnly→string- non-primitive custom objects → generated interfaces
- arrays →
T[] - dictionaries →
Record<K, V> - enums → numeric TypeScript
enum
Non-primitive nullable/reference handling is simplified on the TypeScript side, so review emitted optional properties when null-vs-missing distinctions matter.
Generic types
The generator understands open and closed generics.
- it emits the open generic model file once
- closed generic repository registrations reuse that base model
- generated bootstrap/transformers pass mapper functions for generic arguments when needed
Generated bootstrap
bootstrap/repositorySetup.ts wires RepositoryServices for you.
import { setupRepositoryServices } from "./bootstrap/repositorySetup";
setupRepositoryServices({
baseUrl: "https://localhost:7058/api/",
});
The generated config surface is intentionally small:
setupRepositoryServices({
baseUrl: "https://localhost:7058/api/",
headersEnricher: async (endpoint, uri, method, headers, body) => ({
...headers,
Authorization: `Bearer ${getToken()}`,
}),
errorHandler: async (endpoint, uri, method, headers, body, err) => {
if (err?.status === 401) {
await refreshToken();
return true;
}
return false;
},
});
Generated repository locator
services/repositoryLocator.ts exposes typed accessors over RepositoryServices.
import { RepositoryLocator } from "./services/repositoryLocator";
const user = await RepositoryLocator.users.get("some-id");
const items = await RepositoryLocator.users.query().execute();
await RepositoryLocator.users.insert("some-id", userToSave);
It generates the correct client registration method based on the descriptor type:
Repository→addRepositoryQuery→addQueryCommand→addCommand
Server-side alignment
The generated paths are meant for Repository Framework API endpoints.
Typical server setup:
builder.Services.AddRepository<User, Guid>(repositoryBuilder =>
{
repositoryBuilder.WithInMemory();
});
builder.Services.AddApiFromRepositoryFramework().WithPath("api");
var app = builder.Build();
app.UseApiFromRepositoryFramework().WithNoAuthorization();
Important caveats
--project is effectively required in most real runs
The CLI can auto-discover a .csproj only when exactly one exists in the current directory. In practice, passing --project explicitly is the reliable path.
.dll input is not a true standalone flow today
The option text says --project can point to a .csproj or .dll, but the pipeline still performs dotnet build logic around a project path. Treat .csproj as the supported input.
The tool always builds in Release
It invokes dotnet build -c Release --no-restore before analyzing output.
Generated config surface is smaller than the runtime supports
The emitted RepositoryConfig only covers:
baseUrlheadersEnrichererrorHandler
If you need runtime settings like custom uri, casing, or key separator tweaks, you may need to extend the generated bootstrap manually.
When to use this tool
Use it when you want:
- TypeScript models kept in sync with Repository Framework DTOs
- ready-made
rystem.repository.clientbootstrap code - generated transformers for dates, JSON-name differences, and complex keys
If you need full control over the frontend surface, treat the generated files as a starting point and commit only the parts you want to keep stable.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
This package has no dependencies.
| Version | Downloads | Last Updated |
|---|---|---|
| 10.0.9 | 95 | 5/13/2026 |
| 10.0.8 | 120 | 3/26/2026 |
| 10.0.7 | 106 | 3/3/2026 |
| 10.0.6 | 106 | 2/22/2026 |
| 10.0.5 | 109 | 2/9/2026 |
| 10.0.4 | 110 | 2/9/2026 |
| 10.0.3 | 109 | 2/9/2026 |
| 10.0.3-preview.15 | 61 | 2/8/2026 |
| 10.0.3-preview.14 | 65 | 2/7/2026 |
| 10.0.3-preview.13 | 63 | 2/7/2026 |
| 10.0.3-preview.12 | 65 | 2/7/2026 |
| 10.0.3-preview.10 | 57 | 2/7/2026 |
| 10.0.3-preview.9 | 71 | 2/7/2026 |
| 10.0.3-preview.8 | 82 | 2/7/2026 |
| 10.0.3-preview.7 | 65 | 2/1/2026 |
| 10.0.3-preview.6 | 69 | 2/1/2026 |
| 10.0.3-preview.4 | 65 | 2/1/2026 |
| 10.0.3-preview.3 | 59 | 2/1/2026 |
| 10.0.3-preview.2 | 63 | 2/1/2026 |
| 10.0.3-preview.1 | 64 | 2/1/2026 |