Status: initial draft v0.1, not for production use
An idiomatic C#/.NET library for working with GTS (Global Type System) identifiers and JSON/JSON Schema artifacts.
Supported GTS spec version: v0.14.1 (pinned in .gts-spec-version)
Featureset:
- OP#1 - ID Validation: Verify identifier syntax using regex patterns
- OP#2 - ID Extraction: Fetch identifiers from JSON objects or JSON Schema documents
- OP#3 - ID Parsing: Decompose identifiers into constituent parts (vendor, package, namespace, type, version, etc.)
- OP#4 - ID Pattern Matching: Match identifiers against patterns containing wildcards
- OP#5 - ID to UUID Mapping: Generate deterministic UUIDs from GTS identifiers
- OP#6 - Instance Validation: Validate object instances against their corresponding schemas
- OP#7 - Relationship Resolution: Load all schemas and instances, resolve inter-dependencies, and detect broken references
- OP#8 - Compatibility Checking: Verify that schemas with different MINOR versions are compatible
- OP#8.1 - Backward compatibility checking
- OP#8.2 - Forward compatibility checking
- OP#8.3 - Full compatibility checking
- OP#9 - Version Casting: Transform instances between compatible MINOR versions
- OP#10 - Query Execution: Filter identifier collections using the GTS query language
- OP#11 - Attribute Access: Retrieve property values and metadata using the attribute selector (
@) - OP#12 - Schema Validation: Validate schema against its precedent schema
#TODO: NuGet packagesusing Gts;
using Gts.Extraction;Extract entity and schema IDs from JSON objects (and JSON Schema documents). Uses System.Text.Json (JsonObject / JsonNode).
- ExtractId(JsonObject, GtsExtractOptions?) — returns
ExtractResultwithId,SchemaId, which fields were used, andIsSchema.Idis null when no valid ID is found. - ExtractId(JsonNode?) / ExtractId(JsonElement) — overloads for different JSON sources.
- ExtractEntity(JsonObject, …) — returns
GtsJsonEntitywith parsedGtsId, schema ID, and all GtsRefs (every GTS ID in the tree with path). - ExtractReferences(JsonNode?) — walks the tree and returns all GTS IDs with their JSON paths.
- GtsExtractOptions.Default — default entity fields.
var node = JsonNode.Parse("""{ "gtsId": "gts.acme.order.ns.invoice.v1.0", "name": "Order 1" }""");
var result = GtsExtract.ExtractId(node.AsObject());
// result.Id, result.SchemaId, result.SelectedEntityField, result.IsSchema
var entity = GtsExtract.ExtractEntity(node.AsObject());
// entity.GtsId, entity.GtsRefs (all GTS IDs + paths)
var refs = GtsExtract.ExtractReferences(node);Decompose GTS identifiers into constituent parts (vendor, package, namespace, type, version, etc.).
- Parse a type ID (trailing
~) or instance ID; TryParse for safe parsing without exceptions. - ParsePattern / TryParsePattern for patterns that may end with a wildcard (
.*).
// Parsing
var id = GtsId.Parse("gts.acme.order.ns.invoice.v1~");
// Safe parsing
if (GtsId.TryParse("gts.vendor.pkg.ns.type.v1.0", out var id))
// do something
// Pattern (for matching)
var pattern = GtsId.ParsePattern("gts.acme.order.*");
// Safe pattern parsing
if (GtsId.TryParsePattern("gts.acme.order.*", out var pattern))
// do somethingMatch identifiers against patterns containing wildcards.
- Matches(GtsId pattern) — match this ID against a parsed pattern.
- Matches(string pattern) — match this ID against a pattern string.
var candidate = GtsId.Parse("gts.acme.order.ns.invoice.v1.0");
// Match against pattern (parsed)
var pattern = GtsId.ParsePattern("gts.acme.order.*");
candidate.Matches(pattern); // true
// Match against pattern string
candidate.Matches("gts.acme.order.*"); // true
candidate.Matches("gts.acme.order.ns.*"); // true
candidate.Matches("gts.other.*"); // false
// Exact match (no wildcard)
candidate.Matches("gts.acme.order.ns.invoice.v1.0"); // trueGenerate a deterministic UUID v5 from a GTS identifier. The same ID always yields the same UUID (RFC 4122, namespace + name hashed).
- ToGuid() — returns a
Guidfor this GTS ID using the standard GTS namespace.
var id = GtsId.Parse("gts.acme.order.ns.invoice.v1.0");
Guid uuid = id.ToGuid(); // deterministic: same ID → same UUID every timeValidate stored JSON instances against Draft 07 JSON Schemas registered in the same GtsRegistry, including gts:// $ref between schemas and GTS $$id / $$ref / $$schema keywords on schema documents.
- ValidateInstanceAsync(instanceId) — loads the instance (by GTS instance id or opaque id such as a UUID), resolves its type (chained instance id or
typefield), fetches the schema from the store, and evaluates the instance with JsonSchema.Net. ReturnsGtsInstanceValidationResultwithOk,Id,FailureReason, and optionalSchemaErrors.
using Gts.Extraction;
using Gts.Store;
var registry = GtsRegistry.InMemory(new GtsRegistryConfig(false));
// Save schemas (JSON Schema with $id or $$id) and instances via SaveAsync(GtsJsonEntity.ExtractEntity(...))
var result = await registry.ValidateInstanceAsync("gts.vendor.pkg.ns.type.v1~x._.myinst.v1");
// result.Ok, result.FailureReason, result.SchemaErrorsCommon tasks are wrapped in the Makefile; run make help to
list every target. Requires the .NET SDK (see global.json).
make build # build the solution and publish the gts CLI to ./bin/gts
make fmt # verify formatting (dotnet format whitespace + style)
make lint # run analyzers (dotnet format analyzers)
make test # run the unit tests
make security # audit NuGet dependencies for known vulnerabilities
make coverage # collect code coverage
make check # full local gate: fmt + lint + test + gts-spec-testsmake gts-spec-tests runs the shared
gts-spec conformance suite
against a freshly built server. Tests come from the published runner
image ghcr.io/globaltypesystem/gts-spec-tests; the tag is pinned in
.gts-spec-version as an immutable
vMAJOR.MINOR.PATCH — every commit reproduces the same test run, and
rolling forward is a deliberate bump of that file. Requires a working
Docker daemon plus the .NET SDK (the target builds the CLI binary before
pulling the test-runner image).
make gts-spec-tests # full suite on :8000
make gts-spec-tests PORT=8001 # different port
make gts-spec-tests TEST=test_op1_id_validation.py # single file / selectorOpt into the rolling minor tag, try a different patch, or test a fork:
make gts-spec-tests GTS_SPEC_VERSION=v0.11 # rolling vMAJOR.MINOR
make gts-spec-tests GTS_SPEC_VERSION=v0.11.0 # specific patch
make gts-spec-tests GTS_SPEC_IMAGE=ghcr.io/your-fork/gts-spec-testsIterating on the test suite itself? Mount a local checkout over /tests:
make gts-spec-tests GTS_SPEC_TESTS_DIR=../gts-spec/testsFor tight test-edit loops, keep a long-running server in one terminal and re-run targeted tests in another:
# Terminal 1
make gts-server PORT=8001
# Terminal 2
make gts-spec-tests-run PORT=8001 TEST=test_op6_instance_validation.pyApache License 2.0