Release v21.0.0
Summary
One release covering the proxy generator, the command pipeline's validation surface, and the command form. Supersedes #2442, #2443, #2444 and #2445. Three changes are breaking.
Added
TypeToTsTypebuild item, declaring how a .NET type crosses the wire — consulted ahead of the built-in map, so it corrects an existing type as readily as it declares a new oneValidationResultReasononValidationResult, so a rejection can be told apart from another without matching message text, which is presentation and changes without noticeShouldHaveValidationErrorBecauseOf, for asserting why a command was rejected — asserting only that it failed passes just as readily when it failed for the wrong reasonICommandResultAssertionPolicy, a seam for applying a repository's own policy on top of the built-inCommandResultassertions, so a shared convention lives in one place instead of every specARC0015, warning when a query parameter is declared raw and converted to a concept in the method body, which skips the concept's validator so an invalid value reaches the handler as though it had been validatedmarkAsCommandFormFieldandmarkAsCommandFormColumn, so a command form field survives a build transform that rewritesdisplayName— Storybook'sreactDocgen: 'react-docgen-typescript'does that by default, which unbound every field with nothing in the output to say whybeginSilentValidationon the command form context, for a custom field to claim a token before it validates so a result a later run has overtaken is discarded rather than applied- Documentation for how .NET types map to TypeScript, and for declaring your own
Changed
DateOnlyandTimeOnlynow generate as theDateOnlyandTimeOnlytypes from@cratis/fundamentalsrather than asDate, which rendered a calendar date a day early west of UTC and a time of day asInvalid Date. Each has a converter of its own, so the value arrives as a type rather than as text every call site has to parse. Requires@cratis/fundamentals7.17.0- A validator message declared as a factory is no longer resolved at generation time and baked into the generated client validator, because a factory can depend on state that does not exist then, making the baked result one arbitrary evaluation; the rule still mirrors, the message is left to the server
autoServerValidateThrottlenow governs the per-keystroke validation request instead of a second, redundant one, so typing no longer issues an unthrottled request per keystrokesetSilentValidationResulton the command form context takes the token frombeginSilentValidationand returns whether the result was applied; called without one it behaves as it didShouldHaveValidationErrorsno longer passes when the only thing that rejected the command was a dependency the pipeline could not resolve, which let a spec report success against a pipeline that never ran@cratis/fundamentalsis declared as an ordinary dependency by both@cratis/arcand@cratis/arc.react, at the same range, so an application resolves a single copy; two copies each carry their ownGuidand converter registry and neither recognizes the other's types. The range is^7.17.0Cratis.Fundamentalsis referenced at 7.17.0, level with the npm packages
Fixed
- A
CommandFormno longer lets a validation result that a later run has overtaken decideisValid— overlapping runs resolving out of order could leave the submit button greyed out for good, with every field valid and no message shown anywhere @cratis/arc.reactdeclares its own dependency on@cratis/fundamentals, which it imports across 20 files but declared nowhere — it resolved only by hoisting through@cratis/arc- Cross-references in XML documentation are rendered into the generated TypeScript instead of erased, along with the prose that fused around them
- Documentation stating that routing-only stream metadata does not affect concurrency control, which it does
- Documentation not saying that the provider resolving a command-side read model also decides which serialization boundary it crosses