Skip to content

Release v22.10.0

Choose a tag to compare

@github-actions github-actions released this 02 Sep 19:43
60b2ac1

Added

  • --emit-interfaces renders types as plain TypeScript interfaces rather than classes carrying @field decorators, with no @cratis/fundamentals import for the decorators. A model that is only ever built and read needs neither, and a package that deliberately carries no dependencies cannot take one on. Documentation, base types and nullability are unchanged, so the output differs from the class form only in the ways the mode is for. (#2635)

Fixed

  • A read-only dictionary is now recognized as a dictionary. IsDictionary only looked for IDictionary<,>, and IReadOnlyDictionary<,> is its sibling rather than its derivative — so a model exposing its dictionaries read-only, the natural shape for an immutable record, was not seen as holding dictionaries at all. IReadOnlyDictionary<string, IReadOnlyList<T>> now generates as Record<string, T[]> instead of a KeyValuePair[] referencing a type that was never imported. (#2634)
  • Library mode no longer aborts on a model with two read-only dictionaries. Those unrecognized dictionaries put two closed instantiations of KeyValuePair<,> in one output file, and the duplicate-path guard stopped the entire run. With them recognized, CollectTypesInvolved takes only the value type as it always did for the mutable shape, and no KeyValuePair is emitted. (#2634)
  • Library mode no longer aborts on an open generic either. It collected open definitions such as CompilationResult<T>, and walking one reached its own type parameter — which has no full name, so it produced a nameless descriptor landing on the definition's own path. An open definition has no concrete shape to emit and a generic parameter is not a type, so both are skipped. (#2634)

Verified against two independent model assemblies. The second one is why the third fix exists: after the dictionary fix I claimed the collision could no longer arise, which was true only of dictionaries — checking Cratis.Screenplay surfaced a second, unrelated cause.

assembly before after
Cratis.Scene.Model aborts on the KeyValuePair collision 75 files, no exclusions needed
Cratis.Screenplay aborts on the CompilationResult<T> collision 216 files, 193 types

With --emit-interfaces, Scene emits zero @cratis/fundamentals imports. Screenplay emits one — TimeOnly, a value type Fundamentals provides rather than a decorator, which no emission mode can or should remove.

The Interface template already existed but was unused and incomplete — it gained documentation, extends and optional properties here rather than being written from scratch.

Four generated files under TestApps also change, and not because of anything in this PR: their committed output predates the XML-doc unescaping fix, so &#x60; becomes a backtick when they are regenerated. Left in rather than reverted, so main stops carrying stale generated output.

Verified: 51 projects build in Release with 0 errors and 0 warnings, and 1225 ProxyGenerator specs pass — including 17 new ones covering all three changes.

🤖 Generated with Claude Code