接入 AGC shell TS 资源 kind 边界

新增消费 Rust 生成绑定的未知值解析模块
迁移资源引用与画布引用入口并补充日志测试
更新逐项迁移清单与实施计划
This commit is contained in:
2026-09-15 18:00:34 +08:00
parent 20b0bf4dd7
commit 2befaaef9d
6 changed files with 93 additions and 4 deletions
@@ -0,0 +1,45 @@
import type { GameCreationAppAssetKind } from './generated/GameCreationAppAssetKind';
export type { GameCreationAppAssetKind } from './generated/GameCreationAppAssetKind';
export const GAME_CREATION_APP_ASSET_KINDS = [
'image',
'scene',
'character',
'character-animation',
'icon',
'icon-spritesheet',
'icon-spec',
'ui-design',
'ui-design-doc',
'publication-material',
'spec',
'video',
'audio',
'sound-effect',
'background-music',
'font',
'document',
'code',
'unknown',
] as const satisfies readonly GameCreationAppAssetKind[];
const KNOWN_ASSET_KINDS = new Set<string>(GAME_CREATION_APP_ASSET_KINDS);
export function parseGameCreationAppAssetKind(
raw: unknown,
context: string,
): GameCreationAppAssetKind {
if (typeof raw === 'string' && KNOWN_ASSET_KINDS.has(raw)) {
return raw as GameCreationAppAssetKind;
}
const rawValue = typeof raw === 'string' ? raw : String(raw);
if (rawValue !== 'unknown') {
console.warn('未知的 GameCreationApp 资源 kind,已收口为 unknown', {
rawKind: rawValue,
sourceContext: context,
});
}
return 'unknown';
}
@@ -10,6 +10,10 @@ import {
buildGameCreationAppAssetTagLibrary,
type GameCreationAppAssetTagLibraryEntry,
} from '../../../../../packages/shared/src/contracts/gameCreationAppAssetTagLibrary';
import {
type GameCreationAppAssetKind,
parseGameCreationAppAssetKind,
} from '../../contracts/assetKind';
export type ResourceReferenceSource =
| 'asset-picker'
@@ -20,7 +24,7 @@ export type ResourceReferenceSource =
export type ResourceReference = {
type: 'resource';
resourceId: string;
kind: string;
kind: GameCreationAppAssetKind;
mediaType: string;
label: string;
category: GameCreationAppAssetCategory;
@@ -98,7 +102,7 @@ export function resourceReferenceFromAsset(
return {
type: 'resource',
resourceId: asset.id,
kind: asset.kind,
kind: parseGameCreationAppAssetKind(asset.kind, 'resource-reference'),
mediaType: asset.mediaType,
label: resourceDisplayName(asset),
category: gameCreationAppAssetCategory(asset),
@@ -96,6 +96,7 @@ import {
isFloatingOverlayWheelEvent,
useImageCanvasFloatingOptionDismiss,
} from '../../../../../src/components/image-editor/useImageCanvasFloatingOptionDismiss';
import { parseGameCreationAppAssetKind } from '../../contracts/assetKind';
import { DesignWorkspacePanel } from '../../features/project-workspace/DesignWorkspacePanel';
import {
LocalGamePreviewFrame,
@@ -7226,9 +7227,11 @@ export default function ProjectDevelopmentView({
type: 'resource',
resourceId:
selectedResource.manifestAssetId!,
kind:
kind: parseGameCreationAppAssetKind(
selectedResource.subtype ||
selectedResource.category,
selectedResource.category,
'project-development.resource-reference',
),
mediaType: selectedResource.mediaType,
label: selectedResource.label,
category:
@@ -0,0 +1,28 @@
import { describe, expect, it, vi } from 'vitest';
import {
GAME_CREATION_APP_ASSET_KINDS,
parseGameCreationAppAssetKind,
} from '../src/contracts/assetKind';
describe('shell generated asset kind boundary', () => {
it('keeps the generated kind values aligned with the manifest vocabulary', () => {
expect(GAME_CREATION_APP_ASSET_KINDS).toContain('font');
expect(GAME_CREATION_APP_ASSET_KINDS).toContain('audio');
expect(GAME_CREATION_APP_ASSET_KINDS).toContain('sound-effect');
expect(GAME_CREATION_APP_ASSET_KINDS).toContain('background-music');
expect(GAME_CREATION_APP_ASSET_KINDS).toContain('unknown');
});
it('does not alias old values and records unknown input', () => {
const warn = vi.spyOn(console, 'warn').mockImplementation(() => undefined);
expect(parseGameCreationAppAssetKind('ui', 'manifest.asset.kind')).toBe(
'unknown',
);
expect(warn).toHaveBeenCalledWith(
'未知的 GameCreationApp 资源 kind,已收口为 unknown',
{ rawKind: 'ui', sourceContext: 'manifest.asset.kind' },
);
warn.mockRestore();
});
});