@cxxgo/fund-valuation-query 1.0.5 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/fund.js +14 -14
  2. package/package.json +1 -1
package/dist/fund.js CHANGED
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
- import{Command as tt}from"commander";import{readFileSync as at}from"fs";import y from"axios";import*as G from"cheerio";function Z(e){let t=G.load(e),n=[];return t("table").first().find("tbody tr, tr").each((o,r)=>{let s=t(r).find("td");if(s.length<7)return;let d=s.eq(1).find("a"),i=d.text().trim();if(!i)return;let u=(d.attr("href")||"").match(/\/r\/(\d+)\.(\w+)/),f=u?parseInt(u[1]):i.startsWith("6")?1:0,g=f>=100,p=s.eq(2).find("a").text().trim()||s.eq(2).text().trim(),l=s.eq(6).text().trim().replace("%",""),m=parseFloat(l);isNaN(m)||n.push({stockCode:i,stockName:p,holdingRatio:m,market:f,isOverseas:g})}),n}var I={"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",Referer:"https://fund.eastmoney.com/"},N=1e3,ke=60*N,B=60*ke,R=24*B,T=new Map;async function v(e,t,n,{force:a=!1}={}){let o=Date.now(),r=T.get(e);if(!a&&r?.value!==void 0&&r.expiresAt>o)return r.value;if(r?.promise)return r.promise;let s=(async()=>{try{let d=await n();return T.set(e,{value:d,expiresAt:o+t,promise:null}),d}catch(d){if(r?.value!==void 0&&!a)return T.set(e,r),r.value;throw T.delete(e),d}})();return T.set(e,{value:r?.value,expiresAt:r?.expiresAt||0,promise:s}),s}async function P(e){return v(`fund-holdings:${e}`,R,async()=>{let t=`https://fundf10.eastmoney.com/FundArchivesDatas.aspx?type=jjcc&code=${e}&topline=50`,{data:n}=await y.get(t,{responseType:"text",headers:I,timeout:8e3}),a=n.match(/content:"([\s\S]*?)",arryear:/);return a?Z(a[1]):[]})}async function j(e,{force:t=!1}={}){try{return await v(`fund-estimate:${e}`,30*N,async()=>{let n=`http://fundgz.1234567.com.cn/js/${e}.js`,{data:a}=await y.get(n,{responseType:"text",timeout:5e3}),o=a.match(/jsonpgz\((.+)\)/);if(!o)return null;let r=JSON.parse(o[1]);return r.gszzl==null||!r.gztime?null:{change:parseFloat(r.gszzl),time:r.gztime,navDate:F(r.jzrq)}},{force:t})}catch{return null}}function ee(e){let t=new Intl.DateTimeFormat("en-CA",{timeZone:"Asia/Shanghai",year:"numeric",month:"2-digit",day:"2-digit"}).formatToParts(new Date(e)),n=a=>t.find(o=>o.type===a)?.value||"";return`${n("year")}-${n("month")}-${n("day")}`}function X(e,t="Asia/Shanghai"){let n=new Intl.DateTimeFormat("en-CA",{timeZone:t,year:"numeric",month:"2-digit",day:"2-digit"}).formatToParts(e),a=o=>n.find(r=>r.type===o)?.value||"";return`${a("year")}-${a("month")}-${a("day")}`}async function De(e){return v(`stock-history:nasdaq:${e}`,12*B,async()=>{let t=new Date,n=new Date(t.getTime()-30*R),a=`https://api.nasdaq.com/api/quote/${encodeURIComponent(e)}/historical?assetclass=stocks&fromdate=${X(n)}&limit=12&todate=${X(t)}`,o=null;for(let i=0;i<3;i+=1)try{({data:o}=await y.get(a,{timeout:8e3,headers:{"User-Agent":I["User-Agent"],Accept:"application/json, text/plain, */*",Origin:"https://www.nasdaq.com",Referer:"https://www.nasdaq.com/"}}));break}catch(c){if(c?.response?.status!==429||i===2)throw c;await te(500*(i+1))}let r=o?.data?.tradesTable?.rows;if(!Array.isArray(r)||r.length<2)return{latestDate:null,changesByDate:new Map};let s=r.map(i=>({date:Ce(i?.date),close:Te(i?.close)})).filter(i=>i.date&&Number.isFinite(i.close)).reverse();if(s.length<2)return{latestDate:null,changesByDate:new Map};let d=new Map;for(let i=1;i<s.length;i+=1){let c=s[i-1].close,u=s[i];c!==0&&d.set(u.date,(u.close-c)/c*100)}return{latestDate:s[s.length-1]?.date||null,changesByDate:d}})}function Ce(e){if(!e)return null;let[t,n,a]=String(e).split("/");return!a||!t||!n?null:`${a}-${t.padStart(2,"0")}-${n.padStart(2,"0")}`}function Te(e){return e==null?Number.NaN:Number.parseFloat(String(e).replace(/[$,]/g,""))}function te(e){return new Promise(t=>setTimeout(t,e))}async function L(e){try{return await v(`fund-networth:${e}`,R,async()=>{let t=`https://fund.eastmoney.com/pingzhongdata/${e}.js?v=${Date.now()}`,{data:n}=await y.get(t,{responseType:"text",timeout:8e3,headers:I}),a=n.match(/var Data_netWorthTrend = (\[[\s\S]*?\]);\/\*/);if(!a)return null;let o=JSON.parse(a[1]),r=o[o.length-1];return!r||typeof r.x!="number"||typeof r.equityReturn!="number"?null:{date:ee(r.x),change:r.equityReturn}})}catch{return null}}function Ne({code:e,market:t}){return/^(8|9)\d{5}$/.test(e)?`bj${e}`:t===1?`sh${e}`:t===0?`sz${e}`:t===116?`r_hk${e}`:t>=100?`us${e}`:null}function Se({code:e,market:t}){return/^(8|9)\d{5}$/.test(e)?`bj${e}`:t===1?`sh${e}`:t===0?`sz${e}`:t===116?`hk${e}`:t>=100?`us${e}`:null}function F(e){if(!e)return null;if(/^\d{14}$/.test(e))return`${e.slice(0,4)}-${e.slice(4,6)}-${e.slice(6,8)}`;let t=e.replace(/\//g,"-");return/^\d{4}-\d{2}-\d{2}/.test(t)?t.slice(0,10):null}async function O(){try{return await v("china-market-date",30*N,async()=>{let{data:e}=await y.get("https://qt.gtimg.cn/q=sh000001",{responseType:"arraybuffer",timeout:5e3}),n=new TextDecoder("gbk").decode(e).match(/^v_[^=]+="(.+)";?$/m);if(!n)return null;let a=n[1].split("~");return F(a[30])})}catch{return null}}var Me=[{code:"sh000001",name:"\u4E0A\u8BC1\u6307\u6570"},{code:"sz399001",name:"\u6DF1\u8BC1\u6210\u6307"},{code:"sz399006",name:"\u521B\u4E1A\u677F\u6307"},{code:"bj899050",name:"\u5317\u8BC150"},{code:"sh000688",name:"\u79D1\u521B50"},{code:"sh000016",name:"\u4E0A\u8BC150"},{code:"sz399330",name:"\u6DF1\u8BC1100"},{code:"sh000300",name:"\u6CAA\u6DF1300"},{code:"sh000905",name:"\u4E2D\u8BC1500"},{code:"sh000852",name:"\u4E2D\u8BC11000"},{code:"sh000012",name:"\u56FD\u503A\u6307\u6570"},{code:"sh000013",name:"\u4F01\u503A\u6307\u6570"}];function Le(){return Me.map(e=>({...e}))}function Fe(e){let t=e.match(/^v_[^=]+="(.+)";?$/m);return t?t[1].split("~"):null}function ae(){let e=new Intl.DateTimeFormat("en-GB",{timeZone:"Asia/Shanghai",hour:"2-digit",minute:"2-digit",hour12:!1}).formatToParts(new Date),t=n=>e.find(a=>a.type===n)?.value||"";return`${t("hour")}:${t("minute")}`}function Oe(e){let t=ee(Date.now());if(!e||e!==t)return"closed";let n=ae(),a=Number.parseInt(n.slice(0,2),10)*60+Number.parseInt(n.slice(3,5),10),o=a>=570&&a<=690,r=a>=780&&a<=900;return a>690&&a<780?"midday_break":o||r?"trading":"closed"}async function ne({force:e=!1}={}){let t=Le();try{return await v("market-overview",30*N,async()=>{let n=`https://qt.gtimg.cn/q=${t.map(c=>c.code).join(",")}`,{data:a}=await y.get(n,{responseType:"arraybuffer",timeout:5e3}),o=new TextDecoder("gbk").decode(a),r=new Map;for(let c of o.trim().split(`
3
- `)){let u=c.match(/^v_([^=]+)=/);if(!u)continue;let f=Fe(c);!f||f.length<33||r.set(u[1],f)}let s=r.get(t[0].code),d=F(s?.[30])||null,i=Oe(d);return{status:i,dateLabel:d?d.slice(5):"",timeLabel:i==="trading"?ae():"",items:t.map(c=>{let u=r.get(c.code),f=Number.parseFloat(u?.[3]),g=Number.parseFloat(u?.[4]),p=Number.parseFloat(u?.[32]);return{code:c.code,name:c.name,value:Number.isFinite(f)?f:null,change:Number.isFinite(f)&&Number.isFinite(g)?f-g:null,changePercent:Number.isFinite(p)?p:null}})}},{force:e})}catch{return{status:"closed",dateLabel:"",timeLabel:"",items:t.map(n=>({...n,value:null,change:null,changePercent:null}))}}}async function z(e){let t=new Map;if(e.length===0)return t;await Promise.all(e.map(async({code:a,market:o})=>{if(o>=100)return;let r=Se({code:a,market:o});if(!r){t.set(a,{latestDate:null,changesByDate:new Map});return}try{let s=await v(`stock-history:${r}`,12*B,async()=>{let d=`https://web.ifzq.gtimg.cn/appstock/app/fqkline/get?param=${r},day,,,30,qfq`,{data:i}=await y.get(d,{timeout:5e3,headers:{Referer:"https://gu.qq.com/"}}),c=i?.data?.[r],u=c?.qfqday||c?.day;if(!Array.isArray(u)||u.length===0)return{latestDate:null,changesByDate:new Map};let f=new Map;for(let g=1;g<u.length;g+=1){let p=u[g-1],l=u[g],m=l?.[0],x=parseFloat(p?.[2]),k=parseFloat(l?.[2]);if(!m||Number.isNaN(x)||Number.isNaN(k)||x===0)continue;let D=(k-x)/x*100;f.set(m,D)}return{latestDate:u[u.length-1]?.[0]||null,changesByDate:f}});t.set(a,s)}catch{t.set(a,{latestDate:null,changesByDate:new Map})}}));let n=0;for(let{code:a,market:o}of e)if(!(o<100)){try{n>0&&await te(250);let r=await De(a);t.set(a,r)}catch{t.set(a,{latestDate:null,changesByDate:new Map})}n+=1}return t}async function re(e,{force:t=!1}={}){let n=new Map;if(e.length===0)return n;let a=e.map(({code:r,market:s})=>({code:r,symbol:Ne({code:r,market:s})})).filter(r=>r.symbol);if(a.length===0)return n;let o=new Map(a.map(r=>[r.symbol,r.code]));try{let r=a.map(d=>d.symbol).sort().join(","),s=await v(`stock-quotes:${r}`,20*N,async()=>{let d=`https://qt.gtimg.cn/q=${a.map(g=>g.symbol).join(",")}`,{data:i}=await y.get(d,{responseType:"arraybuffer",timeout:5e3}),c=new TextDecoder("gbk").decode(i),u=new Map,f=c.trim().split(`
4
- `);for(let g of f){let p=g.match(/^v_([^=]+)="(.+)";?$/);if(!p)continue;let l=p[1],m=p[2].split("~");m.length<33||u.set(l,{name:m[1],changePercent:parseFloat(m[32]),quoteDate:F(m[30])})}return u},{force:t});for(let[d,i]of o.entries())s.has(d)&&n.set(i,s.get(d))}catch{}return n}import{readFileSync as H,writeFileSync as $e,existsSync as q}from"fs";import{homedir as Ee}from"os";import{join as Ie,resolve as Be}from"path";var A=Ie(Ee(),".fundrc.json");function K(){return q(A)&&JSON.parse(H(A,"utf-8")).configPath||null}function oe(e){let t=Be(e);q(t)||(console.error(`\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728: ${t}`),process.exit(1));try{let n=JSON.parse(H(t,"utf-8"));(!n||typeof n!="object"||Object.keys(n).length===0)&&(console.error("\u914D\u7F6E\u6587\u4EF6\u4E3A\u7A7A\u6216\u683C\u5F0F\u9519\u8BEF"),process.exit(1))}catch{console.error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF0C\u9700\u8981\u5408\u6CD5\u7684 JSON"),process.exit(1)}$e(A,JSON.stringify({configPath:t},null,2)),console.log(`\u5DF2\u8BBE\u7F6E\u914D\u7F6E\u6587\u4EF6: ${t}`)}function U(){let e=K();return e||(console.error("\u672A\u8BBE\u7F6E\u914D\u7F6E\u6587\u4EF6\uFF0C\u8BF7\u8FD0\u884C: fund config <\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84>"),process.exit(1)),q(e)||(console.error(`\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728: ${e}\uFF0C\u8BF7\u91CD\u65B0\u8BBE\u7F6E: fund config <\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84>`),process.exit(1)),JSON.parse(H(e,"utf-8"))}function ie(e,t){return t.some(a=>a.isOverseas)||/全球|QDII|美元|港|海外|纳斯达克|标普|道琼斯/.test(e)?"\u5168\u7403":/ETF|指数/.test(e)?"\u6307\u6570":/债/.test(e)?"\u504F\u503A":"\u504F\u80A1"}var S="Asia/Shanghai";function Re(e=S,t=new Date){return new Date(t.toLocaleString("en-US",{timeZone:e}))}function Pe(e){return[e.getFullYear(),String(e.getMonth()+1).padStart(2,"0"),String(e.getDate()).padStart(2,"0")].join("-")}function je(){return Pe(Re())}function h(e,t=new Date){let n=new Intl.DateTimeFormat("en-CA",{timeZone:e,year:"numeric",month:"2-digit",day:"2-digit",weekday:"short",hour:"2-digit",minute:"2-digit",hour12:!1}).formatToParts(t),a=o=>n.find(r=>r.type===o)?.value||"";return{date:`${a("year")}-${a("month")}-${a("day")}`,weekday:a("weekday"),minutes:Number.parseInt(a("hour"),10)*60+Number.parseInt(a("minute"),10)}}function _(e){return["Mon","Tue","Wed","Thu","Fri"].includes(e)}function ze(e=new Date){let t=h(S,e);return _(t.weekday)?t.minutes>900||t.minutes<570:!0}function Ae(e=new Date){let t=h("Asia/Hong_Kong",e);return _(t.weekday)?t.minutes>960||t.minutes<570:!0}function He(e=new Date){let t=h("America/New_York",e);return _(t.weekday)?t.minutes>960||t.minutes<570:!0}function qe(e,t,n=new Date){return!t?.quoteDate||!w(t.changePercent)?!1:e.market===116?t.quoteDate===h("Asia/Hong_Kong",n).date:e.market>=100?t.quoteDate===h("America/New_York",n).date:t.quoteDate===h(S,n).date}function Ke(e,t){return!!(e&&t&&e===t)}function Ue(e,t=new Date){return e.market===116?h("Asia/Hong_Kong",t).date:e.market>=100?h("America/New_York",t).date:h(S,t).date}function _e(e,t=new Date){return e.market===116?Ae(t):e.market>=100?He(t):ze(t)}function Je(e,t,n=new Date){let a=t.get(e.stockCode);if(!a)return null;let o=[...a.changesByDate.keys()].sort();if(o.length===0)return null;let r=Ue(e,n);if(_e(e,n))return o[o.length-1]||null;let d=o.filter(i=>i<r);return d[d.length-1]||null}function se(e,t,n=new Date){if(!e?.time||!w(e.change))return!1;let a=e.time.slice(0,10);if(t==="\u5168\u7403"){let r=h("America/New_York",n),s=h("Asia/Hong_Kong",n);return a===r.date||a===s.date}let o=h(S,n).date;return a===o}function $(e){return!e||e.length<10?"":e.slice(5)}function w(e){return typeof e=="number"&&!Number.isNaN(e)}function J(e){return e.map(t=>({code:t.stockCode,market:t.market}))}function W(e,t,n,a=null){let o=je(),r=new Date,s=0,d=e.map(l=>{let m=t.get(l.stockCode),x=n.get(l.stockCode),k=Je(l,n,r),D=qe(l,m,r)&&(l.isOverseas||Ke(o,a))?m.changePercent:null,we=k,E=k&&x?x.changesByDate.get(k)??null:null,xe=w(D)?l.holdingRatio*D/100:0;return w(D)&&(s+=l.holdingRatio),{stockCode:l.stockCode,stockName:l.stockName,holdingRatio:l.holdingRatio,todayChange:D,previousTradingDayChange:E,previousTradingDayDate:we,contribution:w(E)?l.holdingRatio*E/100:0,weightedTodayContribution:xe,isOverseas:l.isOverseas}}),c=d.length>0&&d.every(l=>w(l.previousTradingDayChange))?d.reduce((l,m)=>l+m.contribution,0):null,u=s>0?s/100:0,f=u>=.6?d.reduce((l,m)=>l+m.weightedTodayContribution,0):null,g=d.map(l=>l.previousTradingDayDate).filter(Boolean).sort(),p=g.length>0?g[g.length-1]:null;return{previousTradingDayChange:c,weightedTodayChange:f,coverageRatio:u,contributions:d,todayDate:o,previousTradingDate:p}}async function Q(e){let t=new Map;return await Promise.all(Object.keys(e).map(async n=>{try{t.set(n,await P(n))}catch{t.set(n,[])}})),t}function We(e){let t=new Map;for(let[,n]of e)for(let a of n)t.has(a.stockCode)||t.set(a.stockCode,{code:a.stockCode,market:a.market});return[...t.values()]}async function Y(e,t){return re(We(e),t)}function de(e,t,n,a,o){let r=ie(t,n);return{code:e,name:t,todayChange:se(a,r)?a.change:null,previousTradingDayChange:o?.change??null,previousTradingDayLabel:$(o?.date??null),category:r,canDetail:!0}}async function ce(e,t,n,a,o=null){let[r,s,d]=await Promise.all([z(J(n)),j(e),L(e)]),i=W(n,a,r,o);return{...de(e,t,n,s,d),contributions:i.contributions,weightedTodayChange:i.weightedTodayChange,coverageRatio:i.coverageRatio,todayLabel:$(i.todayDate)}}async function V(e,{forceRefresh:t=!1}={}){let n=await Q(e);return(await Promise.all(Object.entries(e).map(async([o,r])=>{let s=n.get(o)||[],[d,i]=await Promise.all([j(o,{force:t}),L(o)]);return{code:o,name:r,holdings:s,estimate:d,latestNetWorth:i}}))).map(({code:o,name:r,holdings:s,estimate:d,latestNetWorth:i})=>de(o,r,s,d,i))}async function le(e){let[t,n]=await Promise.all([V(e,{forceRefresh:!0}),ne({force:!0})]);return{funds:t,marketOverview:n}}async function ue(e,t,{forceRefreshPrices:n=!1}={}){let a=await P(e),o=new Map([[e,a]]),[r,s,d,i]=await Promise.all([Y(o,{force:n}),O(),z(J(a)),L(e)]),c=W(a,r,d,s);return{code:e,name:t,previousTradingDayChange:i?.change??null,previousTradingDayLabel:$(i?.date??null),weightedTodayChange:w(c.weightedTodayChange)?c.weightedTodayChange:null,coverageRatio:c.coverageRatio,contributions:c.contributions}}import M from"chalk";import fe from"cli-table3";function C(e){if(e==null||Number.isNaN(e))return"-";let t=parseFloat(e);return t>0?M.red(`+${t.toFixed(2)}%`):t<0?M.green(`${t.toFixed(2)}%`):`${t.toFixed(2)}%`}function ge(e,t,n){return!t||t===n?C(e):`${C(e)}
5
- ${M.gray(t)}`}function Qe(e,t){return t?`${e} (${t})`:e}function me(e,t){let n="";for(let a of e){let o=t(a);o&&o>n&&(n=o)}return n}function pe(e,t){return t?`${e}
6
- ${t}`:e}function he(e){let{code:t,name:n,todayChange:a,previousTradingDayChange:o,contributions:r}=e,s=me(r,i=>i.previousTradingDayDate?.slice(5)||""),d=new fe({head:["\u6301\u4ED3","\u5360\u6BD4",pe("\u6536\u76D8\u6DA8\u8DCC",s),"\u6DA8\u8DCC"],style:{head:["cyan"]}});for(let i of r)d.push([`${i.stockCode} ${i.stockName}`,`${i.holdingRatio.toFixed(2)}%`,ge(i.previousTradingDayChange,i.previousTradingDayDate?.slice(5),s),C(i.todayChange)]);console.log(`
7
- ${M.bold(t)} ${M.bold(n)}`),console.log(d.toString()),console.log(`${Qe("\u51C0\u503C",e.previousTradingDayLabel)}: ${C(o)}`),console.log(`\u6DA8\u8DCC: ${C(a)}
8
- `)}function be(e){let t=me(e,a=>a.previousTradingDayLabel||""),n=new fe({head:["\u57FA\u91D1\u4EE3\u7801","\u57FA\u91D1\u540D\u79F0",pe("\u51C0\u503C",t),"\u4F30\u503C"],style:{head:["cyan"]}});for(let a of e)n.push([a.code,a.name,ge(a.previousTradingDayChange,a.previousTradingDayLabel,t),C(a.todayChange)]);console.log(n.toString())}import ye from"express";async function Ye(e){return le(e)}async function Ve(e,t,n=!1){return ue(e,t,{forceRefreshPrices:n})}function Ge(){return`
2
+ import{Command as ot}from"commander";import{readFileSync as it}from"fs";import y from"axios";import*as G from"cheerio";function Z(e){let t=G.load(e),a=[];return t("table").first().find("tbody tr, tr").each((o,r)=>{let i=t(r).find("td");if(i.length<7)return;let d=i.eq(1).find("a"),s=d.text().trim();if(!s)return;let u=(d.attr("href")||"").match(/\/r\/(\d+)\.(\w+)/),f=u?parseInt(u[1]):s.startsWith("6")?1:0,g=f>=100,p=i.eq(2).find("a").text().trim()||i.eq(2).text().trim(),l=i.eq(6).text().trim().replace("%",""),m=parseFloat(l);isNaN(m)||a.push({stockCode:s,stockName:p,holdingRatio:m,market:f,isOverseas:g})}),a}var I={"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",Referer:"https://fund.eastmoney.com/"},N=1e3,ke=60*N,R=60*ke,B=24*R,T=new Map;async function v(e,t,a,{force:n=!1}={}){let o=Date.now(),r=T.get(e);if(!n&&r?.value!==void 0&&r.expiresAt>o)return r.value;if(r?.promise)return r.promise;let i=(async()=>{try{let d=await a();return T.set(e,{value:d,expiresAt:o+t,promise:null}),d}catch(d){if(r?.value!==void 0&&!n)return T.set(e,r),r.value;throw T.delete(e),d}})();return T.set(e,{value:r?.value,expiresAt:r?.expiresAt||0,promise:i}),i}async function P(e){return v(`fund-holdings:${e}`,B,async()=>{let t=`https://fundf10.eastmoney.com/FundArchivesDatas.aspx?type=jjcc&code=${e}&topline=50`,{data:a}=await y.get(t,{responseType:"text",headers:I,timeout:8e3}),n=a.match(/content:"([\s\S]*?)",arryear:/);return n?Z(n[1]):[]})}async function j(e,{force:t=!1}={}){try{return await v(`fund-estimate:${e}`,30*N,async()=>{let a=`http://fundgz.1234567.com.cn/js/${e}.js`,{data:n}=await y.get(a,{responseType:"text",timeout:5e3}),o=n.match(/jsonpgz\((.+)\)/);if(!o)return null;let r=JSON.parse(o[1]);return r.gszzl==null||!r.gztime?null:{change:parseFloat(r.gszzl),time:r.gztime,navDate:F(r.jzrq)}},{force:t})}catch{return null}}function ee(e){let t=new Intl.DateTimeFormat("en-CA",{timeZone:"Asia/Shanghai",year:"numeric",month:"2-digit",day:"2-digit"}).formatToParts(new Date(e)),a=n=>t.find(o=>o.type===n)?.value||"";return`${a("year")}-${a("month")}-${a("day")}`}function X(e,t="Asia/Shanghai"){let a=new Intl.DateTimeFormat("en-CA",{timeZone:t,year:"numeric",month:"2-digit",day:"2-digit"}).formatToParts(e),n=o=>a.find(r=>r.type===o)?.value||"";return`${n("year")}-${n("month")}-${n("day")}`}async function De(e){return v(`stock-history:nasdaq:${e}`,12*R,async()=>{let t=new Date,a=new Date(t.getTime()-30*B),n=`https://api.nasdaq.com/api/quote/${encodeURIComponent(e)}/historical?assetclass=stocks&fromdate=${X(a)}&limit=12&todate=${X(t)}`,o=null;for(let s=0;s<3;s+=1)try{({data:o}=await y.get(n,{timeout:8e3,headers:{"User-Agent":I["User-Agent"],Accept:"application/json, text/plain, */*",Origin:"https://www.nasdaq.com",Referer:"https://www.nasdaq.com/"}}));break}catch(c){if(c?.response?.status!==429||s===2)throw c;await te(500*(s+1))}let r=o?.data?.tradesTable?.rows;if(!Array.isArray(r)||r.length<2)return{latestDate:null,changesByDate:new Map};let i=r.map(s=>({date:Ce(s?.date),close:Te(s?.close)})).filter(s=>s.date&&Number.isFinite(s.close)).reverse();if(i.length<2)return{latestDate:null,changesByDate:new Map};let d=new Map;for(let s=1;s<i.length;s+=1){let c=i[s-1].close,u=i[s];c!==0&&d.set(u.date,(u.close-c)/c*100)}return{latestDate:i[i.length-1]?.date||null,changesByDate:d}})}function Ce(e){if(!e)return null;let[t,a,n]=String(e).split("/");return!n||!t||!a?null:`${n}-${t.padStart(2,"0")}-${a.padStart(2,"0")}`}function Te(e){return e==null?Number.NaN:Number.parseFloat(String(e).replace(/[$,]/g,""))}function te(e){return new Promise(t=>setTimeout(t,e))}async function L(e){try{return await v(`fund-networth:${e}`,B,async()=>{let t=`https://fund.eastmoney.com/pingzhongdata/${e}.js?v=${Date.now()}`,{data:a}=await y.get(t,{responseType:"text",timeout:8e3,headers:I}),n=a.match(/var Data_netWorthTrend = (\[[\s\S]*?\]);\/\*/);if(!n)return null;let o=JSON.parse(n[1]),r=o[o.length-1];return!r||typeof r.x!="number"||typeof r.equityReturn!="number"?null:{date:ee(r.x),change:r.equityReturn}})}catch{return null}}function Ne({code:e,market:t}){return/^(8|9)\d{5}$/.test(e)?`bj${e}`:t===1?`sh${e}`:t===0?`sz${e}`:t===116?`r_hk${e}`:t>=100?`us${e}`:null}function Se({code:e,market:t}){return/^(8|9)\d{5}$/.test(e)?`bj${e}`:t===1?`sh${e}`:t===0?`sz${e}`:t===116?`hk${e}`:t>=100?`us${e}`:null}function F(e){if(!e)return null;if(/^\d{14}$/.test(e))return`${e.slice(0,4)}-${e.slice(4,6)}-${e.slice(6,8)}`;let t=e.replace(/\//g,"-");return/^\d{4}-\d{2}-\d{2}/.test(t)?t.slice(0,10):null}async function O(){try{return await v("china-market-date",30*N,async()=>{let{data:e}=await y.get("https://qt.gtimg.cn/q=sh000001",{responseType:"arraybuffer",timeout:5e3}),a=new TextDecoder("gbk").decode(e).match(/^v_[^=]+="(.+)";?$/m);if(!a)return null;let n=a[1].split("~");return F(n[30])})}catch{return null}}var Me=[{code:"sh000001",name:"\u4E0A\u8BC1\u6307\u6570"},{code:"sz399001",name:"\u6DF1\u8BC1\u6210\u6307"},{code:"sz399006",name:"\u521B\u4E1A\u677F\u6307"},{code:"bj899050",name:"\u5317\u8BC150"},{code:"sh000688",name:"\u79D1\u521B50"},{code:"sh000016",name:"\u4E0A\u8BC150"},{code:"sz399330",name:"\u6DF1\u8BC1100"},{code:"sh000300",name:"\u6CAA\u6DF1300"},{code:"sh000905",name:"\u4E2D\u8BC1500"},{code:"sh000852",name:"\u4E2D\u8BC11000"},{code:"sh000012",name:"\u56FD\u503A\u6307\u6570"},{code:"sh000013",name:"\u4F01\u503A\u6307\u6570"}];function Le(){return Me.map(e=>({...e}))}function Fe(e){let t=e.match(/^v_[^=]+="(.+)";?$/m);return t?t[1].split("~"):null}function ae(){let e=new Intl.DateTimeFormat("en-GB",{timeZone:"Asia/Shanghai",hour:"2-digit",minute:"2-digit",hour12:!1}).formatToParts(new Date),t=a=>e.find(n=>n.type===a)?.value||"";return`${t("hour")}:${t("minute")}`}function Oe(e){let t=ee(Date.now());if(!e||e!==t)return"closed";let a=ae(),n=Number.parseInt(a.slice(0,2),10)*60+Number.parseInt(a.slice(3,5),10),o=n>=570&&n<=690,r=n>=780&&n<=900;return n>690&&n<780?"midday_break":o||r?"trading":"closed"}async function ne({force:e=!1}={}){let t=Le();try{return await v("market-overview",30*N,async()=>{let a=`https://qt.gtimg.cn/q=${t.map(c=>c.code).join(",")}`,{data:n}=await y.get(a,{responseType:"arraybuffer",timeout:5e3}),o=new TextDecoder("gbk").decode(n),r=new Map;for(let c of o.trim().split(`
3
+ `)){let u=c.match(/^v_([^=]+)=/);if(!u)continue;let f=Fe(c);!f||f.length<33||r.set(u[1],f)}let i=r.get(t[0].code),d=F(i?.[30])||null,s=Oe(d);return{status:s,dateLabel:d?d.slice(5):"",timeLabel:s==="trading"?ae():"",items:t.map(c=>{let u=r.get(c.code),f=Number.parseFloat(u?.[3]),g=Number.parseFloat(u?.[4]),p=Number.parseFloat(u?.[32]);return{code:c.code,name:c.name,value:Number.isFinite(f)?f:null,change:Number.isFinite(f)&&Number.isFinite(g)?f-g:null,changePercent:Number.isFinite(p)?p:null}})}},{force:e})}catch{return{status:"closed",dateLabel:"",timeLabel:"",items:t.map(a=>({...a,value:null,change:null,changePercent:null}))}}}async function z(e){let t=new Map;if(e.length===0)return t;await Promise.all(e.map(async({code:n,market:o})=>{if(o>=100)return;let r=Se({code:n,market:o});if(!r){t.set(n,{latestDate:null,changesByDate:new Map});return}try{let i=await v(`stock-history:${r}`,12*R,async()=>{let d=`https://web.ifzq.gtimg.cn/appstock/app/fqkline/get?param=${r},day,,,30,qfq`,{data:s}=await y.get(d,{timeout:5e3,headers:{Referer:"https://gu.qq.com/"}}),c=s?.data?.[r],u=c?.qfqday||c?.day;if(!Array.isArray(u)||u.length===0)return{latestDate:null,changesByDate:new Map};let f=new Map;for(let g=1;g<u.length;g+=1){let p=u[g-1],l=u[g],m=l?.[0],x=parseFloat(p?.[2]),k=parseFloat(l?.[2]);if(!m||Number.isNaN(x)||Number.isNaN(k)||x===0)continue;let D=(k-x)/x*100;f.set(m,D)}return{latestDate:u[u.length-1]?.[0]||null,changesByDate:f}});t.set(n,i)}catch{t.set(n,{latestDate:null,changesByDate:new Map})}}));let a=0;for(let{code:n,market:o}of e)if(!(o<100)){try{a>0&&await te(250);let r=await De(n);t.set(n,r)}catch{t.set(n,{latestDate:null,changesByDate:new Map})}a+=1}return t}async function re(e,{force:t=!1}={}){let a=new Map;if(e.length===0)return a;let n=e.map(({code:r,market:i})=>({code:r,symbol:Ne({code:r,market:i})})).filter(r=>r.symbol);if(n.length===0)return a;let o=new Map(n.map(r=>[r.symbol,r.code]));try{let r=n.map(d=>d.symbol).sort().join(","),i=await v(`stock-quotes:${r}`,20*N,async()=>{let d=`https://qt.gtimg.cn/q=${n.map(g=>g.symbol).join(",")}`,{data:s}=await y.get(d,{responseType:"arraybuffer",timeout:5e3}),c=new TextDecoder("gbk").decode(s),u=new Map,f=c.trim().split(`
4
+ `);for(let g of f){let p=g.match(/^v_([^=]+)="(.+)";?$/);if(!p)continue;let l=p[1],m=p[2].split("~");m.length<33||u.set(l,{name:m[1],changePercent:parseFloat(m[32]),quoteDate:F(m[30])})}return u},{force:t});for(let[d,s]of o.entries())i.has(d)&&a.set(s,i.get(d))}catch{}return a}import{readFileSync as H,writeFileSync as $e,existsSync as q}from"fs";import{homedir as Ee}from"os";import{join as Ie,resolve as Re}from"path";var A=Ie(Ee(),".fundrc.json");function K(){return q(A)&&JSON.parse(H(A,"utf-8")).configPath||null}function oe(e){let t=Re(e);q(t)||(console.error(`\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728: ${t}`),process.exit(1));try{let a=JSON.parse(H(t,"utf-8"));(!a||typeof a!="object"||Object.keys(a).length===0)&&(console.error("\u914D\u7F6E\u6587\u4EF6\u4E3A\u7A7A\u6216\u683C\u5F0F\u9519\u8BEF"),process.exit(1))}catch{console.error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF0C\u9700\u8981\u5408\u6CD5\u7684 JSON"),process.exit(1)}$e(A,JSON.stringify({configPath:t},null,2)),console.log(`\u5DF2\u8BBE\u7F6E\u914D\u7F6E\u6587\u4EF6: ${t}`)}function U(){let e=K();return e||(console.error("\u672A\u8BBE\u7F6E\u914D\u7F6E\u6587\u4EF6\uFF0C\u8BF7\u8FD0\u884C: fund config <\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84>"),process.exit(1)),q(e)||(console.error(`\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728: ${e}\uFF0C\u8BF7\u91CD\u65B0\u8BBE\u7F6E: fund config <\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84>`),process.exit(1)),JSON.parse(H(e,"utf-8"))}function ie(e,t){return t.some(n=>n.isOverseas)||/全球|QDII|美元|港|海外|纳斯达克|标普|道琼斯/.test(e)?"\u5168\u7403":/ETF|指数/.test(e)?"\u6307\u6570":/债/.test(e)?"\u504F\u503A":"\u504F\u80A1"}var S="Asia/Shanghai";function Be(e=S,t=new Date){return new Date(t.toLocaleString("en-US",{timeZone:e}))}function Pe(e){return[e.getFullYear(),String(e.getMonth()+1).padStart(2,"0"),String(e.getDate()).padStart(2,"0")].join("-")}function je(){return Pe(Be())}function h(e,t=new Date){let a=new Intl.DateTimeFormat("en-CA",{timeZone:e,year:"numeric",month:"2-digit",day:"2-digit",weekday:"short",hour:"2-digit",minute:"2-digit",hour12:!1}).formatToParts(t),n=o=>a.find(r=>r.type===o)?.value||"";return{date:`${n("year")}-${n("month")}-${n("day")}`,weekday:n("weekday"),minutes:Number.parseInt(n("hour"),10)*60+Number.parseInt(n("minute"),10)}}function _(e){return["Mon","Tue","Wed","Thu","Fri"].includes(e)}function ze(e=new Date){let t=h(S,e);return _(t.weekday)?t.minutes>900||t.minutes<570:!0}function Ae(e=new Date){let t=h("Asia/Hong_Kong",e);return _(t.weekday)?t.minutes>960||t.minutes<570:!0}function He(e=new Date){let t=h("America/New_York",e);return _(t.weekday)?t.minutes>960||t.minutes<570:!0}function qe(e,t,a=new Date){return!t?.quoteDate||!w(t.changePercent)?!1:e.market===116?t.quoteDate===h("Asia/Hong_Kong",a).date:e.market>=100?t.quoteDate===h("America/New_York",a).date:t.quoteDate===h(S,a).date}function Ke(e,t){return!!(e&&t&&e===t)}function Ue(e,t=new Date){return e.market===116?h("Asia/Hong_Kong",t).date:e.market>=100?h("America/New_York",t).date:h(S,t).date}function _e(e,t=new Date){return e.market===116?Ae(t):e.market>=100?He(t):ze(t)}function Je(e,t,a=new Date){let n=t.get(e.stockCode);if(!n)return null;let o=[...n.changesByDate.keys()].sort();if(o.length===0)return null;let r=Ue(e,a);if(_e(e,a))return o[o.length-1]||null;let d=o.filter(s=>s<r);return d[d.length-1]||null}function se(e,t,a=new Date){if(!e?.time||!w(e.change))return!1;let n=e.time.slice(0,10);if(t==="\u5168\u7403"){let r=h("America/New_York",a),i=h("Asia/Hong_Kong",a);return n===r.date||n===i.date}let o=h(S,a).date;return n===o}function $(e){return!e||e.length<10?"":e.slice(5)}function w(e){return typeof e=="number"&&!Number.isNaN(e)}function J(e){return e.map(t=>({code:t.stockCode,market:t.market}))}function W(e,t,a,n=null){let o=je(),r=new Date,i=0,d=e.map(l=>{let m=t.get(l.stockCode),x=a.get(l.stockCode),k=Je(l,a,r),D=qe(l,m,r)&&(l.isOverseas||Ke(o,n))?m.changePercent:null,we=k,E=k&&x?x.changesByDate.get(k)??null:null,xe=w(D)?l.holdingRatio*D/100:0;return w(D)&&(i+=l.holdingRatio),{stockCode:l.stockCode,stockName:l.stockName,holdingRatio:l.holdingRatio,todayChange:D,previousTradingDayChange:E,previousTradingDayDate:we,contribution:w(E)?l.holdingRatio*E/100:0,weightedTodayContribution:xe,isOverseas:l.isOverseas}}),c=d.length>0&&d.every(l=>w(l.previousTradingDayChange))?d.reduce((l,m)=>l+m.contribution,0):null,u=i>0?i/100:0,f=u>=.6?d.reduce((l,m)=>l+m.weightedTodayContribution,0):null,g=d.map(l=>l.previousTradingDayDate).filter(Boolean).sort(),p=g.length>0?g[g.length-1]:null;return{previousTradingDayChange:c,weightedTodayChange:f,coverageRatio:u,contributions:d,todayDate:o,previousTradingDate:p}}async function Q(e){let t=new Map;return await Promise.all(Object.keys(e).map(async a=>{try{t.set(a,await P(a))}catch{t.set(a,[])}})),t}function We(e){let t=new Map;for(let[,a]of e)for(let n of a)t.has(n.stockCode)||t.set(n.stockCode,{code:n.stockCode,market:n.market});return[...t.values()]}async function Y(e,t){return re(We(e),t)}function de(e,t,a,n,o){let r=ie(t,a);return{code:e,name:t,todayChange:se(n,r)?n.change:null,previousTradingDayChange:o?.change??null,previousTradingDayLabel:$(o?.date??null),category:r,canDetail:!0}}async function ce(e,t,a,n,o=null){let[r,i,d]=await Promise.all([z(J(a)),j(e),L(e)]),s=W(a,n,r,o);return{...de(e,t,a,i,d),contributions:s.contributions,weightedTodayChange:s.weightedTodayChange,coverageRatio:s.coverageRatio,todayLabel:$(s.todayDate)}}async function V(e,{forceRefresh:t=!1}={}){let a=await Q(e);return(await Promise.all(Object.entries(e).map(async([o,r])=>{let i=a.get(o)||[],[d,s]=await Promise.all([j(o,{force:t}),L(o)]);return{code:o,name:r,holdings:i,estimate:d,latestNetWorth:s}}))).map(({code:o,name:r,holdings:i,estimate:d,latestNetWorth:s})=>de(o,r,i,d,s))}async function le(e){let[t,a]=await Promise.all([V(e,{forceRefresh:!0}),ne({force:!0})]);return{funds:t,marketOverview:a}}async function ue(e,t,{forceRefreshPrices:a=!1}={}){let n=await P(e),o=new Map([[e,n]]),[r,i,d,s]=await Promise.all([Y(o,{force:a}),O(),z(J(n)),L(e)]),c=W(n,r,d,i);return{code:e,name:t,previousTradingDayChange:s?.change??null,previousTradingDayLabel:$(s?.date??null),weightedTodayChange:w(c.weightedTodayChange)?c.weightedTodayChange:null,coverageRatio:c.coverageRatio,contributions:c.contributions}}import M from"chalk";import fe from"cli-table3";function C(e){if(e==null||Number.isNaN(e))return"-";let t=parseFloat(e);return t>0?M.red(`+${t.toFixed(2)}%`):t<0?M.green(`${t.toFixed(2)}%`):`${t.toFixed(2)}%`}function ge(e,t,a){return!t||t===a?C(e):`${C(e)}
5
+ ${M.gray(t)}`}function Qe(e,t){return t?`${e} (${t})`:e}function me(e,t){let a="";for(let n of e){let o=t(n);o&&o>a&&(a=o)}return a}function pe(e,t){return t?`${e}
6
+ ${t}`:e}function he(e){let{code:t,name:a,todayChange:n,previousTradingDayChange:o,contributions:r}=e,i=me(r,s=>s.previousTradingDayDate?.slice(5)||""),d=new fe({head:["\u6301\u4ED3","\u5360\u6BD4",pe("\u6536\u76D8\u6DA8\u8DCC",i),"\u6DA8\u8DCC"],style:{head:["cyan"]}});for(let s of r)d.push([`${s.stockCode} ${s.stockName}`,`${s.holdingRatio.toFixed(2)}%`,ge(s.previousTradingDayChange,s.previousTradingDayDate?.slice(5),i),C(s.todayChange)]);console.log(`
7
+ ${M.bold(t)} ${M.bold(a)}`),console.log(d.toString()),console.log(`${Qe("\u51C0\u503C",e.previousTradingDayLabel)}: ${C(o)}`),console.log(`\u6DA8\u8DCC: ${C(n)}
8
+ `)}function be(e){let t=me(e,n=>n.previousTradingDayLabel||""),a=new fe({head:["\u57FA\u91D1\u4EE3\u7801","\u57FA\u91D1\u540D\u79F0",pe("\u51C0\u503C",t),"\u4F30\u503C"],style:{head:["cyan"]}});for(let n of e)a.push([n.code,n.name,ge(n.previousTradingDayChange,n.previousTradingDayLabel,t),C(n.todayChange)]);console.log(a.toString())}import ye from"express";import{spawn as Ye}from"child_process";import{networkInterfaces as Ve}from"os";async function Ge(e){return le(e)}async function Ze(e,t,a=!1){return ue(e,t,{forceRefreshPrices:a})}function Xe(e){let t=null,a=[];process.platform==="darwin"?(t="open",a=[e]):process.platform==="win32"?(t="cmd",a=["/c","start","",e]):(t="xdg-open",a=[e]);try{Ye(t,a,{detached:!0,stdio:"ignore"}).unref()}catch{}}function et(e){let t=Ve(),a=["en0","en1","Ethernet","Wi-Fi","wlan0","eth0"],n=[];for(let[o,r]of Object.entries(t))for(let i of r||[])i.family!=="IPv4"||i.internal||n.push({name:o,address:i.address});return n.length===0?null:(n.sort((o,r)=>{let i=a.indexOf(o.name),d=a.indexOf(r.name),s=i===-1?a.length:i,c=d===-1?a.length:d;return s!==c?s-c:o.name.localeCompare(r.name)}),`http://${n[0].address}:${e}`)}function tt(){return`
9
9
  * { margin: 0; padding: 0; box-sizing: border-box; }
10
10
  body { background: #f5f0eb; color: #4a4a4a; font-family: -apple-system, "Microsoft YaHei", sans-serif; padding: 24px; }
11
11
  h1 { text-align: center; margin-bottom: 8px; font-size: 24px; color: #5a5a5a; }
@@ -186,7 +186,7 @@ ${M.bold(t)} ${M.bold(n)}`),console.log(d.toString()),console.log(`${Qe("\u51C0\
186
186
  .market-card { min-height: 72px; padding: 9px 9px; }
187
187
  .drawer { width: min(460px, 100vw); }
188
188
  }
189
- `}function Ze(){return`
189
+ `}function at(){return`
190
190
  <h1>\u57FA\u91D1\u4F30\u503C\u67E5\u8BE2</h1>
191
191
  <div class="update-time" id="updateTime"><span id="timeText"></span><button class="refresh-btn" id="refreshBtn"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M23 4v6h-6"/><path d="M20.49 15a9 9 0 1 1-2.12-9.36L23 10"/></svg></button></div>
192
192
  <section class="market-overview hidden" id="marketOverview">
@@ -228,7 +228,7 @@ ${M.bold(t)} ${M.bold(n)}`),console.log(d.toString()),console.log(`${Qe("\u51C0\
228
228
  <div class="error-msg" id="errorMsg"></div>
229
229
  </div>
230
230
  </div>
231
- `}function Xe(){return`
231
+ `}function nt(){return`
232
232
  // \u4FDD\u5B58\u5F53\u524D\u9875\u9762\u7684\u6392\u5E8F\u3001\u7B5B\u9009\u3001\u4E3B\u8868\u6570\u636E\u548C\u62BD\u5C49\u72B6\u6001\u3002
233
233
  const state = {
234
234
  sortKey: 'todayChange',
@@ -806,17 +806,17 @@ function bindEvents() {
806
806
 
807
807
  // \u6BCF 30 \u79D2\u81EA\u52A8\u5237\u65B0\u4E00\u6B21\u4E3B\u8868\u548C\u5927\u76D8\u5361\u7247\u3002
808
808
  setInterval(doRefresh, 30000);
809
- `}function et(){return`<!DOCTYPE html>
809
+ `}function rt(){return`<!DOCTYPE html>
810
810
  <html lang="zh-CN">
811
811
  <head>
812
812
  <meta charset="UTF-8">
813
813
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
814
814
  <title>\u57FA\u91D1\u4F30\u503C\u67E5\u8BE2</title>
815
- <style>${Ge()}</style>
815
+ <style>${tt()}</style>
816
816
  </head>
817
817
  <body>
818
- ${Ze()}
819
- <script>${Xe()}</script>
818
+ ${at()}
819
+ <script>${nt()}</script>
820
820
  </body>
821
- </html>`}async function ve(e){let t=ye();t.use(ye.json()),t.get("/",(a,o)=>{o.type("html").send(et())}),t.post("/api/funds",async(a,o)=>{try{let r=a.body?.funds;if(!r||typeof r!="object"||Object.keys(r).length===0)return o.status(400).json({error:"funds \u914D\u7F6E\u65E0\u6548"});let s=await Ye(r);o.json(s)}catch(r){o.status(500).json({error:r.message})}}),t.get("/api/funds/:code/detail",async(a,o)=>{try{let r=a.params.code,s=typeof a.query?.name=="string"?a.query.name:r,d=a.query?.refreshPrices==="1",i=await Ve(r,s,d);o.json(i)}catch(r){o.status(500).json({error:r.message})}});let n=t.listen(e,()=>{console.log(`\u670D\u52A1\u5DF2\u542F\u52A8: http://localhost:${e}`)})}var{version:nt}=JSON.parse(at(new URL("../package.json",import.meta.url),"utf8"));function rt(e,t){let n=e.todayChange===null||e.todayChange===void 0||Number.isNaN(e.todayChange),a=t.todayChange===null||t.todayChange===void 0||Number.isNaN(t.todayChange);return n&&a?0:n?1:a?-1:t.todayChange-e.todayChange}var b=new tt;b.name("fund").description("\u57FA\u91D1\u4F30\u503C\u67E5\u8BE2\u5DE5\u5177").version(nt,"-v, -V, --version");b.action(()=>{b.help()});b.command("config [path]").description("\u8BBE\u7F6E\u6216\u67E5\u770B\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84").action(e=>{if(e)oe(e);else{let t=K();t?console.log(t):(console.error("\u672A\u8BBE\u7F6E\u914D\u7F6E\u6587\u4EF6\uFF0C\u8BF7\u8FD0\u884C: fund config <\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84>"),process.exit(1))}});b.command("list").description("\u5217\u51FA\u6240\u6709\u914D\u7F6E\u7684\u57FA\u91D1").action(async()=>{let e=U(),t=await V(e);t.sort(rt),be(t)});b.command("detail <code>").description("\u67E5\u770B\u5355\u53EA\u57FA\u91D1\u6301\u4ED3\u8BE6\u60C5").action(async e=>{let n=U()[e];n||(console.error(`\u57FA\u91D1 ${e} \u672A\u5728\u914D\u7F6E\u6587\u4EF6\u4E2D\u914D\u7F6E`),process.exit(1));let a=await Q({[e]:n}),[o,r]=await Promise.all([Y(a),O()]),s=await ce(e,n,a.get(e)||[],o,r);he(s)});b.command("serve").description("\u542F\u52A8 Web \u670D\u52A1\uFF08\u7528\u4E8E\u90E8\u7F72\u5230\u670D\u52A1\u5668\uFF09").option("-p, --port <port>","\u7AEF\u53E3\u53F7",process.env.PORT||"8888").action(async e=>{let t=parseInt(e.port,10);await ve(t)});b.command("*",null,{noHelp:!0}).action(()=>{console.error(`\u672A\u77E5\u547D\u4EE4
821
+ </html>`}async function ve(e){let t=ye();t.use(ye.json()),t.get("/",(o,r)=>{r.type("html").send(rt())}),t.post("/api/funds",async(o,r)=>{try{let i=o.body?.funds;if(!i||typeof i!="object"||Object.keys(i).length===0)return r.status(400).json({error:"funds \u914D\u7F6E\u65E0\u6548"});let d=await Ge(i);r.json(d)}catch(i){r.status(500).json({error:i.message})}}),t.get("/api/funds/:code/detail",async(o,r)=>{try{let i=o.params.code,d=typeof o.query?.name=="string"?o.query.name:i,s=o.query?.refreshPrices==="1",c=await Ze(i,d,s);r.json(c)}catch(i){r.status(500).json({error:i.message})}});let a=`http://localhost:${e}`,n=et(e);return new Promise(o=>{let r=t.listen(e,()=>{console.log("\u670D\u52A1\u5DF2\u542F\u52A8:"),console.log(`- ${a}`),n&&console.log(`- ${n}`),Xe(a),o(r)});r.on("error",i=>{if(i?.code==="EADDRINUSE"){console.log(`\u7AEF\u53E3 ${e} \u5DF2\u88AB\u5360\u7528\uFF0C\u53EF\u80FD\u670D\u52A1\u5DF2\u7ECF\u542F\u52A8\u3002\u53EF\u5C1D\u8BD5\u8BBF\u95EE:`),console.log(`- ${a}`),n&&console.log(`- ${n}`),o(null);return}console.error(`\u542F\u52A8\u670D\u52A1\u5931\u8D25: ${i.message}`),o(null)})})}var{version:st}=JSON.parse(it(new URL("../package.json",import.meta.url),"utf8"));function dt(e,t){let a=e.todayChange===null||e.todayChange===void 0||Number.isNaN(e.todayChange),n=t.todayChange===null||t.todayChange===void 0||Number.isNaN(t.todayChange);return a&&n?0:a?1:n?-1:t.todayChange-e.todayChange}var b=new ot;b.name("fund").description("\u57FA\u91D1\u4F30\u503C\u67E5\u8BE2\u5DE5\u5177").version(st,"-v, -V, --version");b.action(()=>{b.help()});b.command("config [path]").description("\u8BBE\u7F6E\u6216\u67E5\u770B\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84").action(e=>{if(e)oe(e);else{let t=K();t?console.log(t):(console.error("\u672A\u8BBE\u7F6E\u914D\u7F6E\u6587\u4EF6\uFF0C\u8BF7\u8FD0\u884C: fund config <\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84>"),process.exit(1))}});b.command("list").description("\u5217\u51FA\u6240\u6709\u914D\u7F6E\u7684\u57FA\u91D1").action(async()=>{let e=U(),t=await V(e);t.sort(dt),be(t)});b.command("detail <code>").description("\u67E5\u770B\u5355\u53EA\u57FA\u91D1\u6301\u4ED3\u8BE6\u60C5").action(async e=>{let a=U()[e];a||(console.error(`\u57FA\u91D1 ${e} \u672A\u5728\u914D\u7F6E\u6587\u4EF6\u4E2D\u914D\u7F6E`),process.exit(1));let n=await Q({[e]:a}),[o,r]=await Promise.all([Y(n),O()]),i=await ce(e,a,n.get(e)||[],o,r);he(i)});b.command("serve").description("\u542F\u52A8 Web \u670D\u52A1\uFF08\u7528\u4E8E\u90E8\u7F72\u5230\u670D\u52A1\u5668\uFF09").option("-p, --port <port>","\u7AEF\u53E3\u53F7",process.env.PORT||"8888").action(async e=>{let t=parseInt(e.port,10);await ve(t)});b.command("*",null,{noHelp:!0}).action(()=>{console.error(`\u672A\u77E5\u547D\u4EE4
822
822
  `),b.help()});b.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cxxgo/fund-valuation-query",
3
- "version": "1.0.5",
3
+ "version": "1.0.6",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "fund": "./dist/fund.js"