From 3788d0e02c5eecfb4d64913231b7d3cf6fb89998 Mon Sep 17 00:00:00 2001 From: kdletters Date: Sat, 20 Jun 2026 15:00:03 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=B6=E7=B4=A7=E7=A7=BB=E5=8A=A8=E5=A3=B3?= =?UTF-8?q?=E5=88=86=E4=BA=AB=E7=9B=AE=E6=A0=87=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 移动壳分享目标缓存改为保存规范化后的分享 payload 移动壳分享测试覆盖缓存裁剪外层目标和私有字段 移动壳配置检查锁定分享目标缓存结构 --- apps/mobile-shell/scripts/check-config.mjs | 4 +++ .../src/host-bridge/share.test.ts | 27 +++++++++++++++++++ apps/mobile-shell/src/host-bridge/share.ts | 5 ++-- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/apps/mobile-shell/scripts/check-config.mjs b/apps/mobile-shell/scripts/check-config.mjs index 4bee3a696..d580360d3 100644 --- a/apps/mobile-shell/scripts/check-config.mjs +++ b/apps/mobile-shell/scripts/check-config.mjs @@ -1643,6 +1643,9 @@ for (const snippet of [ 'type HostBridgeRequest', 'const explicitPayload = normalizeHostBridgeShareOpenPayload(request.payload);', 'normalizeHostBridgeShareOpenPayload(currentShareTarget)', + 'type ShareOpenPayload', + 'let currentShareTarget: ShareOpenPayload | null = null;', + 'currentShareTarget = normalizedTarget.payload;', 'setMobileHostBridgeShareTarget', 'request: HostBridgeRequest', "throw invalidRequest('target is required')", @@ -1671,6 +1674,7 @@ if ( for (const snippet of [ 'resetMobileHostBridgeShareTargetForTest()', 'uses cached work target when share.open has no explicit payload', + 'stores only the normalized cached share payload', 'keeps the previous cached target when a new target is missing or invalid', 'maps native share sheet failures to stable host errors', 'does not fall back to cached target when explicit payload is unsafe', diff --git a/apps/mobile-shell/src/host-bridge/share.test.ts b/apps/mobile-shell/src/host-bridge/share.test.ts index 3ee1598f0..33592f544 100644 --- a/apps/mobile-shell/src/host-bridge/share.test.ts +++ b/apps/mobile-shell/src/host-bridge/share.test.ts @@ -95,6 +95,33 @@ describe('mobile share helpers', () => { }); }); + test('stores only the normalized cached share payload', async () => { + setMobileHostBridgeShareTarget( + request('share.setTarget', { + target: { + type: 'genarrative:share-target', + payload: { + title: ' 暖灯猫街 ', + message: ' 来玩这个作品 ', + work: 'PZ-00000001', + privateDraftId: 'draft-1', + }, + }, + }), + ); + + await expect(openShare(request('share.open'))).resolves.toMatchObject({ + ok: true, + result: true, + }); + expect(Share.share).toHaveBeenCalledWith({ + title: '暖灯猫街', + message: + '来玩这个作品\nhttps://app.genarrative.world/works/detail?work=PZ-00000001', + url: 'https://app.genarrative.world/works/detail?work=PZ-00000001', + }); + }); + test('keeps the previous cached target when a new target is missing or invalid', async () => { setMobileHostBridgeShareTarget( request('share.setTarget', { diff --git a/apps/mobile-shell/src/host-bridge/share.ts b/apps/mobile-shell/src/host-bridge/share.ts index f2793b4a1..3a913bd38 100644 --- a/apps/mobile-shell/src/host-bridge/share.ts +++ b/apps/mobile-shell/src/host-bridge/share.ts @@ -4,10 +4,11 @@ import { type HostBridgeError, type HostBridgeRequest, normalizeHostBridgeShareOpenPayload, + type ShareOpenPayload, } from '../../../../packages/shared/src/contracts/hostBridge'; import { invalidRequest, ok } from './protocol'; -let currentShareTarget: unknown = null; +let currentShareTarget: ShareOpenPayload | null = null; export function setMobileHostBridgeShareTarget(request: HostBridgeRequest) { const payload = request.payload; @@ -27,7 +28,7 @@ export function setMobileHostBridgeShareTarget(request: HostBridgeRequest) { ); } - currentShareTarget = target; + currentShareTarget = normalizedTarget.payload; return ok(request, true); }