{"version":3,"file":"runtime-v1.0.0.umd.js","sources":["../src/switcher.ts"],"sourcesContent":["// 加载灰度资源的版本号,通常是当前latest + 1版本号\n// const version = '<%= version %>'; // 占位符,平台控制\nconst version = '1.0.1';\n\n// 灰度放量比例, 随机数上限为10000\n// const sampleRatio = '<%= sampleRatio %>'; // 占位符,平台控制\nconst sampleRatio = '0';\n\n// 不参与灰度的项目ID\n// const whiteProjectIds = `<%= whiteProjectIds %>`.split(',');\nconst whiteProjectIds: string[] = ['518', '515', '80', '519', '517', '454', '501', '522'];\n\n// 参与全量灰度的项目ID\n// const blackProjectIds = `<%= blackProjectIds %>`.split(',');\nconst blackProjectIds: string[] = ['lgw'];\n\nconst projectId = document.currentScript?.getAttribute('project-id');\nconst isLocal = document.currentScript?.getAttribute('src').includes('./dist');\n\n// 默认加载的线上URL\nconst latestUrl = isLocal ?\n './dist/runtime-v1.0.1.umd.js' :\n 'https://lf-security.bytegoofy.com/obj/security-secsdk/runtime-stable.js';\n// 灰度线上版本URL\nconst grayUrl = isLocal ?\n './dist/runtime-v1.0.1.umd.js' :\n `https://lf-security.bytegoofy.com/obj/security-secsdk-gray/runtime-v${version}.js`;\n\nif (projectId) {\n // 灰度判断逻辑\n const isGray = () => {\n // 命中灰度白名单\n if (projectId && whiteProjectIds.includes(projectId)) {\n return false;\n }\n\n // 命中灰度黑名单\n if (projectId && blackProjectIds.includes(projectId)) {\n return true;\n }\n\n const selectors: { path: string; value: string; op: string; tagerProjectIds: string[] }[] = [\n {\n path: 'gfdatav1.envName',\n value: 'prod',\n op: '!==',\n tagerProjectIds: [],\n },\n {\n path: 'SSR_RENDER_DATA.envService',\n value: 'prod',\n op: '!==',\n tagerProjectIds: [],\n },\n ];\n const result: boolean[] = [];\n // 命中环境变量灰度\n for (const selecor of selectors) {\n const { path, value, op } = selecor;\n let cur: any = window;\n for (const key of path.split('.')) {\n if (cur) {\n cur = cur[key];\n }\n }\n // tagerProjectIds灰度项目黑名单\n if (typeof cur === 'undefined') {\n continue;\n }\n const isProjectGray = selecor.tagerProjectIds.length === 0 || selecor.tagerProjectIds.includes(projectId);\n if (op === '===') {\n result.push(isProjectGray && cur === value);\n } else if (op === '!==') {\n result.push(isProjectGray && cur !== value);\n }\n }\n // 命中灰度 或 未命中环境变量,使用随机数生成,判断命中灰度\n return (result.length !== 0 && result.some(v => v)) || Math.floor(Math.random() * 10000) < Number(sampleRatio);\n };\n\n // 切换资源加载URL\n const currentUrl = isGray() ? grayUrl : latestUrl;\n\n localStorage.setItem('web_runtime_switcher_isgray', String(isGray()));\n\n // 实际加载资源\n const nonce = document.currentScript?.nonce || '';\n\n // 缓存版本,区分灰度版本和线上\n const cacheKey = `web_runtime_switcher_${isGray() ? version : 'latest'}`;\n\n const nativeFetch = window.fetch;\n\n const report = (eventName, e?: any) => {\n // 异步上报策略初始化异常\n const NATIVE_NAVIGATOR = window.navigator;\n const NATIVE_SENDBEACON = NATIVE_NAVIGATOR.sendBeacon;\n const IS_SENDBEACON_SUPOORT = NATIVE_SENDBEACON && typeof NATIVE_SENDBEACON === 'function';\n const url = 'https://mon.zijieapi.com/monitor_browser/collect/batch/security/?bid=global';\n const reportString: any = {\n event_name: eventName,\n event_pageUrl: window.location.href,\n event_payload: '{}',\n fromStage: 'init',\n documentURL: window.location.href,\n is_gray: String(isGray()),\n sdkVersion: version,\n };\n if (e) {\n reportString.errorStack_name = e.name;\n reportString.errorStack_message = e.message;\n reportString.errorStack_detail = e.detail;\n }\n const currentData = {\n age: Date.now(),\n url: projectId,\n type: 'runtime_strategy',\n report: {\n reportString,\n reportInt: {\n event_timestamp: Date.now(),\n },\n },\n 'user-agent': window.navigator.userAgent,\n };\n if (IS_SENDBEACON_SUPOORT) {\n const success = NATIVE_SENDBEACON.call(NATIVE_NAVIGATOR, url, JSON.stringify(currentData));\n if (!success) {\n nativeFetch(url, {\n method: 'post',\n body: JSON.stringify(currentData),\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n }\n } else {\n nativeFetch(url, {\n method: 'post',\n body: JSON.stringify(currentData),\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n }\n };\n\n // 异步加载,进行缓存\n fetch(currentUrl)\n .then(res => res.text())\n .then(text => {\n const setItem = (window as any).SDKNativeWebApi?.API_LOCALSTORAGE_SET;\n // 同步执行eval之后,setItem会被代理,这里需要使用代理前的setItem\n if (setItem) {\n setItem.fn.apply(localStorage, [cacheKey, text]);\n } else {\n localStorage.setItem(cacheKey, text);\n }\n });\n\n try {\n // 同步加载灰度\n if (localStorage.getItem(cacheKey)) {\n // 已有缓存,直接同步eval执行\n eval(localStorage.getItem(cacheKey) as string);\n } else {\n // 同步加载,立刻执行\n document.writeln(``);\n }\n // 添加千一采样\n if (Math.floor(Math.random() * 1000) < 1) {\n report('SWITCHER_LOAD_SUCCESS');\n }\n } catch (e) {\n report('SWITCHER_LOAD_ERROR', e);\n }\n}\n"],"names":["version","sampleRatio","whiteProjectIds","blackProjectIds","projectId","document","currentScript","getAttribute","isLocal","includes","latestUrl","grayUrl","isGray_1","result","selectors_1","path","value","op","tagerProjectIds","_i","selecor","cur","window","_b","split","_a","key","isProjectGray","length","push","some","v","Math","floor","random","Number","currentUrl","localStorage","setItem","String","nonce","cacheKey_1","nativeFetch_1","fetch","report","eventName","e","NATIVE_NAVIGATOR","navigator","NATIVE_SENDBEACON","sendBeacon","IS_SENDBEACON_SUPOORT","url","reportString","event_name","event_pageUrl","location","href","event_payload","fromStage","documentURL","is_gray","sdkVersion","errorStack_name","name","errorStack_message","message","errorStack_detail","detail","currentData","age","Date","now","type","reportInt","event_timestamp","userAgent","call","JSON","stringify","method","body","headers","then","res","text","SDKNativeWebApi","API_LOCALSTORAGE_SET","fn","apply","getItem","eval","writeln"],"mappings":"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"}