Shape matching MUST work with the resolved equivalents of $refs AND must be compatible with core's upcoming $ref resolving in SDCs
>>> [!note] Migrated issue <!-- Drupal.org comment --> <!-- Migrated from issue #3515074. --> Reported by: [pdureau](https://www.drupal.org/user/1903334) Related to !255 >>> <h3 id="overview">Overview</h3> <p>This issue was forced to deal with 3 distinct problem areas:</p> <ol> <li>"Shape matching MUST work with the resolved equivalents of $refs" as the title literally says. This was reviewed &amp; approved by @phenaproxima in <strong>#27</strong> </li><li>&hellip; but really, while dealing with "resolved $ref equivalents", we really ought to A) refactor away Canvas' own $ref resolving in favor of using that in <code>justinrainbow/json-schema</code>, B) which crucially also aligns us with what core is doing in the SDC subsystem at <span class="drupalorg-gitlab-issue-link project-issue-status-info project-issue-status-8"><a href="https://www.drupal.org/project/drupal/issues/3352063" title="Status: Needs review">#3352063: Allow schema references in Single Directory Component prop schemas</a></span> &mdash; Canvas doing the same here increases our confidence level that future core versions won't break what Canvas is doing. IOW: forward core compatibility. <strong>See #31 + #32.</strong> Wim feels confident about it without the need for further review, esssentially nobody knows this, and it's more a matter of core functionality than Canvas functionality. So: fine with merging without additional review, especially because Wim was working closely with @pdureau on this, and reviewed+updated the core MR while doing this. (The core MR influenced this Canvas MR and vice versa.) </li><li>The theme test SDC with a theme-defined well-known prop shape for @phenaproxima's review revealed a bug in Canvas' <code>meta:enum</code> validation. <strong>This was identified by @penyaskito in #33 and solved by #34.</strong> This is being reviewed by @penyaskito. </li></ol> <hr> <p>In the DrupalCon contribution room, helping with SDC &amp; XB, and I got this question from Mike:</p> <blockquote><p>How can I use the XB <code>image</code> prop "type" (to have a media library widget in XB) without having a hard dependency to XB?</p></blockquote> <p>My initial answer was an explanation of how JSON schema references work.</p> <p><code>{$ref: 'json-schema-definitions://experience_builder.module/image'}</code> must resolve to a references-free schema:</p> <pre>type: object<br>required:<br>- src<br>properties:<br>&nbsp; src:<br>&nbsp;&nbsp;&nbsp; type: string<br>&nbsp;&nbsp;&nbsp; format: uri-reference<br>&nbsp;&nbsp;&nbsp; pattern: "^(/|https?://)?.*\\.(png|gif|jpg|jpeg|webp)(\\?.*)?(#.*)?$"<br>&nbsp; alt:<br>&nbsp;&nbsp;&nbsp; type: string<br>&nbsp; width:<br>&nbsp;&nbsp;&nbsp; type: integer<br>&nbsp; height:<br>&nbsp;&nbsp;&nbsp; type: integer</pre><p>The schema resolver is replacing the reference to the resolved JSON schema snippet.</p> <p>Then, the logic (<em>is it an image?</em>) is applied on the resolved JSON schema.</p> <p>So, if a component author directly writes (without using <code>$ref</code>):</p> <pre>type: object<br>required:<br>- src<br>properties:<br>&nbsp; src:<br>&nbsp;&nbsp;&nbsp; type: string<br>&nbsp;&nbsp;&nbsp; format: uri-reference<br>&nbsp;&nbsp;&nbsp; pattern: "^(/|https?://)?.*\\.(png|gif|jpg|jpeg|webp)(\\?.*)?(#.*)?$"<br>&nbsp; alt:<br>&nbsp;&nbsp;&nbsp; type: string<br>&nbsp; width:<br>&nbsp;&nbsp;&nbsp; type: integer<br>&nbsp; height:<br>&nbsp;&nbsp;&nbsp; type: integer</pre><p>It must also works.</p> <p>Or if a component author just writes a compatible subset:</p> <pre>type: object<br>required:<br>- src<br>properties:<br>&nbsp; src:<br>&nbsp;&nbsp;&nbsp; type: string<br>&nbsp;&nbsp;&nbsp; format: uri-reference<br>&nbsp;&nbsp;&nbsp; pattern: "^(/|https?://)?.*\\.(png|gif|jpg|jpeg|webp)(\\?.*)?(#.*)?$"</pre><p>It must also works.</p> <p>Or if a component author uses another reference resolving the same schema snippet.</p> <p><code>{$ref: 'json-schema-definitions://whatever.module/amstragram'})</code></p> <p>It must also work.</p> <p>However, we have tried on Mike local XB instance, and it was not working:</p> <blockquote><p>Experience Builder does not know of a field type/widget to allow populating the image prop, with the shape..</p></blockquote> <p>Source: <code>/admin/structure/component/status</code></p> <h3 id="proposed-resolution">Proposed resolution</h3> <p>We don't really know what is happening here (maybe it is because of an other problem we got: <code>InvalidComponentException: [props.properties.image.properties.src.pattern] Invalid regex format ^(/|https?://)?.*\.(png|gif|jpg|jpeg|webp)(\?.*)?(#.*)?$ </code>), but it is remembering me an issue from last summer: <span class="drupalorg-gitlab-issue-link project-issue-status-info project-issue-status-7"><a href="https://www.drupal.org/project/experience_builder/issues/3454173" title="Status: Closed (fixed)">#3454173: Media Library integration (includes introducing a new main content renderer/`_wrapper_format`)</a></span> </p> <p>If it not already the case, let's not look at the parts of the URI string ("experience_builder", "image") to guess if it is an image or not. Those URI, <a href="https://www.drupal.org%20https://www.w3.org/DesignIssues/Axioms#opaque">like every URI,</a> are opaque. Let's use JSON schema reference as expected. It is a standard, solid, mechanism.</p> <h3 id="ui-changes">User interface changes</h3> <p>None.</p> > Related issue: [Issue #3352063](https://www.drupal.org/node/3352063) > Related issue: [Issue #3365985](https://www.drupal.org/node/3365985) > Related issue: [Issue #3550169](https://www.drupal.org/node/3550169) > Related issue: [Issue #3560286](https://www.drupal.org/node/3560286) > Related issue: [Issue #3446722](https://www.drupal.org/node/3446722)
issue