@tbox.cn/app-sdk-client 0.21.0 → 0.21.1
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.
- package/dist/client/index.d.ts +12 -6
- package/dist/client/index.js +1 -1
- package/package.json +1 -1
package/dist/client/index.d.ts
CHANGED
|
@@ -257,7 +257,7 @@ type InlineCardFilter = (cards: readonly TboxCardPayload[]) => TboxCardPayload[]
|
|
|
257
257
|
* 三通道(单一模板统一化 W3-2):
|
|
258
258
|
* - 原始注册(registerMap):模块自有卡组件(RawCardRenderer 消费面);
|
|
259
259
|
* - 覆盖注册(registerOverride):聊天视图组合层覆盖(同 cardType 包装/替换——原始视图不受影响,
|
|
260
|
-
* 域模块包自持防嵌套语义,如 mall-
|
|
260
|
+
* 域模块包自持防嵌套语义,如 mall-core 包装 alipay-activity 的联单卡);
|
|
261
261
|
* - 内联过滤(registerInlineFilter):域声明哪些卡不进内联流(由域浮层自持;多域按注册序复合)。
|
|
262
262
|
* 应用组装端读取:`{...ctx.cards.getAll(), ...ctx.cards.getOverrides()}` 为聊天视图注册表;
|
|
263
263
|
* `ctx.cards.applyInlineFilters` 为 ChatPage filterInlineCards 注入值。
|
|
@@ -290,7 +290,7 @@ declare class ClientCardRegistry {
|
|
|
290
290
|
}
|
|
291
291
|
/**
|
|
292
292
|
* ClientSlotRegistry:客户端槽位注册表(slotId → 槽值,无状态)。
|
|
293
|
-
* 模块在 clientModule.register(ctx) 内注册(如 mall-
|
|
293
|
+
* 模块在 clientModule.register(ctx) 内注册(如 mall-core `ctx.slots.register('home', render)`);
|
|
294
294
|
* kit 壳按槽存在性派生应用形态(home 注册 = home-first 主屏;缺席 = chat 流)。
|
|
295
295
|
* 槽 id 词汇 = TIER0 contracts KNOWN_CLIENT_SLOT_IDS(封闭集);未知 id =
|
|
296
296
|
* 版本偏斜信号:warn + 照常注册(前向兼容——老壳消费新模块不炸,resolve 侧自然 miss 降级)。
|
|
@@ -364,10 +364,16 @@ declare function getQueryParam(key: string): string | undefined;
|
|
|
364
364
|
/**
|
|
365
365
|
* 是否运行在支付宝小程序 web-view 壳里。
|
|
366
366
|
*
|
|
367
|
-
*
|
|
368
|
-
*
|
|
369
|
-
*
|
|
370
|
-
*
|
|
367
|
+
* 识别策略(2026-09-20 起单一确定性信号):壳子在 web-view URL 上恒附加的契约标记
|
|
368
|
+
* `?container=alipay-miniapp`(buildWebViewUrl 写入;启动参数同名键不得覆盖——H7 钉死)。
|
|
369
|
+
*
|
|
370
|
+
* 历史 UA 兜底(AlipayClient / AliApp)已退役:UA 命中但参数缺席 = 支付宝内置浏览器
|
|
371
|
+
* 扫码直开等非我方壳环境,桥必无对端(壳子 default-deny 门禁),判为壳恒错——会误入
|
|
372
|
+
* code 轨后按 auth-client 既定决策直接匿名(不落 browser 轨),mock 演示不可用。
|
|
373
|
+
* URL 参数仍是本地调试的手动覆盖口(浏览器加 ?container=alipay 可强制壳行为)。
|
|
374
|
+
*
|
|
375
|
+
* 双轴辨析:本函数回答「部署意图」(这是壳);hasAlipayBridge / ensureAlipayJSSDK
|
|
376
|
+
* 回答「运行事实」(桥此刻可用)。能力判定不在此处承担。
|
|
371
377
|
*/
|
|
372
378
|
declare function isInAlipayShell(): boolean;
|
|
373
379
|
/** 支付宝 web-view 桥通信能力是否已经可用。 */
|
package/dist/client/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger as Vt}from"@tbox.cn/app-sdk-core";import{createCoreLogger as be,resolveLevel as j,setLogContextProvider as Ce}from"@tbox.cn/app-sdk-core";var M=null;Ce(()=>M??void 0);function he(e){M=e?{requestId:e.runId,conversationId:e.conversationId}:null}function ve(){try{if(typeof localStorage<"u")return j(localStorage.getItem("tbox:logLevel")??void 0,"info")}catch{}try{if(typeof location<"u"){let e=new URLSearchParams(location.search).get("logLevel");if(e)return j(e,"info")}}catch{}return"info"}function u(e){return be({tag:e,getLevel:ve,getContext:()=>M??void 0})}var X;function we(e){X=e}function Re(e){if(typeof window>"u"||typeof window.addEventListener!="function")return()=>{};let t=e??u("GLOBAL"),r=new Map,n=1e4,l=a=>{let o=Date.now();for(let[g,s]of r)o-s>=n&&r.delete(g);r.has(a)||(r.set(a,o),t.error(a),X?.send("error",a))},i=a=>{l(`uncaught: ${a.message} @ ${a.filename}:${a.lineno}`)},d=a=>{let o=a.reason instanceof Error?a.reason.message:String(a.reason);l(`unhandledrejection: ${o}`)};return window.addEventListener("error",i),window.addEventListener("unhandledrejection",d),()=>{window.removeEventListener("error",i),window.removeEventListener("unhandledrejection",d)}}import{Component as Te}from"react";var Ae=u("ErrorBoundary"),h=class extends Te{state={hasError:!1};static getDerivedStateFromError(){return{hasError:!0}}componentDidCatch(t){Ae.error("render error:",t)}render(){return this.state.hasError?this.props.fallback:this.props.children}};import{jsx as m,jsxs as Ie}from"react/jsx-runtime";var R={info:{bg:"rgba(22,119,255,0.08)",color:"#1677ff"},warning:{bg:"rgba(250,140,22,0.10)",color:"#d46b08"},error:{bg:"rgba(255,77,79,0.08)",color:"#ff4d4f"}};function Se({notices:e}){return e.length?m("div",{style:{display:"flex",flexDirection:"column",gap:4,marginBottom:8},children:e.map(t=>m("div",{style:{fontSize:12,lineHeight:"18px",padding:"4px 10px",borderRadius:8,background:R[t.level]?.bg??R.info.bg,color:R[t.level]?.color??R.info.color},children:t.message},`${t.code}:${t.message}`))}):null}function Pe({card:e,registry:t,onAction:r}){let n=e.status!=="error"?t[e.cardType]:void 0,l=e.status==="error"||!n,i=n?.selfRendersActions===!0,d=!e.isHistory&&!i&&e.actions?.length?e.actions:[],a=typeof e.expiresAt=="number"&&Date.now()>=e.expiresAt;return Ie("div",{className:`tbox-card${l?" tbox-card--fallback":""}${a?" tbox-card--stale":""}`,style:a?{opacity:.55,filter:"grayscale(1)"}:void 0,children:[m(Se,{notices:e.notices??[]}),e.status==="error"?`卡片渲染失败${e.error?`:${e.error}`:""}`:n?m(h,{fallback:"卡片渲染出错",children:m(n,{data:e.data,cardId:e.id,isHistory:!!e.isHistory,actionTokens:e.actionTokens})}):`未知卡片类型:${e.cardType}`,d.length>0&&m("div",{style:{display:"flex",gap:8,marginTop:8,flexWrap:"wrap"},children:d.map(o=>{let g=!o.kind||o.kind==="moduleAction",s=g?e.actionTokens?.[o.actionId]:void 0,p=o.enabled===!1,c=p||!r||g&&!s,f=()=>o.kind==="sendMessage"?{type:"sendMessage",value:o.value??o.label??o.actionId,visible:o.visible??!0}:o.kind==="openLink"?{type:"openLink",url:o.url??""}:{type:"moduleAction",actionId:o.actionId,contextToken:s??""},B=()=>o.style==="primary"?{fontSize:13,padding:"6px 14px",borderRadius:18,border:"1px solid var(--tbox-primary, #1677ff)",color:"#fff",background:"var(--tbox-primary, #1677ff)"}:o.style==="link"?{fontSize:13,padding:"6px 4px",borderRadius:4,border:"none",color:"var(--tbox-primary, #1677ff)",background:"transparent",textDecoration:"underline"}:{fontSize:13,padding:"6px 14px",borderRadius:18,border:"1px solid var(--tbox-primary, #1677ff)",color:"var(--tbox-primary, #1677ff)",background:"transparent"};return m("button",{type:"button",disabled:c,title:p?o.disabledReason:void 0,onClick:()=>!c&&r?.(f()),style:{...B(),cursor:c?"not-allowed":"pointer",opacity:c?.5:1},children:o.label??o.actionId},o.actionId)})})]})}import{Fragment as Ee,jsx as N}from"react/jsx-runtime";function ke({cards:e,renderItem:t,className:r}){if(e.length<=1)return N(Ee,{children:e.length===1?t(e[0]):null});let n=["tbox-card-stack",r].filter(Boolean).join(" ");return N("div",{className:n,style:{display:"flex",flexDirection:"column"},children:e.map(l=>N("div",{children:t(l)},l.id))})}import{jsx as v,jsxs as q}from"react/jsx-runtime";var x=(e,t)=>`var(--${e}, ${t})`;function Le(e){return e.selfRendersActions=!0,e}function Be(e){return q("div",{style:{borderRadius:12,background:x("tbox-card-bg","#ffffff"),padding:"12px 16px",boxShadow:`0 1px 4px ${x("tbox-shadow","rgba(0,0,0,0.06)")}`,...e.style},children:[(e.title||e.subtitle)&&q("div",{style:{marginBottom:8},children:[e.title&&v("div",{style:{fontSize:15,fontWeight:600,color:x("tbox-text-primary","#1a1a1a"),lineHeight:"20px"},children:e.title}),e.subtitle&&v("div",{style:{fontSize:12,color:x("tbox-text-secondary","#888888"),marginTop:2},children:e.subtitle})]}),e.children]})}function Oe(e){return q("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",padding:"4px 0",gap:12},children:[v("span",{style:{fontSize:13,color:x("tbox-text-secondary","#888888"),flexShrink:0},children:e.label}),v("span",{style:{fontSize:13,color:x("tbox-text-primary","#1a1a1a"),textAlign:"right",wordBreak:"break-all",...e.valueStyle},children:e.value})]})}var Me={success:{fg:"#0f8a5f",bg:"#e6f7f0"},warning:{fg:"#b26a00",bg:"#fff4e0"},neutral:{fg:"#666666",bg:"#f2f3f5"}};function Ne(e){let t=Me[e.tone];return v("span",{style:{display:"inline-block",fontSize:11,lineHeight:"18px",padding:"0 8px",borderRadius:9,color:t.fg,background:t.bg,whiteSpace:"nowrap"},children:e.text})}var Y=u("bridge"),_="https://appx/web-view.min.js",b=null;function Q(){return typeof window>"u"?null:window.my&&typeof window.my.postMessage=="function"?window.my:null}function $(){if(typeof window<"u"){let e=Q();if(e)return Promise.resolve(e)}return b||(b=new Promise(e=>{if(typeof window>"u"){e(null);return}let t=!1,r=null,n=null,l=()=>{r&&clearInterval(r),n&&clearTimeout(n),document.removeEventListener("AlipayJSBridgeReady",d)},i=o=>{t||(t=!0,l(),e(o))},d=()=>{let o=Q();o&&i(o)};document.addEventListener("AlipayJSBridgeReady",d);let a=document.querySelector(`script[src="${_}"]`);a||(a=document.createElement("script"),a.src=_,document.head.appendChild(a)),a.addEventListener("load",d,{once:!0}),a.addEventListener("error",()=>{Y.warn("加载支付宝 JSSDK 失败:",_),a?.remove(),i(null)},{once:!0}),r=setInterval(d,50),n=setTimeout(()=>{Y.warn("支付宝 JSSDK 已加载,但 my.postMessage 未就绪"),i(null)},5e3),d()}),b.then(e=>{e||(b=null)}),b)}import{detailForLog as K}from"@tbox.cn/app-sdk-core";var T="open-mini-webview-bridge",qe="1.0.0",D="my",W="my.call",F="tbox";function A(e){return!!e&&typeof e=="object"&&e.bridge===T&&typeof e.requestId=="string"}var C=u("bridge"),S=new Map,Z=0,ee=!1,re=300*1e3;function _e(){return Z+=1,`h5_${Date.now()}_${Z}`}function $e(e){if(A(e)){te(e);return}let t=e,r=e;if(r&&typeof r=="object"&&(r.detail!==void 0?t=r.detail:r.data!==void 0&&(t=r.data)),typeof t=="string")try{t=JSON.parse(t)}catch{return}A(t)&&te(t)}function te(e){let t=S.get(e.requestId);if(!t){C.debug(`收到无 pending 回执 req=${e.requestId} action=${e.action}`);return}clearTimeout(t.timer),S.delete(e.requestId);let r=Date.now()-t.startedAt;e.success?(C.info(`← ${t.apiName} ok ${r}ms req=${e.requestId}`),t.resolve(e.data)):(C.warn(`← ${t.apiName} fail code=${e.code||"BRIDGE_ERROR"} ${r}ms params=${K(t.params)} req=${e.requestId}`),t.reject({code:e.code||"BRIDGE_ERROR",errorMessage:e.errorMessage||"桥调用失败"}))}async function ne(){let e=await $();return e&&!ee&&(e.onMessage=$e,ee=!0),e}function oe(e,t,r,n,l){let i=_e();return new Promise((d,a)=>{let o=setTimeout(()=>{S.delete(i),C.warn(`← ${r} fail code=BRIDGE_TIMEOUT ${l}ms params=${K(n)} req=${i}`),a({code:"BRIDGE_TIMEOUT",errorMessage:`桥调用超时: ${r}`})},l);S.set(i,{resolve:d,reject:a,timer:o,apiName:r,params:n,startedAt:Date.now()}),C.info(`→ ${t} ${r} req=${i}`),C.debug(`params=${K(n)} req=${i}`),e.postMessage({bridge:T,action:t,apiName:r,params:n,requestId:i})})}async function y(e,t={},r="invoke",n=re){let l=await ne();if(!l)throw{code:"BRIDGE_UNAVAILABLE",errorMessage:"支付宝 WebView 桥未就绪"};return oe(l,r==="call"?W:"my",e,t,n)}async function w(e,t={},r=re){let n=await ne();if(!n)throw{code:"BRIDGE_UNAVAILABLE",errorMessage:"支付宝 WebView 桥未就绪"};return oe(n,F,e,t,r)}var H=/^[A-Za-z0-9._-]{1,80}$/u,ie=/[\u0000-\u001F\u007F]/u,ae=/^[A-Za-z][A-Za-z0-9+.-]*:/u;function De(e,t){if(!t||!H.test(t))return;let r;try{r=se(e)}catch{return}if(r.protocol!=="alipays"&&r.protocol!=="alipayrisk"||r.host!=="platformapi"||r.path!=="/startapp")return;let n=(r.appId||r.query.appId||"").trim(),l=(r.query.page||"").trim(),i=(r.query.query||"").trim()||void 0,d=l.replace(/^\/+/,"");if(!(!H.test(n)||!d||ie.test(d)||ae.test(d)||d.split("/").includes(".."))){if(n===t){let a=d.includes("?")?"&":"?";return{apiName:"navigateTo",params:{url:`/${d}${i?`${a}${i}`:""}`}}}return{apiName:"navigateToMiniProgram",params:{appId:n,path:d,...i?{query:i}:{}}}}}function V(e){try{return decodeURIComponent(e)}catch{return e}}function se(e){if(!e||typeof e!="string")throw new Error("Invalid URL");let t={protocol:"",host:"",path:"",query:{page:"",appId:""},appId:"",page:{path:"",query:{}}},r=e.match(/^([a-zA-Z]+):\/\//),n=e;r&&(t.protocol=r[1],n=n.slice(r[0].length));let l=n.indexOf("?"),i=l===-1?n:n.slice(0,l),d=l===-1?"":n.slice(l+1),a=i.indexOf("/");if(a>0?(t.host=i.slice(0,a),t.path=i.slice(a)):t.host=i,d){let o="",g={};for(let s of d.split("&")){if(s.startsWith("page=")){o=s.slice(5);continue}let p=s.indexOf("="),c=p>=0?s.slice(0,p):s;if(!c)continue;let f=p>=0?s.slice(p+1):"";g[c]=V(f)}if(t.query=g,o){t.query.page=V(o),t.query.appId&&(t.appId=t.query.appId);let s=o.indexOf("?"),p=s>=0?o.slice(0,s):o;t.page.path=V(p)}}return t}function le(e){if(typeof e!="string")return;let t;try{t=se(e)}catch{return}if(t.protocol!=="alipays"&&t.protocol!=="alipayrisk"||t.host!=="platformapi"||t.path!=="/startapp")return;let r=(t.appId||t.query.appId||"").trim(),n=(t.query.page||"").trim(),l=(t.query.query||"").trim()||void 0,i=n.replace(/^\/+/,"");if(!H.test(r)||!i||ie.test(i)||ae.test(i)||i.split("/").includes(".."))return;let d=i.includes("?")?"&":"?";return{appId:r,url:`/${i}${l?`${d}${l}`:""}`}}function We(e=9,t){return y("chooseImage",t?{count:e,sourceType:t}:{count:e},"invoke")}function Fe(){return y("chooseVideo",{},"invoke")}async function Ke(){let e=await y("getLocation",{type:0});return{...e,longitude:Number(e.longitude),latitude:Number(e.latitude)}}function Ve(e=["auth_base"]){return y("getAuthCode",{scopes:e})}function He(e){return y("tradePay",{tradeNO:e,orderStr:e})}function Ue(e){let t=le(e);return t?y("navigateTo",{url:t.url}):Promise.reject({code:"INVALID_PARAMS",errorMessage:"支付宝小程序跳转链接无效"})}function Ge(e,t=300*1e3){return w("getLoginState",e??{},t)}function Je(e={}){return w("openPlateKeyboard",{...e})}function ze(){return w("closePlateKeyboard")}import{KNOWN_CLIENT_SLOT_IDS as je}from"@tbox.cn/app-contracts";var P=u("ClientCardRegistry"),de=u("ClientSlotRegistry"),I=class{cards=new Map;overrides=new Map;inlineFilters=[];register(t,r){if(!t){P.warn("register without cardType skipped");return}this.cards.has(t)&&P.warn(`overwriting existing cardType: ${t}`),this.cards.set(t,r)}registerMap(t){for(let[r,n]of Object.entries(t))this.register(r,n)}registerOverride(t,r){if(!t){P.warn("registerOverride without cardType skipped");return}this.overrides.has(t)&&P.warn(`overwriting existing override: ${t}`),this.overrides.set(t,r)}getOverrides(){return Object.fromEntries(this.overrides)}registerInlineFilter(t){this.inlineFilters.push(t)}applyInlineFilters(t){return this.inlineFilters.length===0?[...t]:this.inlineFilters.reduce((r,n)=>n(r),[...t])}resolve(t){return this.cards.get(t)}getAll(){return Object.fromEntries(this.cards)}has(t){return this.cards.has(t)}get size(){return this.cards.size}},k=class{slots=new Map;register(t,r){je.includes(t)||de.warn(`unknown slot id: ${t}(KNOWN_CLIENT_SLOT_IDS 未含——版本偏斜?照常注册)`),this.slots.has(t)&&de.warn(`overwriting existing slot: ${t}`),this.slots.set(t,r)}resolve(t){return this.slots.get(t)}has(t){return this.slots.has(t)}get size(){return this.slots.size}};function Xe(){return{cards:new I,slots:new k}}var pe="";function Ye(e){pe=(e.apiBaseUrl??"").trim().replace(/\/$/,"")}function E(){return pe}function ce(){let e=E();return e||(typeof window<"u"?`${window.location.protocol}//${window.location.host}`:"")}function Qe(e="/ws"){return ce().replace(/^http/,"ws")+e}var U=null;function ue(){if(U)return U;let e={};return typeof window<"u"&&new URLSearchParams(window.location.search).forEach((r,n)=>{e[n]=r}),U=e,e}function ge(e){return ue()[e]}function fe(){let e=ge("container");if(e==="alipay-miniapp"||e==="alipay")return!0;if(typeof navigator<"u"){let t=navigator.userAgent;if(/AlipayClient/i.test(t)||/AliApp\(AP\//i.test(t))return!0}return!1}function Ze(){if(typeof window>"u")return!1;let e=window.my;return!!(e&&typeof e.postMessage=="function")}function et(){return fe()?"alipay-miniapp":"browser"}var tt=u("HTTP"),G=null;function rt(e){G=e}var J=null;function nt(e){J=e}function ot(e,t){if(e!==401)return!1;let r=t?.code;return r==="AUTH_UNAUTHORIZED"||r==="AUTH_TOKEN_EXPIRED"}function it(e){return e.startsWith("/api/auth/")}function ye(e="",t,r={}){let n=e.replace(/\/$/,""),l=r.auth??!1,i=r.dynamicBase??!1,d=s=>({...t?.headers,...s?.headers});function a(){return i?E():n}function o(s){let p=d(s);if(l){let c=G?G():null;c&&!p.Authorization&&(p.Authorization=`Bearer ${c}`)}return p}async function g(s,p,c,f,B=0){let me=s==="POST"&&c instanceof Blob?o(f):s==="POST"?{"Content-Type":"application/json",...o(f)}:o(f),O=await fetch(a()+p,{method:s,headers:me,body:s==="POST"&&c!==void 0?c instanceof Blob?c:JSON.stringify(c):void 0,signal:f?.signal,cache:f?.cache}),z=await O.json().catch(()=>null);if(l&&B===0&&!it(p)&&ot(O.status,z)&&J){try{await J()}catch(xe){tt.warn("401 refresh failed:",xe.message)}return g(s,p,c,f,1)}return{status:O.status,data:z}}return{get:(s,p)=>g("GET",s,void 0,p),post:(s,p,c)=>g("POST",s,p,c),postBinary:(s,p,c)=>g("POST",s,p,c)}}var L=ye("",void 0,{auth:!0,dynamicBase:!0}),at=L.get,st=L.post,lt=L.postBinary;import{sanitizeForLog as ir,detailForLog as ar,truncateForLog as sr}from"@tbox.cn/app-sdk-core";export{T as BRIDGE_NAME,qe as BRIDGE_VERSION,ke as CardCarousel,Be as CardFrame,Pe as CardRenderer,I as ClientCardRegistry,k as ClientSlotRegistry,h as ErrorBoundary,D as MY_ACTION,W as MY_CALL_ACTION,Ne as StatusPill,F as TBOX_ACTION,Oe as ValueText,w as callCapability,y as callJsapi,We as chooseImage,Fe as chooseVideo,ze as closePlateKeyboard,nt as configureAuthErrorHandler,rt as configureAuthToken,Ye as configureRuntime,Xe as createClientContext,u as createClientLogger,Vt as createLogger,ye as createService,L as defaultService,ar as detailForLog,$ as ensureAlipayJSSDK,E as getApiBaseUrl,ce as getApiOrigin,Ve as getAuthCode,et as getContainer,Ke as getLocation,Ge as getLoginState,ge as getQueryParam,ue as getRuntimeQuery,Qe as getWsUrl,Ze as hasAlipayBridge,at as httpGet,st as httpPost,lt as httpPostBinary,Re as installGlobalErrorReporting,A as isBridgeReceipt,fe as isInAlipayShell,Le as markSelfRendering,Ue as navigateToAlipayPage,Je as openPlateKeyboard,He as requestPayment,De as resolveAlipayNavigation,ir as sanitizeForLog,we as setClientLogTransport,he as setClientRunContext,sr as truncateForLog};
|
|
1
|
+
import{createLogger as Vt}from"@tbox.cn/app-sdk-core";import{createCoreLogger as be,resolveLevel as j,setLogContextProvider as Ce}from"@tbox.cn/app-sdk-core";var M=null;Ce(()=>M??void 0);function he(e){M=e?{requestId:e.runId,conversationId:e.conversationId}:null}function ve(){try{if(typeof localStorage<"u")return j(localStorage.getItem("tbox:logLevel")??void 0,"info")}catch{}try{if(typeof location<"u"){let e=new URLSearchParams(location.search).get("logLevel");if(e)return j(e,"info")}}catch{}return"info"}function u(e){return be({tag:e,getLevel:ve,getContext:()=>M??void 0})}var X;function we(e){X=e}function Re(e){if(typeof window>"u"||typeof window.addEventListener!="function")return()=>{};let t=e??u("GLOBAL"),r=new Map,n=1e4,l=a=>{let o=Date.now();for(let[g,s]of r)o-s>=n&&r.delete(g);r.has(a)||(r.set(a,o),t.error(a),X?.send("error",a))},i=a=>{l(`uncaught: ${a.message} @ ${a.filename}:${a.lineno}`)},d=a=>{let o=a.reason instanceof Error?a.reason.message:String(a.reason);l(`unhandledrejection: ${o}`)};return window.addEventListener("error",i),window.addEventListener("unhandledrejection",d),()=>{window.removeEventListener("error",i),window.removeEventListener("unhandledrejection",d)}}import{Component as Te}from"react";var Se=u("ErrorBoundary"),h=class extends Te{state={hasError:!1};static getDerivedStateFromError(){return{hasError:!0}}componentDidCatch(t){Se.error("render error:",t)}render(){return this.state.hasError?this.props.fallback:this.props.children}};import{jsx as m,jsxs as Ie}from"react/jsx-runtime";var R={info:{bg:"rgba(22,119,255,0.08)",color:"#1677ff"},warning:{bg:"rgba(250,140,22,0.10)",color:"#d46b08"},error:{bg:"rgba(255,77,79,0.08)",color:"#ff4d4f"}};function Ae({notices:e}){return e.length?m("div",{style:{display:"flex",flexDirection:"column",gap:4,marginBottom:8},children:e.map(t=>m("div",{style:{fontSize:12,lineHeight:"18px",padding:"4px 10px",borderRadius:8,background:R[t.level]?.bg??R.info.bg,color:R[t.level]?.color??R.info.color},children:t.message},`${t.code}:${t.message}`))}):null}function Pe({card:e,registry:t,onAction:r}){let n=e.status!=="error"?t[e.cardType]:void 0,l=e.status==="error"||!n,i=n?.selfRendersActions===!0,d=!e.isHistory&&!i&&e.actions?.length?e.actions:[],a=typeof e.expiresAt=="number"&&Date.now()>=e.expiresAt;return Ie("div",{className:`tbox-card${l?" tbox-card--fallback":""}${a?" tbox-card--stale":""}`,style:a?{opacity:.55,filter:"grayscale(1)"}:void 0,children:[m(Ae,{notices:e.notices??[]}),e.status==="error"?`卡片渲染失败${e.error?`:${e.error}`:""}`:n?m(h,{fallback:"卡片渲染出错",children:m(n,{data:e.data,cardId:e.id,isHistory:!!e.isHistory,actionTokens:e.actionTokens})}):`未知卡片类型:${e.cardType}`,d.length>0&&m("div",{style:{display:"flex",gap:8,marginTop:8,flexWrap:"wrap"},children:d.map(o=>{let g=!o.kind||o.kind==="moduleAction",s=g?e.actionTokens?.[o.actionId]:void 0,p=o.enabled===!1,c=p||!r||g&&!s,f=()=>o.kind==="sendMessage"?{type:"sendMessage",value:o.value??o.label??o.actionId,visible:o.visible??!0}:o.kind==="openLink"?{type:"openLink",url:o.url??""}:{type:"moduleAction",actionId:o.actionId,contextToken:s??""},B=()=>o.style==="primary"?{fontSize:13,padding:"6px 14px",borderRadius:18,border:"1px solid var(--tbox-primary, #1677ff)",color:"#fff",background:"var(--tbox-primary, #1677ff)"}:o.style==="link"?{fontSize:13,padding:"6px 4px",borderRadius:4,border:"none",color:"var(--tbox-primary, #1677ff)",background:"transparent",textDecoration:"underline"}:{fontSize:13,padding:"6px 14px",borderRadius:18,border:"1px solid var(--tbox-primary, #1677ff)",color:"var(--tbox-primary, #1677ff)",background:"transparent"};return m("button",{type:"button",disabled:c,title:p?o.disabledReason:void 0,onClick:()=>!c&&r?.(f()),style:{...B(),cursor:c?"not-allowed":"pointer",opacity:c?.5:1},children:o.label??o.actionId},o.actionId)})})]})}import{Fragment as Ee,jsx as N}from"react/jsx-runtime";function ke({cards:e,renderItem:t,className:r}){if(e.length<=1)return N(Ee,{children:e.length===1?t(e[0]):null});let n=["tbox-card-stack",r].filter(Boolean).join(" ");return N("div",{className:n,style:{display:"flex",flexDirection:"column"},children:e.map(l=>N("div",{children:t(l)},l.id))})}import{jsx as v,jsxs as q}from"react/jsx-runtime";var x=(e,t)=>`var(--${e}, ${t})`;function Le(e){return e.selfRendersActions=!0,e}function Be(e){return q("div",{style:{borderRadius:12,background:x("tbox-card-bg","#ffffff"),padding:"12px 16px",boxShadow:`0 1px 4px ${x("tbox-shadow","rgba(0,0,0,0.06)")}`,...e.style},children:[(e.title||e.subtitle)&&q("div",{style:{marginBottom:8},children:[e.title&&v("div",{style:{fontSize:15,fontWeight:600,color:x("tbox-text-primary","#1a1a1a"),lineHeight:"20px"},children:e.title}),e.subtitle&&v("div",{style:{fontSize:12,color:x("tbox-text-secondary","#888888"),marginTop:2},children:e.subtitle})]}),e.children]})}function Oe(e){return q("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",padding:"4px 0",gap:12},children:[v("span",{style:{fontSize:13,color:x("tbox-text-secondary","#888888"),flexShrink:0},children:e.label}),v("span",{style:{fontSize:13,color:x("tbox-text-primary","#1a1a1a"),textAlign:"right",wordBreak:"break-all",...e.valueStyle},children:e.value})]})}var Me={success:{fg:"#0f8a5f",bg:"#e6f7f0"},warning:{fg:"#b26a00",bg:"#fff4e0"},neutral:{fg:"#666666",bg:"#f2f3f5"}};function Ne(e){let t=Me[e.tone];return v("span",{style:{display:"inline-block",fontSize:11,lineHeight:"18px",padding:"0 8px",borderRadius:9,color:t.fg,background:t.bg,whiteSpace:"nowrap"},children:e.text})}var Y=u("bridge"),_="https://appx/web-view.min.js",b=null;function Q(){return typeof window>"u"?null:window.my&&typeof window.my.postMessage=="function"?window.my:null}function $(){if(typeof window<"u"){let e=Q();if(e)return Promise.resolve(e)}return b||(b=new Promise(e=>{if(typeof window>"u"){e(null);return}let t=!1,r=null,n=null,l=()=>{r&&clearInterval(r),n&&clearTimeout(n),document.removeEventListener("AlipayJSBridgeReady",d)},i=o=>{t||(t=!0,l(),e(o))},d=()=>{let o=Q();o&&i(o)};document.addEventListener("AlipayJSBridgeReady",d);let a=document.querySelector(`script[src="${_}"]`);a||(a=document.createElement("script"),a.src=_,document.head.appendChild(a)),a.addEventListener("load",d,{once:!0}),a.addEventListener("error",()=>{Y.warn("加载支付宝 JSSDK 失败:",_),a?.remove(),i(null)},{once:!0}),r=setInterval(d,50),n=setTimeout(()=>{Y.warn("支付宝 JSSDK 已加载,但 my.postMessage 未就绪"),i(null)},5e3),d()}),b.then(e=>{e||(b=null)}),b)}import{detailForLog as K}from"@tbox.cn/app-sdk-core";var T="open-mini-webview-bridge",qe="1.0.0",D="my",W="my.call",F="tbox";function S(e){return!!e&&typeof e=="object"&&e.bridge===T&&typeof e.requestId=="string"}var C=u("bridge"),A=new Map,Z=0,ee=!1,re=300*1e3;function _e(){return Z+=1,`h5_${Date.now()}_${Z}`}function $e(e){if(S(e)){te(e);return}let t=e,r=e;if(r&&typeof r=="object"&&(r.detail!==void 0?t=r.detail:r.data!==void 0&&(t=r.data)),typeof t=="string")try{t=JSON.parse(t)}catch{return}S(t)&&te(t)}function te(e){let t=A.get(e.requestId);if(!t){C.debug(`收到无 pending 回执 req=${e.requestId} action=${e.action}`);return}clearTimeout(t.timer),A.delete(e.requestId);let r=Date.now()-t.startedAt;e.success?(C.info(`← ${t.apiName} ok ${r}ms req=${e.requestId}`),t.resolve(e.data)):(C.warn(`← ${t.apiName} fail code=${e.code||"BRIDGE_ERROR"} ${r}ms params=${K(t.params)} req=${e.requestId}`),t.reject({code:e.code||"BRIDGE_ERROR",errorMessage:e.errorMessage||"桥调用失败"}))}async function ne(){let e=await $();return e&&!ee&&(e.onMessage=$e,ee=!0),e}function oe(e,t,r,n,l){let i=_e();return new Promise((d,a)=>{let o=setTimeout(()=>{A.delete(i),C.warn(`← ${r} fail code=BRIDGE_TIMEOUT ${l}ms params=${K(n)} req=${i}`),a({code:"BRIDGE_TIMEOUT",errorMessage:`桥调用超时: ${r}`})},l);A.set(i,{resolve:d,reject:a,timer:o,apiName:r,params:n,startedAt:Date.now()}),C.info(`→ ${t} ${r} req=${i}`),C.debug(`params=${K(n)} req=${i}`),e.postMessage({bridge:T,action:t,apiName:r,params:n,requestId:i})})}async function y(e,t={},r="invoke",n=re){let l=await ne();if(!l)throw{code:"BRIDGE_UNAVAILABLE",errorMessage:"支付宝 WebView 桥未就绪"};return oe(l,r==="call"?W:"my",e,t,n)}async function w(e,t={},r=re){let n=await ne();if(!n)throw{code:"BRIDGE_UNAVAILABLE",errorMessage:"支付宝 WebView 桥未就绪"};return oe(n,F,e,t,r)}var H=/^[A-Za-z0-9._-]{1,80}$/u,ie=/[\u0000-\u001F\u007F]/u,ae=/^[A-Za-z][A-Za-z0-9+.-]*:/u;function De(e,t){if(!t||!H.test(t))return;let r;try{r=se(e)}catch{return}if(r.protocol!=="alipays"&&r.protocol!=="alipayrisk"||r.host!=="platformapi"||r.path!=="/startapp")return;let n=(r.appId||r.query.appId||"").trim(),l=(r.query.page||"").trim(),i=(r.query.query||"").trim()||void 0,d=l.replace(/^\/+/,"");if(!(!H.test(n)||!d||ie.test(d)||ae.test(d)||d.split("/").includes(".."))){if(n===t){let a=d.includes("?")?"&":"?";return{apiName:"navigateTo",params:{url:`/${d}${i?`${a}${i}`:""}`}}}return{apiName:"navigateToMiniProgram",params:{appId:n,path:d,...i?{query:i}:{}}}}}function V(e){try{return decodeURIComponent(e)}catch{return e}}function se(e){if(!e||typeof e!="string")throw new Error("Invalid URL");let t={protocol:"",host:"",path:"",query:{page:"",appId:""},appId:"",page:{path:"",query:{}}},r=e.match(/^([a-zA-Z]+):\/\//),n=e;r&&(t.protocol=r[1],n=n.slice(r[0].length));let l=n.indexOf("?"),i=l===-1?n:n.slice(0,l),d=l===-1?"":n.slice(l+1),a=i.indexOf("/");if(a>0?(t.host=i.slice(0,a),t.path=i.slice(a)):t.host=i,d){let o="",g={};for(let s of d.split("&")){if(s.startsWith("page=")){o=s.slice(5);continue}let p=s.indexOf("="),c=p>=0?s.slice(0,p):s;if(!c)continue;let f=p>=0?s.slice(p+1):"";g[c]=V(f)}if(t.query=g,o){t.query.page=V(o),t.query.appId&&(t.appId=t.query.appId);let s=o.indexOf("?"),p=s>=0?o.slice(0,s):o;t.page.path=V(p)}}return t}function le(e){if(typeof e!="string")return;let t;try{t=se(e)}catch{return}if(t.protocol!=="alipays"&&t.protocol!=="alipayrisk"||t.host!=="platformapi"||t.path!=="/startapp")return;let r=(t.appId||t.query.appId||"").trim(),n=(t.query.page||"").trim(),l=(t.query.query||"").trim()||void 0,i=n.replace(/^\/+/,"");if(!H.test(r)||!i||ie.test(i)||ae.test(i)||i.split("/").includes(".."))return;let d=i.includes("?")?"&":"?";return{appId:r,url:`/${i}${l?`${d}${l}`:""}`}}function We(e=9,t){return y("chooseImage",t?{count:e,sourceType:t}:{count:e},"invoke")}function Fe(){return y("chooseVideo",{},"invoke")}async function Ke(){let e=await y("getLocation",{type:0});return{...e,longitude:Number(e.longitude),latitude:Number(e.latitude)}}function Ve(e=["auth_base"]){return y("getAuthCode",{scopes:e})}function He(e){return y("tradePay",{tradeNO:e,orderStr:e})}function Ue(e){let t=le(e);return t?y("navigateTo",{url:t.url}):Promise.reject({code:"INVALID_PARAMS",errorMessage:"支付宝小程序跳转链接无效"})}function Ge(e,t=300*1e3){return w("getLoginState",e??{},t)}function Je(e={}){return w("openPlateKeyboard",{...e})}function ze(){return w("closePlateKeyboard")}import{KNOWN_CLIENT_SLOT_IDS as je}from"@tbox.cn/app-contracts";var P=u("ClientCardRegistry"),de=u("ClientSlotRegistry"),I=class{cards=new Map;overrides=new Map;inlineFilters=[];register(t,r){if(!t){P.warn("register without cardType skipped");return}this.cards.has(t)&&P.warn(`overwriting existing cardType: ${t}`),this.cards.set(t,r)}registerMap(t){for(let[r,n]of Object.entries(t))this.register(r,n)}registerOverride(t,r){if(!t){P.warn("registerOverride without cardType skipped");return}this.overrides.has(t)&&P.warn(`overwriting existing override: ${t}`),this.overrides.set(t,r)}getOverrides(){return Object.fromEntries(this.overrides)}registerInlineFilter(t){this.inlineFilters.push(t)}applyInlineFilters(t){return this.inlineFilters.length===0?[...t]:this.inlineFilters.reduce((r,n)=>n(r),[...t])}resolve(t){return this.cards.get(t)}getAll(){return Object.fromEntries(this.cards)}has(t){return this.cards.has(t)}get size(){return this.cards.size}},k=class{slots=new Map;register(t,r){je.includes(t)||de.warn(`unknown slot id: ${t}(KNOWN_CLIENT_SLOT_IDS 未含——版本偏斜?照常注册)`),this.slots.has(t)&&de.warn(`overwriting existing slot: ${t}`),this.slots.set(t,r)}resolve(t){return this.slots.get(t)}has(t){return this.slots.has(t)}get size(){return this.slots.size}};function Xe(){return{cards:new I,slots:new k}}var pe="";function Ye(e){pe=(e.apiBaseUrl??"").trim().replace(/\/$/,"")}function E(){return pe}function ce(){let e=E();return e||(typeof window<"u"?`${window.location.protocol}//${window.location.host}`:"")}function Qe(e="/ws"){return ce().replace(/^http/,"ws")+e}var U=null;function ue(){if(U)return U;let e={};return typeof window<"u"&&new URLSearchParams(window.location.search).forEach((r,n)=>{e[n]=r}),U=e,e}function ge(e){return ue()[e]}function fe(){let e=ge("container");return e==="alipay-miniapp"||e==="alipay"}function Ze(){if(typeof window>"u")return!1;let e=window.my;return!!(e&&typeof e.postMessage=="function")}function et(){return fe()?"alipay-miniapp":"browser"}var tt=u("HTTP"),G=null;function rt(e){G=e}var J=null;function nt(e){J=e}function ot(e,t){if(e!==401)return!1;let r=t?.code;return r==="AUTH_UNAUTHORIZED"||r==="AUTH_TOKEN_EXPIRED"}function it(e){return e.startsWith("/api/auth/")}function ye(e="",t,r={}){let n=e.replace(/\/$/,""),l=r.auth??!1,i=r.dynamicBase??!1,d=s=>({...t?.headers,...s?.headers});function a(){return i?E():n}function o(s){let p=d(s);if(l){let c=G?G():null;c&&!p.Authorization&&(p.Authorization=`Bearer ${c}`)}return p}async function g(s,p,c,f,B=0){let me=s==="POST"&&c instanceof Blob?o(f):s==="POST"?{"Content-Type":"application/json",...o(f)}:o(f),O=await fetch(a()+p,{method:s,headers:me,body:s==="POST"&&c!==void 0?c instanceof Blob?c:JSON.stringify(c):void 0,signal:f?.signal,cache:f?.cache}),z=await O.json().catch(()=>null);if(l&&B===0&&!it(p)&&ot(O.status,z)&&J){try{await J()}catch(xe){tt.warn("401 refresh failed:",xe.message)}return g(s,p,c,f,1)}return{status:O.status,data:z}}return{get:(s,p)=>g("GET",s,void 0,p),post:(s,p,c)=>g("POST",s,p,c),postBinary:(s,p,c)=>g("POST",s,p,c)}}var L=ye("",void 0,{auth:!0,dynamicBase:!0}),at=L.get,st=L.post,lt=L.postBinary;import{sanitizeForLog as ir,detailForLog as ar,truncateForLog as sr}from"@tbox.cn/app-sdk-core";export{T as BRIDGE_NAME,qe as BRIDGE_VERSION,ke as CardCarousel,Be as CardFrame,Pe as CardRenderer,I as ClientCardRegistry,k as ClientSlotRegistry,h as ErrorBoundary,D as MY_ACTION,W as MY_CALL_ACTION,Ne as StatusPill,F as TBOX_ACTION,Oe as ValueText,w as callCapability,y as callJsapi,We as chooseImage,Fe as chooseVideo,ze as closePlateKeyboard,nt as configureAuthErrorHandler,rt as configureAuthToken,Ye as configureRuntime,Xe as createClientContext,u as createClientLogger,Vt as createLogger,ye as createService,L as defaultService,ar as detailForLog,$ as ensureAlipayJSSDK,E as getApiBaseUrl,ce as getApiOrigin,Ve as getAuthCode,et as getContainer,Ke as getLocation,Ge as getLoginState,ge as getQueryParam,ue as getRuntimeQuery,Qe as getWsUrl,Ze as hasAlipayBridge,at as httpGet,st as httpPost,lt as httpPostBinary,Re as installGlobalErrorReporting,S as isBridgeReceipt,fe as isInAlipayShell,Le as markSelfRendering,Ue as navigateToAlipayPage,Je as openPlateKeyboard,He as requestPayment,De as resolveAlipayNavigation,ir as sanitizeForLog,we as setClientLogTransport,he as setClientRunContext,sr as truncateForLog};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tbox.cn/app-sdk-client",
|
|
3
|
-
"version": "0.21.
|
|
3
|
+
"version": "0.21.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "tbox 应用平台 SDK client 轴:runtime/http/logger/error-boundary、桥接(支付宝 web-view)、client-context、卡片渲染基元。agent 前端运行时在 @tbox.cn/app-agent-sdk-client。",
|
|
6
6
|
"exports": {
|