53c6334fd9
leo 07-27:「客戶是用 windows 的」。此前四處寫死「下載 Mac 版」,
Windows 用戶按下去拿到 .app=按了連到錯的東西(leo 判準:那不算友善)。
改法(施工圖 rag-wave1/windows-build-and-os-split.md §3):
- daemonPick() 依 UA 判 OS,四處共用;判不出來=兩個都給,不替用戶猜
- 判對了也附「不是這個系統?」另一版連結(UA 會判錯,用戶要有路走)
- 擋關話術跟著 OS 走:Mac=右鍵打開/Windows=更多資訊→仍要執行
- daemonBase 新 key,保留 daemonDownload 舊 key 相容(由檔名推目錄)
- 一律走 raw:Mac zip 21MB > jsDelivr 20MB 上限(實測回 File size exceeded)
測試 os-split.test.mjs 10/10:
⚠️ 測試抓到真 bug——iPhone 的 UA 含 'Mac OS X' 會被判成 Mac,
讓手機用戶下載裝不起來的桌面 app。已加 isMobile 排除,手機落到「兩個都給」。
未驗:真 Windows 機器的實際下載與安裝行為(需真機)。
50 lines
3.0 KiB
JavaScript
50 lines
3.0 KiB
JavaScript
import fs from 'node:fs';
|
|
const html = fs.readFileSync(new URL('./index.html', import.meta.url).pathname,'utf8');
|
|
// 抽出 daemonPick 相關函式(從 DAEMON_BASE_DEFAULT 到 daemonHint 結尾)
|
|
const start = html.indexOf('var DAEMON_BASE_DEFAULT');
|
|
const endMark = "return '(封測版未簽章,第一次請右鍵→打開)';\n }";
|
|
const end = html.indexOf(endMark) + endMark.length;
|
|
if (start < 0 || end < start) throw new Error('抽不到函式區塊');
|
|
const src = html.slice(start, end);
|
|
|
|
const cases = [
|
|
['Windows', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/120 Safari/537.36'],
|
|
['Mac', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 Safari/605.1.15'],
|
|
['iPhone', 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 Safari/604.1'],
|
|
['Linux', 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 Chrome/120 Safari/537.36'],
|
|
];
|
|
let pass=0, fail=0;
|
|
const chk=(l,c,extra='')=>{ if(c){console.log('PASS:',l);pass++;} else {console.log('FAIL:',l,extra);fail++;} };
|
|
|
|
for (const [name, ua] of cases) {
|
|
const fn = new Function('navigator','window', src + '; return {daemonPick:daemonPick, daemonHint:daemonHint, daemonBase:daemonBase};');
|
|
const api = fn({userAgent: ua}, {});
|
|
const d = api.daemonPick();
|
|
const label = d.sure ? d.pick.label : '(兩個都給)';
|
|
const url = d.sure ? d.pick.url : d.mac.url + ' + ' + d.win.url;
|
|
console.log(`\n[${name}] sure=${d.sure} → ${label}`);
|
|
console.log(` url: ${url}`);
|
|
if (name==='Windows') {
|
|
chk('Windows 給 win zip', d.sure && d.pick.url.endsWith('ArcrunRAG-win-unsigned.zip'), d.pick&&d.pick.url);
|
|
chk('Windows 另一版是 Mac', d.other && d.other.url.endsWith('mac-unsigned.zip'));
|
|
chk('Windows 話術提 藍色視窗', api.daemonHint('win').includes('仍要執行'));
|
|
}
|
|
if (name==='Mac') {
|
|
chk('Mac 給 mac zip', d.sure && d.pick.url.endsWith('ArcrunRAG-mac-unsigned.zip'));
|
|
chk('Mac 另一版是 Windows', d.other && d.other.url.endsWith('win-unsigned.zip'));
|
|
chk('Mac 話術提 右鍵打開', api.daemonHint('mac').includes('右鍵'));
|
|
}
|
|
if (name==='iPhone' || name==='Linux') {
|
|
// iPhone 含 "Mac OS X" 但不是桌機 Mac;Linux 兩者皆非 → 都該落在「不確定=兩個都給」
|
|
if (name==='Linux') chk('Linux 判不出來→兩個都給', d.sure===false);
|
|
if (name==='iPhone') chk('iPhone 不該被判成 Mac(手機→兩個都給)', d.sure===false, 'sure='+d.sure);
|
|
}
|
|
}
|
|
// 舊 key 相容
|
|
const fn2 = new Function('navigator','window', src + '; return daemonBase();');
|
|
console.log('\n[相容] daemonDownload 舊 key →', fn2({userAgent:''},{ARCRUN_CONFIG:{daemonDownload:'https://x.dev/d/ArcrunRAG-mac-unsigned.zip'}}));
|
|
chk('舊 key 推得出目錄', fn2({userAgent:''},{ARCRUN_CONFIG:{daemonDownload:'https://x.dev/d/ArcrunRAG-mac-unsigned.zip'}})==='https://x.dev/d/');
|
|
chk('daemonBase 新 key 優先', fn2({userAgent:''},{ARCRUN_CONFIG:{daemonBase:'https://y.dev/z'}})==='https://y.dev/z/');
|
|
console.log(`\n=== ${pass} passed, ${fail} failed ===`);
|
|
process.exit(fail?1:0);
|