Skip to content

field:permission-facet-link 是全仓唯一绕过 withFieldCarrier 的 field 注册 —— SDUI 路径下会拿不到 field #3307

Description

@xuyushun441-sys

在 objectui#3291 的只读审计中顺带发现(origin/main @ 91757a79f)。无 DOM 泄漏,所以不在 #3291 的改动集里;单独记录。

事实

packages/plugin-detail/src/index.tsx:459 把 PermissionFacetLink 裸注册进 field: 命名空间,没有经过 withFieldCarrier 包装 —— 这是全仓唯一一处这样做的 field 注册。

withFieldCarrier(objectui#3233 引入)的职责是把 SDUI 侧传来的 schema 收敛成 widget 契约里唯一的载体 field:

({ schema, field, ...props }) => <FieldWidget {...props} field={field ?? schema} />

而 PermissionFacetLink.tsx:66-68 读的是 props.field。

后果

  • 表单宿主与内联编辑宿主下正常 —— 它们本来就传 field;
  • SchemaRenderer(SDUI)路径下会静默失效 —— 该路径传的是 schema,于是 widget 拿到 field === undefined,field?.name 为空。

这正是 withFieldCarrier 存在的理由所要防的那种静默失败:不报错、不警告,只是渲染出一个内容为空的东西。

修法

一行:注册时套上 withFieldCarrier,与 packages/fields/src/index.tsx:2286 的注册循环一致。

顺带值得考虑的加固:让 field 命名空间的注册无法绕过这道封口(例如只暴露一个已内置包装的 registerField(),而不是让调用方自己决定包不包),否则下一个第三方 widget 作者会以完全相同的方式再踩一次 —— 这是「约定 vs 门禁」的老问题。

参考


Generated by Claude Code

Activity

  1. xuyushun441-sys commented on Aug 4, 2026

    @xuyushun441-sys
    ContributorAuthor

    认领 — session session_01NVPjPzmmAJ2Ngtvgg5MSRa,分支 claude/issue-3307-facet-link-carrier。

    PM 裁决:最小修法——注册处套 withFieldCarrier(对齐 fields/src/index.tsx:2286 的注册循环),加回归测试断言 SDUI 路径(传 schema 不传 field)下 PermissionFacetLink 拿到收敛后的 field。issue 提出的结构性加固(收口 field 命名空间注册、让绕过成为不可能)本单不做——那是公共注册表面的设计变更,另立单裁决;PR 里可留一句指引。


    Generated by Claude Code

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

Metadata

Metadata

Labels

bugSomething isn't workingpm:queue

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions