Parser and validators for the deterministic-specifications contract. Each language is its own library. Specs and samples stay in the specifications repo; these libraries only read them.
typescript/— npm package@deterministic-code/deterministic-generators-common(DeterministicParserandVersionSnapshoton the./parserexport, validators on the package root)rust/— cratedeterministic_generators_common(path/git dependency)csharp/—Deterministic.Generators.Common(net10.0class library)
# Cargo.toml
deterministic_generators_common = { git = "https://github.com/deterministic-code/deterministic-generators-common", subdirectory = "rust" }<ProjectReference Include="path/to/deterministic-generators-common/csharp/Deterministic.Generators.Common/Deterministic.Generators.Common.csproj" /><PackageReference Include="Deterministic.Generators.Common" Version="0.1.1" />TypeScript packs pin #main:
"@deterministic-code/deterministic-generators-common": "github:deterministic-code/deterministic-generators-common#main"C# first-party consumers use the ProjectReference. Out-of-repo C# can take the NuGet package.
npm run publish:nuget # pack and smoke-test
npm run publish:nuget -- --publish # push to nuget.org (NUGET_API_KEY)
npm test # TypeScript parser + validator (100% coverage)
sh rust/coverage.sh # cargo llvm-cov, 100% lines + functions
dotnet test csharp/Deterministic.Generators.Common.slnx --settings csharp/coverlet.runsettings
VersionSnapshot reconstructs specification YAML by folding every deterministic/version-*/diff.yaml in name order. Documents are the library YAML AST (YamlValue / YamlMap / YamlSeq / YamlScalar), not compiled IDeterministic and not DeterministicParser output.
| API | Role |
|---|---|
Combine / combine |
Fold already-parsed diff trees (mappings), in order |
Read / read |
Scan a deterministic/ directory and fold matching version dirs |
Documents / documents |
Reconstructed file path → tree |
Yaml / yaml(path) |
Serialize one reconstructed file with the library serializer |
Apply helpers are private instance methods. Version directories must match ^version-\d{8}T\d{6}Z-\d{3}$. Missing or empty diff.yaml is skipped. A non-mapping diff throws expected a mapping. TypeScript read is async; C# and Rust Read are sync.
var snapshot = VersionSnapshot.Read(deterministicRoot);
var types = snapshot.Yaml("types.yaml");
var datasource = snapshot.Yaml("datasource.yaml");import { VersionSnapshot } from "@deterministic-code/deterministic-generators-common/parser";
const snapshot = await VersionSnapshot.read(deterministicRoot);
const types = snapshot.yaml("types.yaml");let snapshot = VersionSnapshot::read(deterministic_root)?;
let types = snapshot.yaml("types.yaml")?;Combine takes an ordered list of parsed mappings, not YAML strings. To compare a fold to a live file, wrap the live tree as { added: true, content } and compare Yaml strings from the same serializer — do not string-compare authored YAML (comments and flow sequences differ).
Per file key in a diff:
{ added: true, content }insertscontent(trueor the strings"true"/"True").{ removed: true }deletes the file.- Object merge: nested apply,
removed:string list deletes keys, new keys are appended. - Keyed collections (sequence of single-key maps):
{ added, changed, removed }. Added entries are prepended. - Otherwise the next value replaces.
Read does not grow IDeterministicReader.