Repository navigation
Feat/zodsharp 3 blazor - #9
Merged
Merged
Conversation
…rerelease.1 and SGF 1.2.2 Purview.ZodSharp 3 ships net10.0 and net11.0, which is already this repository's 'Supported' set, so no target framework changes. Purview.ValueObjects 1.3.0-prerelease.1 is the version built against ZodSharp 3, with trim- and AOT-safe generated JSON converters. SourceGeneratorFramework 1.2.2 stops its framework assembly leaking into the output of projects that reference the generator as an analyzer; there was no workaround for it here to remove. ZodSharp 3's generated schemas gain ValidateAsync, so CA1849 flags the synchronous Validate in async tests. The failure-mapper tests, which only need a ValidationResult, now await ValidateAsync. The integration tests exist to fold the synchronous schema through the synchronous ToResult bridge and compare it with the asynchronous path, so they keep Validate and suppress CA1849 for that class with the reason.
…blemDetailsOptions setting ZodValidationProblems.ToProblem converted the errors through ZodException.ToHttpValidationProblemDetails(registry, status), which in Purview.ZodSharp 3 builds a writer from the registry alone: message formatting off and every new option - path naming, issues, parameter merging, the error type resolver, the default status and the status override - ignored. ZodSharp's exception handler writes through ZodProblemDetailsWriter with the configured options, so a result-carried failure and the same thrown ZodException no longer produced the same response, which this package guarantees. ToProblem now writes through ZodProblemDetailsWriter with the host's options, overriding only the default status a ZodResultsHttpOptions rule supplies, on a copy so the shared options are never mutated. StatusCodeSelector is no longer applied here first: the writer applies ZodSharp 3's precedence (default, then the highest ErrorType.HttpStatus, then the selector, then the override), exactly as for a thrown exception. A test pins that the copy carries every settable option, so a future option cannot be dropped silently. Behaviour changes, matching a thrown ZodException: an ErrorType's MessageFormat now formats the message, and a StatusCodeSelector now wins over an ErrorType status.
BuildSdk 1.2.0 rewrote the managed .editorconfig with its new version marker; the rule set is unchanged. Its new Blazor WebAssembly, Razor class library, BFF and Blazor host detection, PurviewBrowserSafe with the PRBLZ0001 reference check, PDS0007 (the CA1034 suppression on extension blocks) to PDS0009 and the unmarked .editorconfig warning apply to no project in this solution - the generator's extension blocks are emitted into consumers, and nothing here suppressed CA1034 - and the build produced no new warning. Skills.Testing 1.2.0 passes every skill unchanged.
Every project built its net11.0 target with Features=runtime-async=on. A library compiled with the
experiment carries runtime-async methods that only a runtime implementing it can execute, and the
Mono runtime behind Blazor WebAssembly does not: ToResultAsync, ToUnitResultAsync and every async
combinator of the net11.0 packages threw PlatformNotSupportedException ("Runtime Async is not
supported on this platform") in the browser. The new packed-consumer gate found it.
The setting moves to Directory.Build.targets, where IsPackable is known, and applies to net11.0
projects that do not ship. Tests and examples keep the experiment; the libraries they reference
are compiled with the stable lowering, so the tests exercise exactly what ships.
…patibility suppressions Purview.ZodSharp 2's generator emitted ZodSharp.ZodSchemaAttribute and ZodSharp.Core.ErrorTypeAttribute, marked [Embedded], into every assembly it generated for, so Purview.Results.ZodSharp and Purview.Results.ZodSharp.AspNetCore 1.0.x carry hidden copies. Purview.ZodSharp 3 defines both once, in Purview.ZodSharp, and package validation against the 1.0.0.1 baseline reports CP0001 for their removal on both target frameworks. No compiled consumer can bind to an [Embedded] type, so the removal breaks nothing; the generated CompatibilitySuppressions.xml files record it, and the changelog's upgrade note is the matching evidence.
`dotnet pack /p:GenerateCompatibilitySuppressionFile=true` writes two-space indentation; the repository's CSharpier lint indents XML with tabs.
…sembly and Blazor Server Every in-repo build references the libraries and the generator as projects, which exercises nothing of what ships. Modelled on purview-dev/zodsharp's gate, `just smoke-packed-consumers` packs every Purview.Results package to an isolated feed and NUGET_PACKAGES, guards Directory.Build.* and Directory.Packages.props in a temp root, and builds consumers outside the repository from the packages alone, with Purview.ZodSharp 3 and Purview.ValueObjects: - a Native AOT console over a [GenerateResult] union, the generated AsFailure helpers and union-receiver factory, the ZodSharp bridge (sync and async) and a value object's type-level rule, published with -warnaserror and run - a Blazor WebAssembly app whose <ZodValidator> form input then flows through the result pipeline, published trimmed and with RunAOTCompilation=true, served and run in a headless browser driven over the DevTools protocol - a Blazor Server app over every package: a minimal API whose result maps onto a validation problem, a code rule's 422, a case mapping's 409 and a 200; a statically rendered form; and an interactive page running the same checks over a live circuit - a net10.0 console, so the packages' other target framework keeps restoring and running Every bin and publish folder is scanned for compiler-host assemblies, including the Results generator and code fix, by scripts/assert-no-compiler-host-assemblies.ps1. Dependency gaps are reported as known issues (-StrictKnownIssues fails on them). PackValidation's ForbiddenContent grows from one rule to 25, mirroring ZodSharp's, and `just verify-pack-rules` (scripts/test-pack-validation-rules.ps1) proves each rejects a package. The consumers' union-declaring files join .csharpierignore.
… requests Purview.ZodSharp 3.0.0-prerelease.1 and its Blazor package are built against the rc.3 ASP.NET Core packages, and the WebAssembly consumers need the matching rc.3 WebAssembly SDK, so global.json and both workflows move from rc.2 to rc.3 together. The new packed-consumers job runs scripts/test-packed-consumers.ps1 on ubuntu-latest with -WasmAot Require and -Browser Require (the image ships Chrome) and the .NET 10 runtime for the net10.0 consumer, then proves every pack-validation ForbiddenContent rule. Purview.ZodSharp 3.0.0-prerelease.1, Purview.ValueObjects 1.3.0-prerelease.1 and Purview.SourceGeneratorFramework 1.2.2 are not on nuget.org yet, so until they are - or the RESULTS_DEPENDENCY_FEED repository variable names a feed that has them - the job fails at its first step, the dependency preflight, with what to do, instead of skipping.
…problem precedence A new wiki page, Blazor-and-Native-AOT, covers which packages are trim- and AOT-safe (the result type and the ZodSharp bridge) and which are server-only (the ASP.NET Core mapping), the target frameworks, a Blazor form whose input flows through a result, and the WebAssembly AOT gap for a value object's type-level rule. The ZodSharp Problem Details page, the package README and the problems skill describe the new behaviour, in which every ZodProblemDetailsOptions setting applies, with Purview.ZodSharp 3's status precedence. The page also explains that .NET 11 request validation (AddZodSharpValidation, also turned on by AddZodSharpBlazor) answers a [ZodSchema] parameter before a result-returning handler runs, and that such an endpoint calls DisableValidation(). The README's ProblemDetails sample shows the ZodSharp 3 shape; README, Getting Started and the validation skill name the ZodSharp 3 requirement and ValidateAsync with ToResultAsync; AGENTS.md names the packed-consumer gate.
A minor prerelease. No package loses a target framework (all four still ship net10.0 and net11.0) and no public member changed; package validation's only findings are the hidden [Embedded] ZodSharp attribute copies, which no compiled consumer can bind to. The ZodSharp integration packages now require Purview.ZodSharp 3, and result-carried validation problems follow its options and status precedence; the changelog's upgrade notes cover both.
…tion Purview.ZodSharp 3.0.0-prerelease.1's AddZodSharpBlazor() no longer turns on minimal-API parameter validation, so the Blazor Server consumer's /api/tenants endpoint drops DisableValidation(). The gate's existing check now proves the intended behaviour with nothing opted out: the refinement's code rule answers 422 with tenant_id_matches_name, because the handler runs and returns its result. The /api/tenants/prevalidated endpoint existed only to show the old behaviour and is identical to /api/tenants now, so it is gone with its known-issue probe. The known-issue reporting and -StrictKnownIssues are removed, so every check fails the gate.
The Blazor and Native AOT and ZodSharp Problem Details pages said AddZodSharpBlazor() turns on .NET 11 request validation, so endpoints had to call DisableValidation(), and that a type-level [ZodRule] crashed the Mono AOT compiler. Both are fixed in Purview.ZodSharp. The pages now say AddZodSharpBlazor() validates form models only, explain that only AddZodSharpValidation() validates endpoint parameters (and how to register it for type validation only), and state that a value object with a type-level rule composes with results in a WebAssembly AOT client.
The skills this repository depends on are installed by the skills CLI into the universal
.agents/skills/ location and committed with skills-lock.json, so a clone has them without
running anything. Nothing was written outside .agents/ and skills-lock.json:
npx -y skills@1 add purview-dev/engineering-playbook -s '*' -a universal -y
npx -y skills@1 add purview-dev/build-sdk -s '*' -a universal -y
npx -y skills@1 add purview-dev/sourcegenerator-framework -s '*' -a universal -y
npx -y skills@1 add purview-dev/zodsharp -s '*' -a universal -y
npx -y skills@1 add purview-dev/value-objects -s '*' -a universal -y
.agents/ was effectively gitignored by a .agents/.gitignore that an older Purview.BuildSdk wrote
for its package mirror, with that mirror's stale, untracked copies beside it. Both were removed
from the working tree before installing; none of it was tracked.
/.claude/ is gitignored, and src/Directory.Build.props sets PurviewSkillsAgents to universal, so
the SDK's InstallPurviewSkills target no longer defaults to writing a copy for every agent.
…ention InstalledSkillTests mirrors ZodSharp's five checks: every skills-lock.json entry is installed under .agents/skills/, every installed folder is recorded in the lockfile, no skill authored in skills/ is copied into .agents/skills/, no .claude/skills/ copy exists, and there is no CLAUDE.md at the root or in .github/.
…ntion AGENTS.md gains an "Installed skills (.agents/skills/)" section: the installed set and its sources, the -a universal install and restore commands, why nothing goes into .claude/ and no CLAUDE.md is added, and the test that guards it. The authored-skills section no longer says .agents/skills/ is gitignored, and the layout table lists both skill folders. The Copilot instructions point at the installed skills rather than at package-delivered content.
…roring The root README, the package READMEs, Contributing and Agent Skills still said each package ships its skills under .agents/ and that Purview.BuildSdk mirrors them into a consumer's .agents/ on restore. That route was removed in Purview.BuildSdk 1.0.6. They now name the skill and the one delivery route, npx skills add purview-dev/results, and Agent Skills describes the upstream skills committed under .agents/skills/.
The pack-validation step fails twice over on a fresh runner: - dotnet tool restore exits 1 with "The command "purview-build" specified in the tool manifest file is not contained in the package with Package Id purview.build. The commands contained in the package are dotnet-inspect." although Purview.Build declares purview-build. The .NET 11 rc.3 CLI attributes the command of the RID-specific dotnet-inspect tool to the manifest entry beside it; the failed attempt has installed every tool by then, so the next attempt succeeds. - Every run validates by expecting purview-build to fail, so $LASTEXITCODE is 1 at the end of the script and GitHub's pwsh shell appends `exit $LASTEXITCODE`, failing the step after it printed "Every ForbiddenContent rule (25) rejected its file". scripts/restore-dotnet-tools.ps1 retries a bounded number of times, quiet on success, printing every attempt when all fail. It is now the only place local tools are restored: `just` (ensure-pipeline-tool), the CI pack-validation step, and the scratch repository test-pack-validation-rules.ps1 builds for each of its 30 runs. The script also exits 0 once every rule has passed. Reproduced with the runner's wrapper locally: cold cache, attempt 1 fails, attempt 2 restores, 30 validation runs pass, step exit 0.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.