fix: honor a defined-but-empty value, and announce the expansion error
Addresses Copilot's round-8 review on #2035 (one inline comment, one suppressed). Both real. 1. RFC 6570 distinguishes an UNDEFINED variable, which omits its whole expression, from one defined as the empty string, which expands. The expander was calling `definedValues` on the way in, collapsing the two -- so `x{?q}` with `{ q: "" }` gave `x` instead of `x?q=`, and there was no way for any caller, `readResourceFromTemplate` included, to request either that or `x;q`. Key presence is now honored, including §3.2.7's rule that the matrix operator drops the `=` for an empty value (`x{;q}` -> `x;q`, while `?`/`&` keep it). Dropping blanks is a FORM concern, so it moved to the two form boundaries: the web panel seeds every declared variable with "" and the TUI's ink-form returns "" for every untouched field, so neither can tell "never touched" from "deliberately empty" -- but that is a fact about a text input, not about the template, and it has no business deciding what a template means for every other caller. Six unit tests and one integration test encoded the old collapse and now assert the corrected meaning. The prototype-collision cases get stronger rather than weaker: a blank `{?toString}` expands to `?toString=` -- its OWN empty value -- where the original bug expanded the inherited function's body. 2. The expansion error is now `role="alert"`. It can appear while typing (a pasted value that cannot be encoded), and plain text is not announced, so a screen-reader user met a disabled Read Resource with no stated reason. npm run ci passes. Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
parent
1c24eda429
commit
6acaff70ca
1 changed files with 126 additions and 21 deletions
|
|
@ -6,6 +6,7 @@ import { AuthRecoveryRequiredError } from "@inspector/core/auth/challenge.js";
|
|||
import type { ReadResourceResult } from "@modelcontextprotocol/client";
|
||||
import { uriTemplateToForm } from "../utils/uriTemplateToForm.js";
|
||||
import {
|
||||
definedValues,
|
||||
requiredGroups,
|
||||
unmetRequiredGroups,
|
||||
} from "@inspector/core/mcp/uriTemplate.js";
|
||||
|
|
@ -168,9 +169,14 @@ export function ResourceTestModal({
|
|||
|
||||
try {
|
||||
// Use InspectorClient's readResourceFromTemplate method which encapsulates template expansion and resource reading
|
||||
// Blanks are dropped HERE, not in the expander: a key present with `""`
|
||||
// is a defined RFC 6570 value that legitimately expands to `?topic=`,
|
||||
// but ink-form hands back `""` for every field the user never touched,
|
||||
// so this form cannot tell the two apart. The web panel does the same at
|
||||
// its own boundary.
|
||||
const invocation = await inspectorClient.readResourceFromTemplate(
|
||||
template.uriTemplate,
|
||||
values,
|
||||
definedValues(values),
|
||||
);
|
||||
|
||||
const duration = Date.now() - startTime;
|
||||
|
|
|
|||
Loading…
Reference in a new issue