k2-im 0.1.56 → 0.1.58

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.
@@ -0,0 +1 @@
1
+ import'./chunk-WOT6VMZA.js';import {loadBrowserCryptoDriver}from'./request-crypto.js';import {parse,isInteger,isSafeNumber}from'lossless-json';import Nt from'axios';var W="b097f885e9577cdb04d9faf91aa08329";function bt(t){return Object.keys(t).sort((r,o)=>r.localeCompare(o,void 0,{numeric:true})).map(r=>r+t[r]).join("")}function J(t,e){let r=bt(e);return t.cryptMd5(W+r+W).toUpperCase()}var Y={core:"/api/h5",wallet:"/api/h5",bi:"/bi/h5",im:""};function Ct(t){return isInteger(t)?isSafeNumber(t)?Number.parseInt(t,10):t:Number.parseFloat(t)}function k(t){return parse(t,void 0,{parseNumber:Ct})}var G="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";function L(t){if(!Number.isSafeInteger(t)||t<0)throw new RangeError("\u968F\u673A\u5B57\u7B26\u4E32\u957F\u5EA6\u5FC5\u987B\u662F\u975E\u8D1F\u6574\u6570");let e=new Uint8Array(16),r="";for(;r.length<t;){globalThis.crypto.getRandomValues(e);for(let o of e)if(!(o>=248)&&(r+=G.charAt(o%G.length),r.length===t))return r}return r}function K(){return L(10)}function X(t){return t?t instanceof Headers?Object.fromEntries(t.entries()):Array.isArray(t)?Object.fromEntries(t):{...t}:{}}function Q(t){return t?t instanceof Headers?Object.fromEntries(t.entries()):Object.fromEntries(Object.entries(t).map(([e,r])=>[e,Array.isArray(r)?r.join(", "):String(r)])):{}}function Z(t,e){let r=e.toLowerCase();return Object.entries(t).find(([n])=>n.toLowerCase()===r)?.[1]??null}function x(t,e=2){return t.toString().padStart(e,"0")}function tt(t){return `${t.getFullYear()}-${x(t.getMonth()+1)}-${x(t.getDate())} ${x(t.getHours())}:${x(t.getMinutes())}:${x(t.getSeconds())}`}function ht(t){if(t!=null)return typeof t=="string"?t:typeof t=="number"||typeof t=="boolean"||typeof t=="bigint"?String(t):t&&typeof t=="object"?JSON.stringify(t):String(t)}function et(t){let e={};for(let[r,o]of Object.entries(t)){let n=ht(o);n!==void 0&&(e[r]=n);}return e}function rt(t=16){return L(t)}function ot(t){let e={deviceBrand:"web",deviceInfo:"web",deviceNumber:"",deviceToken:"web"},r=t||(typeof navigator<"u"?navigator.userAgent:"");if(!r)return e;let o=r.match(/(Chrome|Firefox|Safari|Edg)\/([\d.]+)/i);return o?{deviceBrand:"web",deviceInfo:`${o[1]}/${o[2]}`,deviceNumber:o[2]??"",deviceToken:"web"}:{...e,deviceInfo:r}}function nt(t){let e=String(t||"").trim().toLowerCase();return e==="cn"||e.startsWith("zh-cn")?"cn":e==="tc"||e.startsWith("zh-tw")||e.startsWith("zh-hk")?"tc":e==="vn"||e.startsWith("vi")?"vn":e==="th"||e.startsWith("th")?"th":e==="en"||e.startsWith("en")?"en":"cn"}function b(t,e){return {baseUrl:e?.baseUrl??"",prefix:e?.prefix??Y[t]}}function Ot(t){return t.replace(/^\/+|\/+$/g,"")}function st(t,e,r){let o=t.replace(/\/+$/g,""),n=Ot(e),s=r.startsWith("/")?r:`/${r}`,a=n?`/${n}`:"";return `${o}${a}${s}`}function it(t,e){let r=new URLSearchParams(Object.entries(e).map(([p,c])=>[p,String(c)])).toString();if(!r)return t;let o=t.indexOf("#"),n=o>=0?t.slice(0,o):t,s=o>=0?t.slice(o):"",a=n.includes("?")?n.endsWith("?")||n.endsWith("&")?"":"&":"?";return `${n}${a}${r}${s}`}function H(t){return !!t&&t.toLowerCase().includes("application/json")}function q(t){return !!t&&t.toLowerCase().startsWith("text/")}function _(t){return t==null?new Uint8Array:typeof t=="string"?new TextEncoder().encode(t):t instanceof ArrayBuffer?new Uint8Array(t):ArrayBuffer.isView(t)?new Uint8Array(t.buffer,t.byteOffset,t.byteLength):new TextEncoder().encode(JSON.stringify(t))}function B(t){return typeof t=="string"?t:new TextDecoder().decode(_(t))}function at(t){return typeof FormData<"u"&&t instanceof FormData}var _t=new Set(["content-etag","token","req-id"]);function pt(t){let e=t.rawBody,r=e!==null&&typeof e=="object"&&"code"in e?e.code:void 0;return {transportStatus:t.transportStatus,...t.httpStatus===void 0?{}:{httpStatus:t.httpStatus},...typeof r=="number"&&Number.isFinite(r)?{businessCode:r}:{}}}function Et(t){return Number.isInteger(t)&&t>=400&&t<=599?t:502}function St(t,e){return {code:t.status,msg:t.statusText,data:null,time:Math.floor(e/1e3)}}function Dt(t,e){return {code:502,msg:t instanceof Error?t.message:String(t),data:null,time:Math.floor(e/1e3)}}function kt(t){if(!t||typeof t!="object")return false;let e=t;return Number.isFinite(e.code)&&"data"in e}function ct(t,e,r,o){if(H(r))return k(B(e.data));if(q(r))return B(e.data);let n=_(e.data),s=o?t.crypto.decryptAes(n):n,a=new TextDecoder().decode(s);return k(a)}async function ut(t,e,r){if(!t.onDebugRecord)return;let o={...e.meta,response:e.response,...r?{error:{name:r instanceof Error?r.name:void 0,message:r instanceof Error?r.message:String(r)}}:{}};try{await t.onDebugRecord(o);}catch{}}function Bt(t,e,r,o,n){if(r.customUrl)return t;let s=b(o,e.config.targets[o]),a=r.baseUrl??s.baseUrl;return st(a,n,t)}function Mt(t,e){let r=new AbortController,o=setTimeout(()=>r.abort(),t),n=()=>r.abort();return e&&(e.aborted?r.abort():e.addEventListener("abort",n,{once:true})),{signal:r.signal,dispose:()=>{clearTimeout(o),e?.removeEventListener("abort",n);}}}async function Ut(t,e,r,o,n,s,a){let p=Q(e.headers),c=Z(p,"content-type");if(e.status<200||e.status>=300){let i;if(o)i=void 0;else try{i=ct(t,e,c,r);}catch{i=void 0;}return {response:kt(i)?i:St(e,a),meta:{...n,transportStatus:"http_error",httpStatus:e.status,contentType:c,responseHeaders:p,...i!==void 0?{rawBody:i}:{},timings:{totalMs:a-s,upstreamMs:a-s}}}}let l=Date.now();if(o){let i=_(e.data),u=Date.now();return {response:{code:e.status,data:i,time:Math.floor(u/1e3)},meta:{...n,transportStatus:"success",httpStatus:e.status,contentType:c,responseHeaders:p,rawBody:i,timings:{totalMs:u-s,upstreamMs:a-s,parseMs:u-l}}}}try{if(H(c)){let P=ct(t,e,c,!1),f=Date.now();return {response:P,meta:{...n,transportStatus:"success",httpStatus:e.status,contentType:c,responseHeaders:p,rawBody:P,timings:{totalMs:f-s,upstreamMs:a-s,parseMs:f-l}}}}if(q(c)){let P=B(e.data),f=Date.now();return {response:{code:e.status,msg:e.statusText,data:P,time:Math.floor(f/1e3)},meta:{...n,transportStatus:"success",httpStatus:e.status,contentType:c,responseHeaders:p,rawBody:P,timings:{totalMs:f-s,upstreamMs:a-s,parseMs:f-l}}}}let i=_(e.data),u=Date.now(),R=r?t.crypto.decryptAes(i):i,w=Date.now(),y=new TextDecoder().decode(R),h=k(y),E=Date.now();return {response:h,meta:{...n,transportStatus:"success",httpStatus:e.status,contentType:c,responseHeaders:p,rawBody:h,timings:{totalMs:E-s,upstreamMs:a-s,parseMs:E-l,...r?{decryptMs:w-u}:{}}}}}catch(i){let u=Date.now();return {response:{code:Et(e.status),msg:i instanceof Error?i.message:String(i),data:null,time:Math.floor(u/1e3)},meta:{...n,transportStatus:"invalid_response",httpStatus:e.status,contentType:c,responseHeaders:p,timings:{totalMs:u-s,upstreamMs:a-s,parseMs:u-l}}}}}function vt(t){return async function(r,o={}){let n=t.now??(()=>new Date),s=t.randomNonce??K,a=t.randomRequestId??(()=>`req-${crypto.randomUUID().replaceAll("-","")}`),p=t.randomETag??(()=>rt()),c=(o.method??"POST").toUpperCase(),l=o.target??"core",i=b(l,t.config.targets[l]),u=o.prefix??i.prefix??"",R=o.body!=null,w=et(o.data??{}),y=r==="/v1/feedback"&&u==="/bi/h5",h=y?false:o.encrypt??!R,E=y?false:o.sign??!R,P=n(),f=p(),F=a(),mt=o.token??await t.getToken?.()??"",dt=nt(o.locale??t.getLocale?.()),O=t.getBrowserInfo?.()??ot(o.userAgent),S={app_id:"5",os_type:"4",app_version:t.config.appVersion,sign_method:"md5",timestamp:tt(P),nonce:s()},g={...S,...w,nonce:S.nonce},M=S,j=w,C=g;!y&&E&&(g.sign=t.crypto.generateSign("api",t.config.envType,g,f),S.sign=g.sign);let Pt={app_version:t.config.appVersion,"X-ENC-VERSION":t.config.appVersion,"X-APP-TYPE":"h5","Client-type":"2","Content-ETag":f,"brand-id":t.config.brandId,"channel-id":o.channelId||t.config.channelId,device_brand:O.deviceBrand,device_info:O.deviceInfo,device_number:O.deviceNumber,device_token:O.deviceToken,lang:dt,"mch-id":t.config.merchantId,"req-id":F,token:mt},Tt=X(o.headers),At=Object.fromEntries(Object.entries(Tt).filter(([T])=>!_t.has(T.toLowerCase()))),U=r,I,m={...Pt,...At};if(R)I=o.body??void 0,M=null,j=o.data??null,C=o.data??null;else if(y){let T=String(P.getTime()),d={"app-id":"1","app-version":t.config.appVersion,"sys-type":"h5","sys-version":O.deviceNumber,time:T};M=d,m={...m,...d,sign:J(t.crypto,d),"Content-Type":"application/json"},I=JSON.stringify(w),C=w;}else c==="GET"?(U=it(U,g),C=g):h?(I=t.crypto.encryptAes(new TextEncoder().encode(JSON.stringify(g))),m["Content-Type"]=m["Content-Type"]||"application/octet-stream",C=g):(I=JSON.stringify(g),m["Content-Type"]=m["Content-Type"]||"application/json",C=g);at(I)&&delete m["Content-Type"];let v=Bt(U,t,o,l,u),N=Date.now(),$=o.timeoutMs??6e4,z=Mt($,o.signal),V={requestId:F,eTag:f,method:c,upstreamUrl:v,requestHeaders:m,requestCommonParams:M,requestBusinessParams:j,requestParams:C},D;try{let T=await t.transport({url:v,method:c,headers:m,body:I,signal:z.signal,timeoutMs:$,onUploadProgress:o.onUploadProgress}),d=Date.now(),A=await Ut(t,T,h&&!y,o.responseMode==="raw",V,N,d);return o.onResponse&&(D=pt(A.meta),A.observation=D),await ut(t,A),!o.skipBusinessResponseHandler&&t.onBusinessResponse&&await t.onBusinessResponse(A.response,{request:{path:r,method:c,target:l,url:v},options:o}),A}catch(T){let d=Date.now(),A={response:Dt(T,d),...D===void 0?{}:{observation:D},meta:{...V,transportStatus:"network_error",timings:{totalMs:d-N,upstreamMs:d-N}}};return await ut(t,A,T),A}finally{z.dispose();}}}function lt(t){let e=vt(t);return async function(o,n={}){let s=await e(o,n);return await n.onResponse?.(s.observation??pt(s.meta)),s.response}}function ft(t={}){let e={core:b("core",{baseUrl:t.coreBaseUrl||"",...t.targets?.core}),wallet:b("wallet",{baseUrl:t.walletBaseUrl||"",...t.targets?.wallet}),bi:b("bi",{baseUrl:t.biBaseUrl||"",...t.targets?.bi}),im:b("im",{baseUrl:t.imBaseUrl||"",...t.targets?.im})};return {appVersion:t.appVersion||"",brandId:t.brandId||"",merchantId:t.merchantId||"",channelId:t.channelId||"",envType:t.envType||"prod",targets:e}}function gt(t={}){let e=t.axios??Nt.create();return async r=>{let o=await e.request({url:r.url,method:r.method,headers:r.headers,data:r.body,signal:r.signal,timeout:r.timeoutMs,onUploadProgress:r.onUploadProgress?n=>{let s=typeof n.progress=="number"?n.progress:typeof n.total=="number"&&n.total>0?n.loaded/n.total:void 0;r.onUploadProgress?.({loaded:n.loaded,...typeof n.total=="number"?{total:n.total}:{},...typeof s=="number"?{progress:s}:{},event:n});}:void 0,responseType:"arraybuffer",transformResponse:n=>n,validateStatus:()=>true});return {status:o.status,statusText:o.statusText,headers:o.headers,data:o.data}}}async function pe(t={}){let e=await loadBrowserCryptoDriver(),r=ft(t.config);return lt({...t,config:r,crypto:e,transport:t.transport??gt()})}export{pe as createBrowserApiProtocolClient};
package/dist/browser.d.ts CHANGED
@@ -291,7 +291,7 @@ interface ApiProtocolClientDependencies {
291
291
  getBrowserInfo?: () => ApiProtocolBrowserInfo;
292
292
  /** 注入时间源,方便测试签名与时间戳。 */
293
293
  now?: () => Date;
294
- /** 注入 nonce,方便测试或兼容特定容器随机数实现。 */
294
+ /** 注入 nonce 生成器;生产实现必须每次生成新的 10 位字母数字串,并使用安全随机源。 */
295
295
  randomNonce?: () => string;
296
296
  /** 注入请求 ID 生成器。 */
297
297
  randomRequestId?: () => string;
package/dist/browser.js CHANGED
@@ -1 +1 @@
1
- export{Va as canCopyImageToClipboard,Wa as copyImageToClipboard,C as createLazyBrowserApiProtocolClient}from'./chunk-KORCFTGX.js';import'./chunk-Q6TFPZMF.js';import'./chunk-WOT6VMZA.js';
1
+ export{Za as canCopyImageToClipboard,_a as copyImageToClipboard,C as createLazyBrowserApiProtocolClient}from'./chunk-X7ZBIWYF.js';import'./chunk-PHJQ6QKU.js';import'./chunk-WOT6VMZA.js';
@@ -400,7 +400,7 @@ type ImRobotModule = ImRobotTextModule | ImRobotImageGroupModule | ImRobotCountd
400
400
  interface ImRobotCommand {
401
401
  menuName: string;
402
402
  menuId?: string;
403
- /** wire `msg_type`;`2` 表示打开小程序,其它走固定话术。第一期宿主可只展示。 */
403
+ /** wire `msg_type`。`2` 且带 appId、domain 时打开小程序,其它类型用 menuId 请求固定回复。 */
404
404
  messageType?: string;
405
405
  miniProgram?: {
406
406
  path?: string;
@@ -5928,6 +5928,44 @@ type ImRobotDirectoryScope = {
5928
5928
  /** `bound` 对齐 iOS 输入栏 `search_type=1`。 */
5929
5929
  filter?: 'bound';
5930
5930
  };
5931
+ /** 单个机器人的资料;字段缺失时不补默认文案或人数。 */
5932
+ interface ImRobotProfile {
5933
+ id: string;
5934
+ displayName: string;
5935
+ username?: string;
5936
+ avatarUrl?: string;
5937
+ developerName?: string;
5938
+ description?: string;
5939
+ userCount?: number;
5940
+ firstChat?: boolean;
5941
+ appId?: string;
5942
+ developerId?: string;
5943
+ appName?: string;
5944
+ domain?: string;
5945
+ suffixAddress?: string;
5946
+ h5Url?: string;
5947
+ dynamicHost?: boolean;
5948
+ }
5949
+ /** 机器人输入栏的一条指令。 */
5950
+ interface ImRobotChatMenuItem {
5951
+ id: string;
5952
+ name: string;
5953
+ kind: 'message' | 'app';
5954
+ requestsReply?: boolean;
5955
+ appId?: string;
5956
+ domain?: string;
5957
+ path?: string;
5958
+ }
5959
+ /** 请求某条发消息指令的固定回复。 */
5960
+ interface ImRobotMenuReplyInput {
5961
+ robotId: string;
5962
+ menuId: string;
5963
+ }
5964
+ /** 拉取机器人资料。`lang` 是旧端语言编号 1–5。 */
5965
+ interface ImRobotProfileInput {
5966
+ robotId: string;
5967
+ lang?: number;
5968
+ }
5931
5969
  /** 机器人目录项;只保留打开私聊和列表展示所需字段。 */
5932
5970
  interface ImRobotDirectoryItem {
5933
5971
  id: string;
@@ -5958,6 +5996,14 @@ interface ImRobotsApi {
5958
5996
  listNextPage: (pageToken: ImPageToken) => Promise<ImRobotDirectoryPage>;
5959
5997
  bindToConversation: (input: ImRobotConversationBindInput) => Promise<void>;
5960
5998
  unbindFromConversation: (input: ImRobotConversationBindInput) => Promise<void>;
5999
+ /** 读取机器人资料。未配置 coreApi 时显式失败。 */
6000
+ getProfile: (input: ImRobotProfileInput) => Promise<ImRobotProfile>;
6001
+ /** 确认用户开始与该机器人私聊。 */
6002
+ confirmChat: (robotId: string) => Promise<void>;
6003
+ /** 读取输入栏指令。没有指令时返回空列表。 */
6004
+ listChatMenus: (robotId: string) => Promise<readonly ImRobotChatMenuItem[]>;
6005
+ /** 请求发消息指令的固定回复。 */
6006
+ requestMenuReply: (input: ImRobotMenuReplyInput) => Promise<void>;
5961
6007
  }
5962
6008
 
5963
6009
  /**
@@ -6870,6 +6916,8 @@ interface MediaObjectUrlLease {
6870
6916
 
6871
6917
  /** 一个用户在当前账号下已缓存的好友备注、公开昵称和头像;消息展示时再按业务优先级选择名称。 */
6872
6918
  interface SenderProfileEntry {
6919
+ /** 由机器人目录确认的资料,不用普通用户接口缺失的展示字段替换。未设置时表示普通用户资料。 */
6920
+ source?: 'robot-directory';
6873
6921
  remark: string;
6874
6922
  nickname: string;
6875
6923
  avatar: string;