twinsphere.Vdi2770
0.1.0
dotnet add package twinsphere.Vdi2770 --version 0.1.0
NuGet\Install-Package twinsphere.Vdi2770 -Version 0.1.0
<PackageReference Include="twinsphere.Vdi2770" Version="0.1.0" />
<PackageVersion Include="twinsphere.Vdi2770" Version="0.1.0" />
<PackageReference Include="twinsphere.Vdi2770" />
paket add twinsphere.Vdi2770 --version 0.1.0
#r "nuget: twinsphere.Vdi2770, 0.1.0"
#:package twinsphere.Vdi2770@0.1.0
#addin nuget:?package=twinsphere.Vdi2770&version=0.1.0
#tool nuget:?package=twinsphere.Vdi2770&version=0.1.0
twinsphere.Vdi2770
A .NET library providing utilities for working with VDI 2770 packages:
- Conversion of VDI 2770 packages to AAS HandoverDocumentation structures
- Validation of VDI 2770 packages for correctness
Installation
dotnet add package twinsphere.Vdi2770
Requires .NET 10 or later.
Usage
Results over Exceptions
Public APIs return FluentResults Result/Result<T> values instead of throwing exceptions. Callers must check result.IsSuccess / result.IsFailed before consuming the value. Exceptions are reserved for programming errors (precondition violations) and catastrophic/unrecoverable failures.
Validating a Package
Vdi2770Validator checks a VDI 2770 package ZIP for structural, model, and consistency errors:
using twinsphere.Vdi2770.Validation;
var validator = new Vdi2770Validator();
var result = validator.Validate(packagePath);
if (result.IsFailed)
{
// Inspect result.Errors for details (e.g. PackageValidationError instances)
}
Vdi2770ValidationOptions.ValidationLevel controls how strictly a package is validated:
ValidationLevel.Vdi2770Conformance(default) checks only what the VDI 2770 standard strictly mandates.ValidationLevel.Strictadditionally flags unreferenced files, unresolvable document relationships, duplicateDocumentVersionlanguages, and orphanedRefersTorelationships.
Independently of the validation level, a nested Document Container or Documentation Container is only included in the converted/validated model if it is referenced via a RefersTo DocumentRelationship from its enclosing container's main document; unreferenced sub-containers present in the ZIP are excluded from the result (and, in Strict mode, reported as an error).
var options = new Vdi2770ValidationOptions { ValidationLevel = ValidationLevel.Strict };
var validator = new Vdi2770Validator(options);
var result = validator.Validate(packagePath);
Converting a Package
Vdi2770Converter validates a package and converts it into an AAS HandoverDocumentation payload, streaming the result into a caller-supplied IHandoverDocumentationSink and routing any digital files through a caller-supplied IDigitalFileHandler:
using twinsphere.Vdi2770.Conversion;
var converter = new Vdi2770Converter();
var result = await converter.ConvertAsync(
packagePath,
submodelId: "https://example.com/ids/sm/1234",
sink: mySink, // implements IHandoverDocumentationSink
digitalFileHandler: myFileHandler // implements IDigitalFileHandler
);
if (result.IsFailed)
{
// Inspect result.Errors for details
}
IHandoverDocumentationSink receives the converted payload (e.g. to serialise it to JSON), and IDigitalFileHandler decides where each digital file referenced by the package ends up (e.g. a directory, archive, or blob store), returning the URI to embed in the resulting HandoverDocumentation.
Retrieving the Code
git clone https://dev.azure.com/twinsphere/Foundation/_git/twinsphere.Vdi2770
cd twinsphere.Vdi2770
Building
Requires the .NET 10 SDK.
dotnet restore
dotnet build
Running Tests
Run the full test suite:
dotnet test
Run a single test by name:
dotnet test --filter "FullyQualifiedName~Vdi2770ConverterTests"
Run a single test project:
dotnet test tests/twinsphere.Vdi2770.Tests.Unit/twinsphere.Vdi2770.Tests.Unit.csproj
Code Style
This project uses the following tools to enforce consistent formatting:
| Tool | Purpose | Config |
|---|---|---|
| CSharpier | C# code formatter | defaults |
| Biome | JSON/XML formatter and linter | defaults |
| EditorConfig | IDE-level style rules | .editorconfig |
To format C# files manually:
dotnet tool restore
dotnet csharpier .
Pre-commit Hooks
This project uses pre-commit to automatically format code and validate commit messages before each commit.
Setup
Install pre-commit:
pip install pre-commitInstall the hooks:
pre-commit install --hook-type pre-commit --hook-type commit-msg
The hooks will now run automatically on git commit. To run them manually against all files:
pre-commit run --all-files
Configured hooks
| Hook | What it does |
|---|---|
csharpier |
Auto-formats staged C# files |
biome-check |
Formats and lints staged JSON/XML files |
commitlint |
Validates commit message format (conventional commits) |
Contributing
This project follows GitHub Flow:
- Create a feature branch from
main(feat/my-feature,fix/my-fix, etc.) - Commit your changes with conventional commit messages (see below)
- Open a pull request against
main - After review and CI passing, merge using squash or merge commit
Please ensure pre-commit hooks are installed and passing before opening a pull request.
Versioning
This project follows Semantic Versioning. The current version is maintained in the <VersionPrefix> property of src/twinsphere.Vdi2770/twinsphere.Vdi2770.csproj, and is kept up to date automatically by the release pipeline (see Releasing) — you normally don't need to edit it by hand.
Releasing
Releases are triggered by pushing a tag of the form:
release/vX.Y.Z
release/vX.Y.Z-SUFFIX # pre-release, e.g. release/v1.2.0-RC1
Pushing such a tag to the Azure DevOps repository runs pipelines/build.azure-pipelines.yml, which:
- Parses the version (and optional pre-release suffix) directly out of the tag name.
- Builds, tests, and packs the NuGet package using that version, overriding whatever is currently checked into the
.csproj(-p:VersionPrefix=X.Y.Z). - Publishes the package to nuget.org (after manual approval).
- Commits the resolved
X.Y.Zback into<VersionPrefix>onmain(suffix dropped), so the repository's on-disk version stays in sync without a manual edit.
The sync-back commit uses the ***NO_CI*** marker so it doesn't re-trigger the pipeline.
Note: the pipeline's Build Service identity must have "Contribute" permission on the repository (and "Bypass policies when pushing" if
mainhas branch policies) for step 4 to succeed. This is a one-time Azure DevOps project setting, not something configured in this repository.
Publishing to nuget.org requires a nuget_api_key secret (see the twinsphere.Vdi2770-cicd Library variable group in Azure DevOps). nuget.org caps API key lifetimes at 30 days, so this key must be regenerated and updated in the Library group periodically — nuget.org does not yet support OIDC-based keyless "Trusted Publishing" for Azure DevOps (only GitHub Actions and GitLab CI, as of this writing).
Commit Messages
Commit messages must follow the Conventional Commits specification. This is enforced by the commitlint pre-commit hook and the CI pipeline.
Examples:
feat: add VDI 2770 package validation
fix: handle missing metadata in converter
docs: update README with build instructions
chore: bump FluentResults to 3.17.0
License
This software is subject to copyright. See LICENSE for the full terms.
Changelog
See CHANGELOG.md for release history.
| 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. |
-
net10.0
- FluentResults (>= 4.0.0)
- MimeMapping (>= 4.0.0)
- PdfPig (>= 0.1.15)
- SharpCompress (>= 1.0.0)
- twinsphere.TypedAasMetamodels (>= 1.3.2)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.1.0 | 88 | 9/8/2026 |