@@ -63,6 +63,11 @@ export function currentOtaId(): string | null {
6363}
6464
6565export type AppUpdate = { version : string ; url : string } | null ;
66+ const APP_VERSION_RE = / ^ \d + $ / ;
67+
68+ function isHttpUrl ( value : string ) : boolean {
69+ return / ^ h t t p s ? : \/ \/ / i. test ( value ) ;
70+ }
6671
6772/**
6873 * 检查是否有更新的「原生版本」(新安装包)。比 OTA 优先:原生改动 OTA 推不动,
@@ -71,17 +76,21 @@ export type AppUpdate = { version: string; url: string } | null;
7176 *
7277 * 用 path 而非 query:`<updatesServer>/app-version/<platform>.json` —— 这样可以直接
7378 * 作为静态文件托管在 OSS/CDN 上(每个平台一个 JSON,内容为 { version, url })。
79+ * 生产 updatesServer 指向发布静态目录,如 https://release.monkeycode-ai.com/public/mobile。
7480 */
7581export async function checkAppUpdate ( ) : Promise < AppUpdate > {
7682 const base = ( Constants . expoConfig ?. extra as { updatesServer ?: string } | undefined ) ?. updatesServer ?. replace ( / \/ $ / , '' ) ;
7783 const installed = installedAppVersion ( ) ;
7884 if ( ! base || ! installed ) return null ;
7985 try {
80- const res = await fetch ( `${ base } /app-version/${ Platform . OS } .json` ) ;
86+ const res = await fetch ( `${ base } /app-version/${ Platform . OS } .json?_= ${ Date . now ( ) } ` , { cache : 'no-store' } ) ;
8187 if ( ! res . ok ) return null ;
82- const j = ( await res . json ( ) ) as { version ?: string ; url ?: string } ;
83- if ( j ?. version && String ( j . version ) > installed ) {
84- return { version : String ( j . version ) , url : String ( j . url || '' ) } ;
88+ const j = ( await res . json ( ) ) as { version ?: unknown ; url ?: unknown } ;
89+ const version = typeof j ?. version === 'string' ? j . version . trim ( ) : '' ;
90+ const url = typeof j ?. url === 'string' ? j . url . trim ( ) : '' ;
91+ if ( ! APP_VERSION_RE . test ( version ) || ! isHttpUrl ( url ) ) return null ;
92+ if ( version > installed ) {
93+ return { version, url } ;
8594 }
8695 return null ;
8796 } catch {
0 commit comments