sdk

Radroots SDK and bindings
git clone https://radroots.dev/git/sdk.git
Log | Files | Refs | README

commit beb99b13e992af5593e0255a7229a1a0c09a498b
parent ca443903b9cfbaba3f97ec3826f44a3982075553
Author: triesap <tyson@radroots.org>
Date:   Wed, 24 Jun 2026 07:05:52 +0000

dto: guard events registry migration inputs

- inventory current events binding type exports in xtask tests
- verify event inventory against committed package output
- cover integer policy propagation through transparent containers
- validate targeted SDK dto registry tests

Diffstat:
Mtools/xtask/src/dto_render.rs | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtools/xtask/src/dto_roots.rs | 116+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 184 insertions(+), 0 deletions(-)

diff --git a/tools/xtask/src/dto_render.rs b/tools/xtask/src/dto_render.rs @@ -647,4 +647,72 @@ mod tests { "large integer field requires explicit numeric policy" ); } + + #[test] + fn propagates_integer_policy_through_transparent_containers_only() { + let mut registry = Registry::new(); + let counter_id = registry.register_type( + RustTypeId::new("sdk", "Counter"), + TypeDef::Struct( + StructDef::new("Counter", "Counter", span()).with_field( + field("value", "value", TypeRef::Primitive(Primitive::U64)) + .with_int_repr(IntRepr::JsonNumberUnsafe), + ), + ), + ); + registry.register_type( + RustTypeId::new("sdk", "TransparentCounters"), + TypeDef::Struct( + StructDef::new("TransparentCounters", "TransparentCounters", span()) + .with_field( + field( + "maybe_count", + "maybeCount", + TypeRef::option(TypeRef::Primitive(Primitive::U64)), + ) + .with_presence(FieldPresence::optional_nullable()) + .with_int_repr(IntRepr::JsonString), + ) + .with_field( + field( + "count_list", + "countList", + TypeRef::vec(TypeRef::Primitive(Primitive::U64)), + ) + .with_int_repr(IntRepr::JsonString), + ) + .with_field( + field( + "fixed_counts", + "fixedCounts", + TypeRef::array(TypeRef::Primitive(Primitive::U64), 2), + ) + .with_int_repr(IntRepr::JsonString), + ) + .with_field( + field( + "by_key", + "byKey", + TypeRef::Map { + key: Box::new(TypeRef::String), + value: Box::new(TypeRef::Primitive(Primitive::U64)), + }, + ) + .with_int_repr(IntRepr::JsonString), + ) + .with_field( + field("named_counter", "namedCounter", TypeRef::Named(counter_id)) + .with_int_repr(IntRepr::JsonString), + ), + ), + ); + + let rendered = render_registry_types(&registry, &DtoRegistryRenderOptions::default()) + .expect("registry renders"); + + assert_eq!( + rendered.body_ts(), + "export type Counter = { value: number, };\n\nexport type TransparentCounters = { maybeCount?: string | null, countList: Array<string>, fixedCounts: [string, string], byKey: Record<string, string>, namedCounter: Counter, };" + ); + } } diff --git a/tools/xtask/src/dto_roots.rs b/tools/xtask/src/dto_roots.rs @@ -133,6 +133,111 @@ mod tests { package_root_set, }; + const EVENTS_BINDINGS_TYPES_TS: &str = + include_str!("../../../packages/events-bindings/src/generated/types.ts"); + const EVENTS_TYPE_INVENTORY: &[&str] = &[ + "JobFeedbackStatus", + "JobInputType", + "JobPaymentRequest", + "RadrootsAccountClaim", + "RadrootsActiveTradeEnvelope", + "RadrootsActiveTradeMessageType", + "RadrootsAppData", + "RadrootsComment", + "RadrootsCoop", + "RadrootsCoopLocation", + "RadrootsCoopRef", + "RadrootsDocument", + "RadrootsDocumentSubject", + "RadrootsFarm", + "RadrootsFarmLocation", + "RadrootsFarmRef", + "RadrootsFollow", + "RadrootsFollowProfile", + "RadrootsGcsLocation", + "RadrootsGeoChat", + "RadrootsGeoJsonPoint", + "RadrootsGeoJsonPolygon", + "RadrootsGiftWrap", + "RadrootsGiftWrapRecipient", + "RadrootsJobFeedback", + "RadrootsJobInput", + "RadrootsJobParam", + "RadrootsJobRequest", + "RadrootsJobResult", + "RadrootsList", + "RadrootsListEntry", + "RadrootsListSet", + "RadrootsListing", + "RadrootsListingAvailability", + "RadrootsListingBin", + "RadrootsListingDeliveryMethod", + "RadrootsListingImage", + "RadrootsListingImageSize", + "RadrootsListingLocation", + "RadrootsListingProduct", + "RadrootsListingProductTagKeys", + "RadrootsListingStatus", + "RadrootsMessage", + "RadrootsMessageFile", + "RadrootsMessageFileDimensions", + "RadrootsMessageRecipient", + "RadrootsNostrEvent", + "RadrootsNostrEventPtr", + "RadrootsNostrEventRef", + "RadrootsPlot", + "RadrootsPlotLocation", + "RadrootsPlotRef", + "RadrootsPost", + "RadrootsProfile", + "RadrootsProfileType", + "RadrootsReaction", + "RadrootsRelayDocument", + "RadrootsResourceArea", + "RadrootsResourceAreaLocation", + "RadrootsResourceAreaRef", + "RadrootsResourceHarvestCap", + "RadrootsResourceHarvestProduct", + "RadrootsSeal", + "RadrootsTradeAnswer", + "RadrootsTradeDiscountDecision", + "RadrootsTradeDiscountOffer", + "RadrootsTradeDiscountRequest", + "RadrootsTradeDomain", + "RadrootsTradeEconomicActor", + "RadrootsTradeEconomicEffect", + "RadrootsTradeEconomicLineKind", + "RadrootsTradeEnvelope", + "RadrootsTradeInventoryCommitment", + "RadrootsTradeListingCancel", + "RadrootsTradeListingParseError", + "RadrootsTradeListingValidateRequest", + "RadrootsTradeListingValidateResult", + "RadrootsTradeListingValidationError", + "RadrootsTradeMessagePayload", + "RadrootsTradeMessageType", + "RadrootsTradeOrderCancelled", + "RadrootsTradeOrderChange", + "RadrootsTradeOrderDecision", + "RadrootsTradeOrderDecisionEvent", + "RadrootsTradeOrderEconomicItem", + "RadrootsTradeOrderEconomicLine", + "RadrootsTradeOrderEconomicTotals", + "RadrootsTradeOrderEconomics", + "RadrootsTradeOrderItem", + "RadrootsTradeOrderRequested", + "RadrootsTradeOrderResponse", + "RadrootsTradeOrderRevision", + "RadrootsTradeOrderRevisionDecision", + "RadrootsTradeOrderRevisionDecisionEvent", + "RadrootsTradeOrderRevisionProposed", + "RadrootsTradeOrderRevisionResponse", + "RadrootsTradeOrderStatus", + "RadrootsTradePricingBasis", + "RadrootsTradeQuestion", + "RadrootsTradeTransportLane", + ]; + #[test] fn approved_source_roots_build_registries() { for root_set in DTO_PACKAGE_ROOTS { @@ -177,4 +282,15 @@ mod tests { .any(|allowance| allowance.shape_family.contains("IResult")) ); } + + #[test] + fn events_type_inventory_matches_current_package_surface() { + let actual = EVENTS_BINDINGS_TYPES_TS + .lines() + .filter_map(|line| line.strip_prefix("export type ")) + .map(|rest| rest.split([' ', '<']).next().expect("type name")) + .collect::<Vec<_>>(); + + assert_eq!(actual, EVENTS_TYPE_INVENTORY); + } }