Skip to content

Implement key validation in router and enhance schema serializa… - #438

Open
freekh wants to merge 6 commits into
mainfrom
add-key-validation-router
Open

Implement key validation in router and enhance schema serializa…#438
freekh wants to merge 6 commits into
mainfrom
add-key-validation-router

Conversation

@freekh

@freekh freekh commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

…tion

@changeset-bot

changeset-bot Bot commented Jun 2, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 04dcac9

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 7 packages
Name Type
@valbuild/core Patch
@valbuild/ui Patch
@valbuild/shared Patch
@valbuild/server Patch
@valbuild/next Patch
@valbuild/react Patch
@valbuild/cli Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@freekh freekh changed the title feat: implement key validation in router and enhance schema serializa… Implement key validation in router and enhance schema serializa… Jun 2, 2026
@freekh

freekh commented Jun 2, 2026

Copy link
Copy Markdown
Contributor Author

We need some UI updates to make sure description looks good for routes

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends the core schema router helper to support explicit key schemas (mirroring s.record(key, value)), enabling constraints like .maxLength(), .regexp(), .validate(), and .describe() to apply to router keys, and updates validation behavior so router pattern errors and key-schema errors can surface together.

Changes:

  • Added overloads to s.router(...) to accept an optional key schema argument and pass it through to RecordSchema.
  • Updated RecordSchema.executeValidate to merge router validation errors instead of returning early, allowing additional validation errors to be reported.
  • Added comprehensive tests for key-schema serialization, key validation, combined error reporting, and serialize/deserialize round-tripping; updated Next example renders to include list selection fields.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
packages/core/src/schema/router.ts Adds s.router(router, keySchema, itemSchema) overload and implementation to forward key schema into RecordSchema.
packages/core/src/schema/router.test.ts Adds coverage for key schema serialization, key validation behaviors, combined error surfacing, and serialize/deserialize round-trip.
packages/core/src/schema/record.ts Changes router-validation handling to merge errors into existing ValidationErrors rather than returning early.
examples/next/content/authors.val.ts Updates list render selection to include image.
examples/next/app/blogs/[blog]/page.val.ts Adds .render({ as: "list", select: ... }) to the router-backed schema in the example.
.changeset/router-key-validation.md Documents the new s.router key validation support in a patch changeset.

Comment thread packages/core/src/schema/record.ts Outdated
freekh and others added 4 commits July 30, 2026 09:28
Sub-errors were merged with object spread, which replaces the array of a
colliding SourcePath rather than concatenating it. A record validates the
key and the item on the same path, so a key with a router error, a key
schema error and an item error only reported one of them.

Adds a mergeValidationErrors helper next to appendValidationError on
Schema and uses it for every merge in record, array and object.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The add and rename popovers only showed the key description when a caller
passed it explicitly, so the sitemap's add-route button - which knows the
path but not the schema - showed none. Both popovers already resolve the
record schema, so fall back to its key description and keep the prop as an
override.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Uses the new three-argument s.router form in examples/next so the key
description is visible in the editor, and notes the UI change and the
validation error merge in the changeset.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@freekh

freekh commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

Merged main in (was 79 commits behind, no conflicts) and addressed both open comments.

Copilot review comment (resolved): validation errors are now merged path-wise via a new mergeValidationErrors helper on Schema, so a route key can report its router error, key schema error and item error together instead of only one set. Applied to record, and the same spreads in array and object for consistency. Covered by a new test that fails on the old spread merge.

"We need some UI updates to make sure description looks good for routes": main already renders the key description in the module header, the add popover and the rename popover, but only when the caller passes it explicitly — so the sitemap's add-route button showed nothing, which is exactly the routes case. AddRecordPopover and ChangeRecordPopover now fall back to schema.key?.description themselves (prop still wins), so the sitemap gets it for free. examples/next uses the new three-arg form with s.string().describe("The URL of the blog post") so it is visible in the editor.

I deliberately left the RouteSelector dropdown in RouteField alone: it lists routes owned by another module, where the key description is not the field's own. Happy to add it if you disagree. I also did not add a description line above the routes list itself — without a label it reads as if it described the record rather than its keys.

Checks run from the repo root: lint, format, typecheck (all packages), test (1030 tests), build, and examples/next build. All green. I have not visually confirmed the popover copy in a browser.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants