resolveEntityUri() hardcodes entity:node/, so link props can never target any other entity type

Problem/motivation

A link_default-backed prop (any SDC prop with format: uri or format: uri-reference) autocompletes against node entities only. This is hardcoded in two places:

  • Drupal core's LinkWidget::formElement() sets $element['uri']['#target_type'] = 'node' unconditionally — tracked as core issue #2423093, open since 2013.

  • Canvas's resolveEntityUri() assumes any autocomplete selection is a node and rewrites it to entity:node/${id}:

    // ui/src/utils/transforms.ts
    export const resolveEntityUri = (uri: string): string => {
      const id = parseSingleEntityAutocompleteSelection(uri);
      // LinkWidget with autocomplete support only supports matching on node
      // entities.
      // @todo Add support for other entity types once core does -
      // https://www.drupal.org/i/2423093
      return id !== null ? `entity:node/${id}` : uri;
    };

Canvas's own canvas_page entity type — a first-class content entity with its own canonical route — can never be a link prop's target because of this. It affects any site author trying to link to a Canvas-built page from a component prop.

This is the reverse of an already-fixed bug: #3588884 (closed) (fixed in 1.4.0) was the same node assumption breaking non-link entity autocompletes, such as the Webform block picker. That fix scoped the assumption correctly there; this issue is the matching half for link props.

A related, distinct gap: Linkit's own autocomplete also excludes Canvas pages (linkit#3552659).

Steps to reproduce

  1. On a site with Canvas pages (canvas_page entities) and a custom entity-reference autocomplete wired up for a non-node target type on a uri/uri-reference prop.
  2. Select any non-node entity from that autocomplete inside a component instance form.
  3. Observe the stored value is always rewritten to entity:node/<id>, which is wrong unless the selected entity happens to be a node — for a canvas_page, the id collides with an unrelated node and the link silently targets the wrong page.

Proposed resolution

A uri/uri-reference prop often needs more than one valid target type at once — a Canvas-built page and a legacy node are both valid destinations on the same field, and other content entity types apply as a site's content model grows. Making the hardcoded type configurable to a single alternative (e.g. a hook_canvas_storable_prop_shape_alter() override that swaps in canvas_page) doesn't cover this; it only relocates the assumption, and is rejected for that reason.

Closing the gap requires per-selection type resolution:

  • The autocomplete endpoint must report which entity type it matched for each suggestion, not just return a bare {value, label} pair. resolveEntityUri() can then build entity:<type>/<id> per selection instead of assuming node.
  • LinkWidget's own matching needs to query more than one target type in a single autocomplete request to produce those suggestions in the first place. Core issue #2423093 as filed only covers making the target type configurable to one alternative, not several at once, so it wouldn't close this gap even if it landed.

Remaining tasks

  • Agree on how a suggestion payload carries its entity type (new field vs. an encoded value) without breaking existing {value, label} consumers.
  • Decide whether multi-type matching belongs in core's EntityAutocompleteMatcher/ LinkWidget, or is a Canvas-specific concern layered on top.
  • Prototype resolveEntityUri() building entity:<type>/<id> from a type-aware suggestion.
  • Design how mixed-type suggestion rows are labeled so authors can tell entity types apart (see this module's two-line suggestion rows for one approach).

User interface changes

None today. Once resolved, a link prop's autocomplete could return suggestions spanning multiple entity types in one dropdown instead of node-only. The suggestion list would need a way to show each row's entity type so authors aren't guessing (e.g. a secondary line with content type and path, as implemented in this contrib module).

API changes

  • Core: LinkWidget::formElement()'s $element['uri']['#target_type'] would need to accept more than a single scalar entity type ID, affecting getUriAsDisplayableString() and getUserEnteredStringAsUri(), which currently assume 'node'.
  • Canvas: resolveEntityUri() in ui/src/utils/transforms.ts would need a target entity type per selection instead of a hardcoded 'node'.
  • Any custom autocomplete route backing an entity_autocomplete element would need to add the matched entity type to its JSON response. Additive change — existing {value, label} consumers are unaffected.

Data model changes

None. No new fields, storage, or schema; this is a widget/matching-logic and autocomplete response-shape change only.