工程验证
OpenFairyGUI 的工程验证用于回答:当前工程能否被可靠读取、保持正式 UAM 约束,并在当前宿主已提供的能力范围内确认资源完整性。验证只读,不修改工程,也不等同于发布成功证明。
验证范围
| 层级 | 当前检查 |
|---|---|
| 工程读取 | .fairy、主/分支 package.xml、component XML 与 settings JSON 是否可读和可解析;同时检查 component XML 的布尔、数值、固定长度元组和枚举值,以及 Desktop 按 Int32 读取的几何字段,无法解析或不兼容的内容会成为诊断,不再静默丢失 |
| UAM 完整性 | 正式字段约束、ID/包名唯一性、路径安全、大小写不敏感文件系统上的输出冲突、资源文件夹关系,以及组件、字体、骨骼、列表、gear、transition 等资源引用 |
| 源文件 | 声明源文件是否存在、可读、非空;PNG/JPEG/SVG 的可移植检查与 MovieClip JTA 解析 |
| 宿主解码 | Node 入口使用 Sharp 解码图片;Web 入口复用浏览器 Canvas/ImageBitmap 解码能力 |
验证不执行自动修复、风格 lint、发布设置预检、图集生成、二进制封包或运行时加载。需要确认发布产物时,仍应单独运行目标宿主的 publish 流程。
SVG 源文件校验接受标准的 xmlns="http://www.w3.org/2000/svg" 命名空间声明,同时继续拒绝外部 href、src、非片段 url(...)、脚本 URL、事件属性、DTD/实体和主动内容元素。
报告契约
ProjectValidationReport 包含:
status: 'valid' | 'invalid' | 'incomplete'complete: 当前入口是否完成了它请求的全部检查diagnostics: 按属性路径稳定排序的ProjectDiagnostic[]
invalid 表示发现确定错误;incomplete 表示未发现确定错误,但缺少源字节或宿主解码能力,不能宣称完整通过。诊断提供稳定 code、severity、path、message,并在适用时提供 packageId、resourceId、nodeId 和 sourcePath。
原始 component XML 的 size、xy、restrictSize、边距、clipSoftness、设计图偏移及 gearXY / gearSize 整数部分若不是有符号 32 位整数,会报告 desktop_incompatible_geometry。缩放、旋转、透明度、pivot、skew 和 gear 百分比等浮点字段不受此规则限制;检查只报告问题,不修改源工程。
工程根、assets、分支或资源子目录枚举失败会产生 unreadable_source,详细读取返回 complete: false;只有可选 assets 目录明确不存在时才按空目录处理。返回混合文件/目录条目的适配器可通过 stat 区分目录;未提供 stat 时,资源子目录探测将 ENOTDIR / TypeMismatchError 视为普通文件并跳过,其他读取错误仍会报告,失败条目不会登记为空资源目录。Backend 将不完整文件读取标记为不支持完整写回,避免用部分模型覆盖源工程。
当前纳入严格检查的已建模字段在进入宽松读取器前执行词法检查:布尔值接受 true、false、1、0;浮点值必须是有限十进制数,元组长度必须准确;透明度必须在 0..1;整数必须符合字段的 Int32 约束;枚举必须是当前读取器正式支持的取值。失败时报告 invalid_project_value,避免 parseInt、parseFloat 或默认枚举分支把错误值静默改成看似有效的 UAM。
API
Node 工程目录使用完整入口:
import { validateProjectNode } from '@openfairygui/functions/node';
const report = await validateProjectNode('./MyProject/MyProject.fairy');自定义读写宿主可以保留读取诊断,再与 UAM 检查组合:
import { liftDocumentToUamProject } from '@openfairygui/core';
import { validateProject } from '@openfairygui/functions';
const read = await io.readProjectDetailed('Project.fairy', { hydrateResourceBytes: true });
const report = read.document
? validateProject(liftDocumentToUamProject(read.document), {
readDiagnostics: read.diagnostics,
complete: read.complete,
validateSources: true,
})
: { status: 'invalid', complete: false, diagnostics: read.diagnostics };已水合 UAM 的浏览器图片解码使用 validateProjectWeb(project)。若只需要 UAM 结构和引用检查,使用 validateProject(project)。
CLI、Backend 与 MCP
ofgui validate ./MyProject
ofgui validate ./MyProject --jsonCLI 退出码为:0 有效、1 无效/读取失败、2 参数错误、3 验证不完整。--json 只向标准输出写入一个统一 envelope;完整报告位于 result,无效/不完整同时带 success:false 与 error。见 CLI 机器输出。
Backend 的 validateSession({ sessionId }) 验证当前 revision 的 authoritative UAM,并把同一批诊断镜像到 response meta。MCP 工具 openfairygui_backend_validate_session 只做该方法的薄映射,不建立第二套规则。
镜像到 Backend meta 的首批诊断附加归属、文档 URI 与结构化恢复建议;原始 ProjectValidationReport 的错误分类、完整性和正文保持不变。未知 code 不猜测修复方式,详见诊断与恢复。
ofgui doctor [project] --json 组合安装版本/能力诊断与可选的 Node 工程验证。传入工程时返回磁盘的原始验证报告,不代表当前 session 的未保存状态;无工程时不测试工程源字节,但仍进行内存 PNG/JPEG 编码与像素解码。它不开会话、不取锁、不写探针;退出码 0 为本次检查完成、1 为错误、2 为参数错误、3 为原生图片检查不可用/失败或工程验证不完整,详见安装版本文档与产品诊断。
事务支持检查、执行预演与工程验证
| 入口 | 回答的问题 | 边界 |
|---|---|---|
Core validateTransactionSupport | 当前模型/操作是否落在支持范围,参数与投影约束是否满足 | 不等同于完整执行成功 |
Backend preflightTransaction | 当前 revision 上这批操作经正式事务入口执行是否成功 | 在隔离工程上执行并丢弃;不修改会话,不预留 revision,不检查保存目标或承诺落盘成功 |
Backend validateSession | 当前已提交到会话的工程是否有效,已有读取/源文件检查是否完整 | 不预演待执行操作,不保存或发布 |
安全编辑先通过 queryEntity 获取当前属性和 revision,再预演、正式 apply、验证并保存;正式 apply 和 save 仍各自检查 revision。预演失败沿用 Core/Functions 的事务诊断,不能把支持检查通过或预演成功当作工程验证报告。参数与只读边界见契约指南。