Release v20.61.2
Fixed
- A model-bound command's client validation rules were taken from the wrong type. When a command's own validator held no client-projectable rule,
ToCommandDescriptortreated the supplied-but-empty rule set as "not supplied" and re-extracted from theHandlemethod's parameter — which for a model-bound command is the valueProvide()resolves, not the command. A command whoseProvide()returns a record carrying a validated concept (e.g. anEmail) then had that concept's rules emitted on its own generated validator, bound to a field the command does not have — invalid TypeScript. "No rules supplied" (null) is now distinguished from "supplied, empty", so the fallback runs only for the controller path it was written for. - A regex rule was emitted as a quoted string, but the client-side
matchesrule takes aRegExp. The pattern is now carried through as aRegularExpressionPatternand formatted as a regex literal — an empty pattern as/(?:)/, a literal slash escaped — somatches(/^\d{4}$/)is generated rather than an unassignablematches('^\d{4}$').
Both were latent until validator rules first reached generated proxies (#2363); before that, no rule was extracted, so neither path ran. Verified end to end against a real application's regenerated proxies: the leaked command validators are gone and every matches rule is a valid regex literal that typechecks. New specs cover both and were confirmed to have teeth. Full suite green: 3,970 passed, 0 failed.
🤖 Generated with Claude Code