Skip to content

Release v21.0.0

Choose a tag to compare

@github-actions github-actions released this 05 Aug 17:32
a16f30a

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

  • TypeToTsType build 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 one
  • ValidationResultReason on ValidationResult, so a rejection can be told apart from another without matching message text, which is presentation and changes without notice
  • ShouldHaveValidationErrorBecauseOf, for asserting why a command was rejected — asserting only that it failed passes just as readily when it failed for the wrong reason
  • ICommandResultAssertionPolicy, a seam for applying a repository's own policy on top of the built-in CommandResult assertions, so a shared convention lives in one place instead of every spec
  • ARC0015, 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 validated
  • markAsCommandFormField and markAsCommandFormColumn, so a command form field survives a build transform that rewrites displayName — Storybook's reactDocgen: 'react-docgen-typescript' does that by default, which unbound every field with nothing in the output to say why
  • beginSilentValidation on 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

  • DateOnly and TimeOnly now generate as the DateOnly and TimeOnly types from @cratis/fundamentals rather than as Date, which rendered a calendar date a day early west of UTC and a time of day as Invalid 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/fundamentals 7.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
  • autoServerValidateThrottle now governs the per-keystroke validation request instead of a second, redundant one, so typing no longer issues an unthrottled request per keystroke
  • setSilentValidationResult on the command form context takes the token from beginSilentValidation and returns whether the result was applied; called without one it behaves as it did
  • ShouldHaveValidationErrors no 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/fundamentals is declared as an ordinary dependency by both @cratis/arc and @cratis/arc.react, at the same range, so an application resolves a single copy; two copies each carry their own Guid and converter registry and neither recognizes the other's types. The range is ^7.17.0
  • Cratis.Fundamentals is referenced at 7.17.0, level with the npm packages

Fixed

  • A CommandForm no longer lets a validation result that a later run has overtaken decide isValid — 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.react declares 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