Repository navigation
Expand file tree
/
Copy pathsw.js
More file actions
1 lines (1 loc) · 10.1 KB
/
Copy pathsw.js
File metadata and controls
1 lines (1 loc) · 10.1 KB
1
(()=>{"use strict";function e(e,t){if(!e)throw new Error(`[zovo-tg] ${t}`)}const t="zovo_tg_cache",r=4e6;async function n(e){c("string"==typeof e&&e.length>0,"getCached: asin must be non-empty string");try{const r=await o();if(!r)return null;const n=r[e];return n?Date.now()-n.cachedAt>6048e5?(await async function(e){try{const r=await o();r[e]&&(delete r[e],await chrome.storage.local.set({[t]:r}))}catch(e){s("removeEntry failed",e)}}(e),null):(c("string"==typeof n.grade,"cached entry has grade"),c("number"==typeof n.score,"cached entry has score"),n):null}catch(e){return s("getCached failed",e),null}}async function o(){c(!0,"CACHE_KEY must be string");try{const e=(await chrome.storage.local.get(t))[t];return e&&"object"==typeof e?(c("object"==typeof e,"cache data must be object"),e):{}}catch(e){return s("getAllCached failed",e),{}}}function a(e){let t=0;for(const[r,n]of Object.entries(e))t+=i(r,n);return t}function i(e,t){try{return 2*JSON.stringify({[e]:t}).length}catch{return 2e3}}function c(e,t){if(!e)throw new Error(`[zovo-tg] ${t}`)}function s(e,t){console.error("[zovo-tg]",e,t)}const l="zovo_tg_license_verified_at",u="zovo_tg_license_key",f="zovo_tg_tier",g=/^ZOVO-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}$/;async function d(){y(!0,"KEY_TIER must be string");const e=await h();return y("free"===e||"pro"===e,"getCachedTier: invalid tier"),e}async function h(){try{return"pro"===(await chrome.storage.local.get(f))[f]?"pro":"free"}catch(e){return m("getCachedTierSafe failed",e),"free"}}function y(e,t){if(!e)throw new Error(`[zovo-tg] ${t}`)}function m(e,t){console.error("[zovo-tg]",e,t)}const p="zovo-tg-regrade",_={zovo_tg_config:{enabled:!0,alertsEnabled:!1,alertSensitivity:"full"}},b="zg_onb_d0",E="zg_onb_d3",v="zg_onb_d7",w="zg_onb_d14",O=[b,E,v,w];chrome.runtime.onInstalled.addListener(e=>{try{"install"===e.reason&&(chrome.storage.local.set(_,()=>{chrome.runtime.lastError&&console.error("[zovo-tg]","config seed failed",chrome.runtime.lastError)}),chrome.tabs.create({url:chrome.runtime.getURL("onboarding.html")},()=>{chrome.runtime.lastError&&console.error("[zovo-tg]","onboarding open failed",chrome.runtime.lastError)}),function(){try{chrome.alarms.create(b,{delayInMinutes:.01}),chrome.alarms.create(E,{delayInMinutes:4320}),chrome.alarms.create(v,{delayInMinutes:10080}),chrome.alarms.create(w,{delayInMinutes:20160})}catch(e){console.error("[zovo-tg]","onboarding alarm schedule failed",e)}}()),chrome.alarms.create(p,{periodInMinutes:10080})}catch(e){console.error("[zovo-tg]","onInstalled error",e)}}),chrome.runtime.onMessage.addListener((p,_,b)=>function(t){if(e(void 0!==t,"isTgMessage: value checked"),!t||"object"!=typeof t)return!1;const r=t;if("string"!=typeof r.action)return!1;const n=new Set(["ZOVO_SCAN_COMPLETE","ZOVO_GET_CACHED_GRADE","ZOVO_REGRADE","ZOVO_OPEN_POPUP","ZOVO_GET_TIER","ZOVO_VERIFY_LICENSE","ZOVO_DEEP_ANALYSIS","ZOVO_ENABLE_ALERTS"]);return e(8===n.size,"isTgMessage: 8 valid actions"),n.has(r.action)}(p)?(async function(e){switch(z("object"==typeof e&&null!==e,"handleMessage: msg must be object"),z("string"==typeof e.action,"handleMessage: msg.action must be string"),e.action){case"ZOVO_SCAN_COMPLETE":return async function(e){z("object"==typeof e&&null!==e,"handleScanComplete: result must be object"),z("string"==typeof e.asin,"handleScanComplete: result.asin must be string");try{return await async function(e){c("object"==typeof e&&null!==e,"setCached: entry must be non-null object"),c("string"==typeof e.asin&&e.asin.length>0,"setCached: entry.asin must be non-empty string");try{const n=await o()??{},s={...e,cachedAt:Date.now()};n[e.asin]=s;const l=await async function(e){c("object"==typeof e&&null!==e,"evictIfNeeded: all must be object");let t=a(e);if(t<=r)return e;const n=Object.entries(e).sort((e,t)=>(e[1].cachedAt??0)-(t[1].cachedAt??0)),o=Math.max(1,Math.ceil(.25*n.length)),s={};for(let e=o;e<n.length;e++){const t=n[e];if(!t)continue;const[r,o]=t;r&&o&&(s[r]=o)}return t=a(s),t>r&&n.length>o?function(e,t){const r=Object.entries(e).sort((e,t)=>(t[1].cachedAt??0)-(e[1].cachedAt??0)),n={};let o=0;for(const[e,a]of r){if(!e||!a)continue;const r=i(e,a);if(o+r>t)break;n[e]=a,o+=r}return n}(s,r):s}(n);await chrome.storage.local.set({[t]:l})}catch(e){s("setCached failed",e)}}(e),{ok:!0}}catch(e){return console.error("[zovo-tg]","SCAN_COMPLETE cache write failed",e),{ok:!1}}}(e.result);case"ZOVO_GET_CACHED_GRADE":return async function(e){z("string"==typeof e,"handleGetCachedGrade: asin must be string"),z(e.length>0,"handleGetCachedGrade: asin must be non-empty");try{return{entry:await n(e)}}catch(e){return console.error("[zovo-tg]","GET_CACHED_GRADE failed",e),{entry:null}}}(e.asin);case"ZOVO_REGRADE":return async function(e){return z("string"==typeof e,"handleRegradeRequest: asin must be string"),z(e.length>0,"handleRegradeRequest: asin non-empty"),{ok:!0}}(e.asin);case"ZOVO_GET_TIER":return async function(){z(!0,"handleGetTier entry");try{const e=await d();return z("free"===e||"pro"===e,"invalid tier"),{tier:e}}catch(e){return console.error("[zovo-tg]","GET_TIER failed",e),{tier:"free"}}}();case"ZOVO_VERIFY_LICENSE":return async function(e){z("string"==typeof e,"handleVerifyLicense: key must be string");try{const t=await async function(e){if(y("string"==typeof e,"verifyLicense: key must be string"),!e.startsWith("ZOVO-"))return h();if(!g.test(e))return h();const t=await async function(){try{const e=await chrome.storage.local.get([l,f]),t=e[l],r=e[f];return t&&r?Date.now()-t>18e5?null:"pro"===r?"pro":"free":null}catch(e){return m("getRecentTier failed",e),null}}();if(t)return t;try{const t=new AbortController,r=setTimeout(()=>t.abort(),3e4),n=await fetch("https://zgubxqomnbmxgbdhvwja.supabase.co/functions/v1/verify-extension-license",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({license_key:e,extension:"trustgrade_pro"}),signal:t.signal});if(clearTimeout(r),!n.ok)return h();const o=await n.json(),a=o.valid&&"pro"===o.tier?"pro":"free";return await async function(e,t){y("string"==typeof e,"storeTier: key must be string"),y("free"===t||"pro"===t,"storeTier: invalid tier");try{await chrome.storage.local.set({[l]:Date.now(),[u]:e,[f]:t})}catch(e){m("storeTier failed",e)}}(e,a),y("free"===a||"pro"===a,"tier must be free or pro"),a}catch(e){return m("verifyLicense failed",e),h()}}(e);return z("free"===t||"pro"===t,"invalid tier from verify"),{ok:"pro"===t,tier:t}}catch(e){return console.error("[zovo-tg]","VERIFY_LICENSE failed",e),{ok:!1,tier:"free"}}}(e.key);case"ZOVO_OPEN_POPUP":return async function(){z(!0,"handleOpenPopup entry");try{return chrome.action.openPopup?(await chrome.action.openPopup(),{ok:!0}):{ok:!1}}catch(e){return console.error("[zovo-tg]","OPEN_POPUP failed",e),{ok:!1}}}();case"ZOVO_DEEP_ANALYSIS":return async function(e){z("string"==typeof e,"handleDeepAnalysis: asin must be string"),z(e.length>0,"handleDeepAnalysis: asin non-empty");try{return"pro"!==await d()?{ok:!1,entry:null}:{ok:!0,entry:await n(e)}}catch(e){return console.error("[zovo-tg]","DEEP_ANALYSIS failed",e),{ok:!1,entry:null}}}(e.asin);case"ZOVO_ENABLE_ALERTS":return async function(e){z("boolean"==typeof e,"handleEnableAlerts: enabled must be boolean"),z(!0,"handleEnableAlerts: config exists");try{const t=(await chrome.storage.local.get("zovo_tg_config")).zovo_tg_config??{};return t.alertsEnabled=e,await chrome.storage.local.set({zovo_tg_config:t}),{ok:!0}}catch(e){return console.error("[zovo-tg]","ENABLE_ALERTS failed",e),{ok:!1}}}(e.enabled);default:return{error:`unhandled action: ${e.action}`}}}(p).then(b).catch(e=>{console.error("[zovo-tg]","message handler error",e),b({error:"handler failed"})}),!0):(b({error:"invalid message"}),!1)),chrome.alarms.onAlarm.addListener(e=>{e.name!==p?O.includes(e.name)&&async function(e){z("string"==typeof e,"onb alarm: name is string"),z(e in A,"onb alarm: known alarm name");try{const t=A[e];if(!t)return;if((await new Promise(e=>{chrome.notifications.getAll(t=>{e(t)})}))[t])return;const{title:r,message:n}=await async function(e){if(e===b)return{title:"Welcome to TrustGrade",message:"Visit any Amazon product to see its A–F review trust grade."};if(e===E){const e=await async function(){try{const e=await o();return Object.keys(e).length}catch{return 0}}();return e>0?{title:"Is your favorite brand legit?",message:`TrustGrade has graded ${e} product${e>1?"s":""} for you. Click to see your history.`}:{title:"Is your favorite brand legit?",message:"Try it on any Amazon product page."}}return e===v?{title:"Review rings are getting smarter",message:"We added brand-track-record detection. See how it works."}:{title:"A tip from TrustGrade",message:"Open Settings to tune the confidence threshold and grade-drop alerts to your taste."}}(e);!function(e,t){new Promise((r,n)=>{chrome.notifications.create(e,t,e=>{chrome.runtime.lastError?n(chrome.runtime.lastError):r(e)})})}(t,{type:"basic",iconUrl:chrome.runtime.getURL("icons/icon128.png"),title:r,message:n,priority:1})}catch(e){console.error("[zovo-tg]","onboarding notification failed",e)}}(e.name).catch(e=>{console.error("[zovo-tg]","onboarding alarm failed",e)}):async function(){z(!0,"alarm name set");try{const e=await d();if(z("free"===e||"pro"===e,"valid tier in alarm"),"pro"!==e)return;const t=(await chrome.storage.local.get("zovo_tg_config")).zovo_tg_config;if(!t?.alertsEnabled)return;const r="full"===(t.alertSensitivity??"full")?1:2,n=function(e,t){return z("object"==typeof e&&null!==e,"findGradeDrops: all must be object"),z("number"==typeof t&&t>=1,"findGradeDrops: threshold must be >= 1"),[]}(await o(),r);n.length>0&&await async function(e){if(z(Array.isArray(e),"fireDropNotification: asins must be array"),0!==e.length)try{await chrome.notifications.create({type:"basic",iconUrl:chrome.runtime.getURL("icons/icon128.png"),title:"Zovo TrustGrade — Grade Drop Alert",message:`${e.length} product${e.length>1?"s":""} dropped in review trust grade. Click to view details.`,priority:1})}catch(e){console.error("[zovo-tg]","notification create failed",e)}}(n)}catch(e){console.error("[zovo-tg]","handleRegradeAlarm error",e)}}().catch(e=>{console.error("[zovo-tg]","regrade alarm failed",e)})});const A={[b]:"zg_onb_d0_notif",[E]:"zg_onb_d3_notif",[v]:"zg_onb_d7_notif",[w]:"zg_onb_d14_notif"};function z(e,t){if(!e)throw new Error(`[zovo-tg] ${t}`)}})();