字体 kind 提升为 canonical 并去掉 font 别名

- game_creation_app.rs:`GAME_CREATION_APP_CANONICAL_ASSET_KINDS` 加入 `font`(17 → 18 项),分类表补 `font → document`,删除 `"font" => "document"` 别名。
- gameCreationApp.ts:TS 侧同步加入 `font`、删除别名表条目、补 `font: 'document'` 分类,并同步别名表注释。
- 测试:两侧用例改为断言 `font` 是 canonical 成员(大小写仍不敏感)、栏目仍是 document。
- 理由:字体上传写入侧直接落 `font`,再把它当别名会让「落盘值集合」与「canonical 集合」分叉;严格解析下写入侧的值必须本身就是 canonical。
This commit is contained in:
2026-09-17 13:42:05 +08:00
parent 3ab56e6cfa
commit 29ba9a358e
4 changed files with 12 additions and 13 deletions
@@ -251,7 +251,7 @@ describe('真机出现的 kind 归类口径', () => {
canonical: GAME_CREATION_APP_UI_DESIGN_DOC_ASSET_KIND,
category: 'ui-interaction',
},
{ kind: 'font', canonical: 'document', category: 'document' },
{ kind: 'font', canonical: 'font', category: 'document' },
// `Object.prototype` 上的键不是别名:TS 侧必须用 `Object.hasOwn` 挡住对象字面量的
// 原型命中,Rust 侧 match 字面量本来就落 `image`;这类极端输入两侧也必须一致。
{ kind: 'constructor', canonical: 'image', category: 'unclassified' },
@@ -756,9 +756,11 @@ describe('AI 游戏创作 App 共享契约', () => {
// 别名表大小写不敏感:UI 设计资产的现役写入侧写的是大写 `"UI"`。
expect(canonicalGameCreationAppAssetKind('UI')).toBe('ui-design');
expect(canonicalGameCreationAppAssetKind('UI-Prototype')).toBe('ui-design');
// 字体资产的现役写入侧写的是 `font`。
expect(canonicalGameCreationAppAssetKind('font')).toBe('document');
expect(canonicalGameCreationAppAssetKind('FONT')).toBe('document');
// 字体是 canonical 成员(现役写入侧就直接写 `font`),不再走 `font → document` 别名,
// 否则「落盘值集合」与「canonical 集合」会分叉。大小写仍不敏感。
expect(canonicalGameCreationAppAssetKind('font')).toBe('font');
expect(canonicalGameCreationAppAssetKind('FONT')).toBe('font');
expect(gameCreationAppAssetCategoryForKind('font')).toBe('document');
/**
* `Object.prototype` 上的键不是别名:别名表是对象字面量,直接下标取值会拿到原型上的
* 函数/对象(truthy)并被当成 canonical kind 返回;Rust 侧是 `match` 字面量,只会落
@@ -505,6 +505,7 @@ export const GAME_CREATION_APP_CANONICAL_ASSET_KINDS = [
'sound-effect',
'background-music',
'audio',
'font',
'document',
'code',
] as const;
@@ -520,9 +521,6 @@ export type GameCreationAppCanonicalAssetKind =
* 否则会落到 `canonicalGameCreationAppAssetKind` 的 `image` 兜底,再经
* `image → unclassified` 被误分到「待归类」。
*
* `font` 同样属于现役写入侧:字体上传(`ttf / otf / woff / woff2`)登记的 manifest
* 资产 `kind` 就是 `font`,不在此收口就只能落「待归类」。
*
* 本表与 Rust 侧 `server-rs/crates/shared-contracts/src/game_creation_app.rs` 的
* `canonical_game_creation_app_asset_kind` 必须成对维护,由
* `tests/assetKindCanonicalMapping.test.ts` 交叉钉住。
@@ -546,7 +544,6 @@ const GAME_CREATION_APP_LEGACY_ASSET_KINDS: Record<
'game-style': 'code',
animation: 'character-animation',
asset: 'image',
font: 'document',
};
export function canonicalGameCreationAppAssetKind(
@@ -606,6 +603,7 @@ export const GAME_CREATION_APP_ASSET_CATEGORY_BY_KIND: Record<
'sound-effect': 'audio',
'background-music': 'audio',
audio: 'audio',
font: 'document',
document: 'document',
code: 'unclassified',
};
@@ -570,7 +570,7 @@ impl<'de> Deserialize<'de> for GameCreationAppAssetManifestEntry {
}
}
pub const GAME_CREATION_APP_CANONICAL_ASSET_KINDS: [&str; 17] = [
pub const GAME_CREATION_APP_CANONICAL_ASSET_KINDS: [&str; 18] = [
"image",
"scene",
"character",
@@ -586,6 +586,7 @@ pub const GAME_CREATION_APP_CANONICAL_ASSET_KINDS: [&str; 17] = [
"sound-effect",
"background-music",
"audio",
"font",
"document",
"code",
];
@@ -608,9 +609,6 @@ pub fn canonical_game_creation_app_asset_kind(value: &str) -> &'static str {
"game-entry" | "game-script" | "game-style" => "code",
"animation" => "character-animation",
"asset" => "image",
// 字体上传(`ttf / otf / woff / woff2`)登记的 manifest 资产 kind 就是 `font`
// 不收口同样只能落「待归类」。
"font" => "document",
canonical => match GAME_CREATION_APP_CANONICAL_ASSET_KINDS
.iter()
.find(|candidate| **candidate == canonical)
@@ -642,7 +640,7 @@ pub const GAME_CREATION_APP_ASSET_CATEGORIES: [GameCreationAppAssetCategory; 6]
];
/// canonical kind 到功能分类的默认映射,必须穷举 `GAME_CREATION_APP_CANONICAL_ASSET_KINDS`。
pub const GAME_CREATION_APP_ASSET_CATEGORY_BY_KIND: [(&str, GameCreationAppAssetCategory); 17] = [
pub const GAME_CREATION_APP_ASSET_CATEGORY_BY_KIND: [(&str, GameCreationAppAssetCategory); 18] = [
("image", GameCreationAppAssetCategory::Unclassified),
("scene", GameCreationAppAssetCategory::Scene),
("character", GameCreationAppAssetCategory::Character),
@@ -670,6 +668,7 @@ pub const GAME_CREATION_APP_ASSET_CATEGORY_BY_KIND: [(&str, GameCreationAppAsset
("sound-effect", GameCreationAppAssetCategory::Audio),
("background-music", GameCreationAppAssetCategory::Audio),
("audio", GameCreationAppAssetCategory::Audio),
("font", GameCreationAppAssetCategory::Document),
("document", GameCreationAppAssetCategory::Document),
("code", GameCreationAppAssetCategory::Unclassified),
];