easemob-websdk 5.1.0 → 5.1.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/bundle/im-sdk-web.iife.js +1 -1
- package/chunks/{chat-manager-D_KF5qM1.cjs → chat-manager-QJCNq-in.cjs} +1 -1
- package/chunks/{chat-manager-DCqgMxLm.js → chat-manager-QxcfwVLg.js} +1 -1
- package/chunks/{index-BsIqq7LU.cjs → index-Baofxzfc.cjs} +1 -1
- package/chunks/{index-BmwQgZ3E.js → index-CKbroPac.js} +1 -1
- package/chunks/{index-Dvvh1nf6.cjs → index-DIV5mZP8.cjs} +1 -1
- package/chunks/{index-CFMcR5a_.js → index-DPi6gEFw.js} +1 -1
- package/chunks/light-BcQg8h2W.cjs +1 -0
- package/chunks/light-DImBnNes.js +1 -0
- package/chunks/{reflection-proto-codec-CjRraw85.js → reflection-proto-codec-7r8Sei3y.js} +1 -1
- package/chunks/{reflection-proto-codec-BerStgkC.cjs → reflection-proto-codec-CwrIKT1L.cjs} +1 -1
- package/index.cjs +1 -1
- package/index.js +2 -2
- package/managers/chat/index.cjs +1 -1
- package/managers/chat/index.js +1 -1
- package/managers/contact/index.cjs +1 -1
- package/managers/contact/index.js +1 -1
- package/managers/group/index.cjs +1 -1
- package/managers/group/index.js +1 -1
- package/package.json +1 -1
- package/chunks/light-Dg9A1Xmd.js +0 -1
- package/chunks/light-dJjIln5b.cjs +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";const e=require("./common-BIpcR2uQ.cjs"),t=require("./cache-utils-gowrxNr8.cjs"),s=require("./user-info-DsDDTJrw.cjs"),r=require("./reflection-proto-codec-BerStgkC.cjs"),a=require("./light-dJjIln5b.cjs"),n=e=>({userId:e}),o=e=>({userId:e.userId,nickname:e.nickname,avatarUrl:e.avatarUrl,sign:e.sign,ext:e.ext}),i=e=>e,c=async(e,t)=>{const s=(e=>{const t=[],s=new Set;for(const r of e){const e=r.trim();e&&!s.has(e)&&(s.add(e),t.push(e))}return t})(e),r=new Map;if(0===s.length)return r;const a=t.cacheManager?.getUserInfoSummaries(s,!1)??[];for(const n of a)r.set(n.userId,o(n));const c=s.filter(e=>!r.has(e));if(c.length>0&&t.fetchUserInfos){const e=await t.fetchUserInfos({userIds:c});for(const t of e)r.set(t.userId,i(t))}for(const o of s)r.has(o)||r.set(o,n(o));return r},d={UNSPECIFIED:0,PING:1,PONG:2,REQUEST:3,RESPONSE:4,ERROR:5},l=0,u=0,h=1,p=1001,g=1002,m=1003,y=1004,R=1005,I=1101,E=t=>{const{orgName:s,appName:r}=e.parseAppKey(t.appKey);return{orgName:s,appName:r,encodedUserId:encodeURIComponent(t.userId),encodedResource:encodeURIComponent(t.clientResource)}},C=e=>t.isRecord(e)&&Array.isArray(e.data)?e.data.filter(e=>"string"==typeof e&&e.length>0):Array.isArray(e)?e.filter(e=>"string"==typeof e&&e.length>0):[],S=(s,r)=>{if(!Array.isArray(s.userIds)||0===s.userIds.length)throw new e.ValidationError(`${r} is required`,{code:e.ERROR_CODES.VALIDATION_REQUIRED,details:{fields:[{path:r,message:`${r} is required`,rule:"required"}]}});const a=s.userIds.map((t,s)=>{if("string"!=typeof t)throw new e.ValidationError(`${r}[${s}] must be a string`,{code:e.ERROR_CODES.VALIDATION_INVALID_FORMAT,details:{fields:[{path:`${r}[${s}]`,message:"userId must be a string",rule:"invalid_format"}]}});return t.trim()}),n=(e=>{const t=[],s=new Set;for(const r of e)r&&!s.has(r)&&(s.add(r),t.push(r));return t})(a);if(0===n.length)throw new e.ValidationError(`${r} is required`,{code:e.ERROR_CODES.VALIDATION_REQUIRED,details:{fields:[{path:r,message:`${r} is required`,rule:"required"}]}});return n.length!==a.length&&t.isRecord(s),n},f=async(e,t)=>{const s=E(t),r=`/${s.orgName}/${s.appName}/users/${s.encodedUserId}/blocks/users`,a=await e.get(r,{operation:"getBlocklist"});return C(a).map(e=>({userId:e}))},v=async(e,t,s)=>{const r=E(t),a=`/${r.orgName}/${r.appName}/sdk/user/${r.encodedUserId}/blocks?resource=${r.encodedResource}`,n=await e.post(a,{usernames:s},{operation:"addUsersToBlocklist"});return{succeeded:C(n).map(e=>({userId:e})),failed:[]}},_={nested:{easemob:{nested:{imfusion:{nested:{gateway:{nested:{v1:{nested:{MessageType:{values:{MESSAGE_TYPE_UNSPECIFIED:0,MESSAGE_TYPE_PING:1,MESSAGE_TYPE_PONG:2,MESSAGE_TYPE_ROSTER_REQUEST:3,MESSAGE_TYPE_ROSTER_RESPONSE:4,MESSAGE_TYPE_ERROR:5}},ServerStatus:{values:{SERVER_STATUS_OK:0,SERVER_STATUS_BUSY:1}},RosterResponseType:{values:{ROSTER_RESPONSE_TYPE_UNSPECIFIED:0,ROSTER_RESPONSE_TYPE_INCREMENTAL:1,ROSTER_RESPONSE_TYPE_FULL:2}},BaseMessage:{fields:{type:{type:"MessageType",id:1}}},GatewayHeader:{fields:{resource:{type:"string",id:1},timestamp:{type:"int64",id:2},requestId:{type:"string",id:3},protocolVersion:{type:"int32",id:4}}},PingRequest:{fields:{type:{type:"MessageType",id:1}}},PongResponse:{fields:{type:{type:"MessageType",id:1},status:{type:"ServerStatus",id:2}}},ErrorDetail:{fields:{type:{type:"MessageType",id:1},code:{type:"string",id:2},message:{type:"string",id:3},header:{type:"GatewayHeader",id:4}}},GetRosterRequest:{fields:{type:{type:"MessageType",id:1},header:{type:"GatewayHeader",id:2},org:{type:"string",id:3},app:{type:"string",id:4},username:{type:"string",id:5},version:{type:"string",id:6},cursor:{type:"uint64",id:7}}},RosterItem:{fields:{contact:{type:"string",id:1},remark:{type:"string",id:2},metadata:{type:"string",id:3},createdAt:{type:"int64",id:4},updatedAt:{type:"int64",id:5},metadataUpdatedAt:{type:"int64",id:6}}},GetRosterResponse:{fields:{type:{type:"MessageType",id:1},header:{type:"GatewayHeader",id:2},data:{rule:"repeated",type:"RosterItem",id:3},cursor:{type:"uint64",id:4},version:{type:"string",id:5},responseType:{type:"RosterResponseType",id:6}}}}}}}}}}}}};let O=!1,T=null;const U=()=>T||(O||(a.lightExports.util.Long=r.Long,a.lightExports.configure(),O=!0),r.installReflectionRuntime(),T=a.lightExports.Root.fromJSON(_),r.installReflectionCodecInNamespace(T),T),w=e=>"number"==typeof e?e:r.Long.isLong(e)?e.toNumber():0,b=e=>{if(!e||"object"!=typeof e)return;const t=e;return{resource:"string"==typeof t.resource?t.resource:"",timestamp:w(t.timestamp),requestId:"string"==typeof t.requestId?t.requestId:"",protocolVersion:w(t.protocolVersion)}};class N{encodeRequest(e){const t=U().lookupType("easemob.imfusion.gateway.v1.GetRosterRequest");return t.encode(t.create(e)).finish()}encodePong(e=l){const t=U().lookupType("easemob.imfusion.gateway.v1.PongResponse");return t.encode(t.create({type:d.PONG,status:e})).finish()}decode(e){const t=U(),s=t.lookupType("easemob.imfusion.gateway.v1.BaseMessage").decode(e);switch(s.type){case d.PING:return{type:d.PING};case d.PONG:{const s=t.lookupType("easemob.imfusion.gateway.v1.PongResponse").decode(e);return{type:d.PONG,status:w(s.status)}}case d.RESPONSE:{const s=t.lookupType("easemob.imfusion.gateway.v1.GetRosterResponse").decode(e);return{type:d.RESPONSE,header:b(s.header),data:Array.isArray(s.data)?s.data.map(e=>(e=>{const t=e&&"object"==typeof e?e:{};return{contact:"string"==typeof t.contact?t.contact:"",remark:"string"==typeof t.remark?t.remark:"",metadata:"string"==typeof t.metadata?t.metadata:"",createdAt:w(t.createdAt),updatedAt:w(t.updatedAt),metadataUpdatedAt:w(t.metadataUpdatedAt)}})(e)):[],cursor:w(s.cursor),version:"string"==typeof s.version?s.version:"",responseType:w(s.responseType)||u}}case d.ERROR:{const s=t.lookupType("easemob.imfusion.gateway.v1.ErrorDetail").decode(e);return{type:d.ERROR,header:b(s.header),code:"string"==typeof s.code?s.code:"",message:"string"==typeof s.message?s.message:"Unknown roster error"}}default:return{type:"number"==typeof s.type?s.type:d.UNSPECIFIED}}}}class k{constructor(e){this.pages=[],this.responseType=null,this.version="",this.nextCursor=0,this.pageCount=0,this.completed=!1,this.requestId=e}push(t){const s=t.header?.requestId;if(s&&s!==this.requestId)throw new e.SDKError("Roster response requestId mismatched",e.ERROR_CODES.CONTACT_SYNC_PROTO_DECODE_FAILED,{details:{stage:"response_decode",expectedRequestId:this.requestId,receivedRequestId:s}});if(this.completed)throw new e.SDKError("Roster response received after completion",e.ERROR_CODES.CONTACT_SYNC_CURSOR_INVALID,{details:{cursor:t.cursor}});if(null!==this.responseType&&this.responseType!==t.responseType)throw new e.SDKError("Roster response type changed in same session",e.ERROR_CODES.CONTACT_SYNC_CURSOR_INVALID,{details:{expected:this.responseType,received:t.responseType}});if(this.pages.length>0&&0!==t.cursor&&t.cursor===this.pages[this.pages.length-1]?.cursor)throw new e.SDKError("Roster cursor duplicated",e.ERROR_CODES.CONTACT_SYNC_CURSOR_INVALID,{details:{cursor:t.cursor}});return this.responseType=t.responseType,this.version=t.version||this.version,this.pages.push(t),this.nextCursor=t.cursor,this.pageCount+=1,this.completed=0===t.cursor,{done:this.completed,nextCursor:this.nextCursor,pageCount:this.pageCount}}getNextCursor(){return this.nextCursor}getPageCount(){return this.pageCount}hasPages(){return this.pages.length>0}isCompleted(){return this.completed}buildResult(){return{mode:this.responseType===h?"incremental":"full",version:this.version,pages:this.pages}}}const A=e=>e.type===d.RESPONSE,D=e=>"message"in e&&"code"in e;class M{constructor(e){this.codec=new N,this.sharedSession=e}async sync(e){const t=new k(e.request.header.requestId);return await this.syncWithSharedSession(e.request,t)}cancel(){this.sharedSession.cancel("contact-sync-cancelled")}async syncWithSharedSession(t,s){return await this.sharedSession.request({dataType:"contact",label:"Roster sync",requestId:t.header.requestId,encode:()=>{const e=this.buildAttemptRequest(t,s.getNextCursor());return this.codec.encodeRequest(e)},decode:e=>{const t=this.codec.decode(e);return{type:t.type,requestId:A(t)||D(t)?t.header?.requestId:void 0,frame:t}},onFrame:async(t,r)=>{try{if(t.type===d.PING)return void(await r.send(this.codec.encodePong()));if(A(t)){if(!s.push(t).done)return;return{done:!0,result:s.buildResult()}}if(D(t))throw(t=>{const s=t.header?.requestId,r=e=>({stage:"sync_page",serverCode:t.code,requestId:s,retryable:e});switch(Number.parseInt(t.code,10)){case g:return new e.AuthenticationError(t.message,{code:e.ERROR_CODES.AUTH_UNAUTHORIZED,details:r(!1)});case m:return new e.SDKError(t.message,e.ERROR_CODES.SERVICE_LIMIT_EXCEEDED,{details:r(!0)});case p:return new e.SDKError(t.message,e.ERROR_CODES.VALIDATION_REQUIRED,{details:r(!1)});case y:return new e.SDKError(t.message,e.ERROR_CODES.VALIDATION_INVALID_FORMAT,{details:r(!1)});case R:return new e.SDKError(t.message,e.ERROR_CODES.REST_BUSINESS_UNKNOWN,{details:r(!0)});case I:return new e.SDKError(t.message,e.ERROR_CODES.CONTACT_SYNC_SOCKET_FAILED,{details:r(!1)});default:return new e.SDKError(t.message,e.ERROR_CODES.CONTACT_SYNC_SOCKET_FAILED,{details:r(!0)})}})(t);return}catch(a){throw a instanceof e.SDKError?a:new e.SDKError("Roster frame decode failed",e.ERROR_CODES.CONTACT_SYNC_PROTO_DECODE_FAILED,{details:{stage:"response_decode",cause:a instanceof Error?a.message:String(a)}})}}})}buildAttemptRequest(e,t){return{...e,cursor:t,header:{...e.header,timestamp:Date.now(),requestId:e.header.requestId}}}}const q=e=>e.versionState.version?"incremental":"full",P=e=>{const{metadata:t,metadataFailed:s,state:r}=e,a=r.versionState.version;return s||!t?{decision:"complete"===r.cacheMeta.cacheIntegrity?q(r):"full",version:a}:t.requiresSync||"complete"!==r.cacheMeta.cacheIntegrity?t.requiresSync&&"complete"===r.cacheMeta.cacheIntegrity&&a?{decision:"incremental",version:t.version||a}:{decision:"full",version:t.version||a}:{decision:"skip",version:t.version||a}},$=e=>{if(!e)return{};try{const t=JSON.parse(e);return{nickname:"string"==typeof t.nickname?t.nickname:void 0,avatarUrl:"string"==typeof t.avatarUrl?t.avatarUrl:"string"==typeof t.avatarurl?t.avatarurl:void 0,sign:"string"==typeof t.sign?t.sign:void 0,ext:"string"==typeof t.ext?t.ext:void 0}}catch{return{}}},B=t=>{const s=(t=>{if(!(t instanceof e.SDKError&&t.details))return null;const s=t.details.httpStatus;return"number"==typeof s?s:null})(t);return 401===s||403===s||404===s},F=(e,t,s,r)=>({code:t,stage:e,message:`${e}: ${s}`,retryable:r}),x=t=>{e.logger.warn("Contact sync duration",t)};class L{constructor(e){this.running=null,this.dependencies=e}async sync(){if(this.running)return await this.running;this.running=this.runSync();try{await this.running}finally{this.running=null}}cancel(){this.dependencies.getSharedSyncSession().cancel("contact-sync-cancelled")}async runSync(){const t=this.dependencies.getContextState(),s=Date.now();let r;this.dependencies.onStart();try{const e=await this.dependencies.queryMetadata(t.versionState.version);if(r=P({metadata:e,state:t}),"skip"===r.decision)return this.dependencies.onFinish(),void x({outcome:"skip",decision:r.decision,durationMs:Date.now()-s,version:r.version,hasUsableSnapshot:t.cachedSnapshot.complete})}catch(a){if(B(a)){const r=P({metadataFailed:!0,state:t}),n=a instanceof e.SDKError?a:new e.SDKError("Contact metadata request failed",e.ERROR_CODES.CONTACT_SYNC_METADATA_FAILED,{details:{stage:"metadata"}});return this.dependencies.onFinish({error:F("metadata",n.code,n.message,!1)}),void x({outcome:"fail",decision:r.decision,durationMs:Date.now()-s,version:t.versionState.version,stage:"metadata",hasUsableSnapshot:t.cachedSnapshot.complete,source:t.cachedSnapshot.complete?t.cachedSnapshot.source:void 0})}if(r=P({metadataFailed:!0,state:t}),t.cachedSnapshot.complete)return this.dependencies.onFinish({error:F("metadata",e.ERROR_CODES.CONTACT_SYNC_METADATA_FAILED,a instanceof Error?a.message:String(a),!0)}),void x({outcome:"fail",decision:r.decision,durationMs:Date.now()-s,version:r.version,stage:"metadata",hasUsableSnapshot:!0,source:t.cachedSnapshot.source})}try{const e=await this.dependencies.getSyncUrls(),a=this.dependencies.buildRosterRequest({decision:r.decision,version:t.versionState.version}),n=await new M(this.dependencies.getSharedSyncSession()).sync({urls:e,request:a}),o=(e=>{const t=[];for(const s of e)for(const e of s.data){const s=$(e.metadata);t.push({relation:{userId:e.contact,remark:e.remark,sign:s.sign??"",addTs:e.createdAt,updatedAt:e.updatedAt,metadataUpdatedAt:e.metadataUpdatedAt},userInfo:{userId:e.contact,nickname:s.nickname,avatarUrl:s.avatarUrl,sign:s.sign,ext:s.ext}})}return t})(n.pages),i=this.dependencies.applySyncResult({mode:n.mode,relations:o.map(e=>e.relation),userInfos:o.map(e=>e.userInfo),version:n.version,lastSyncTs:Date.now()});this.dependencies.onFinish(),x({outcome:"finish",decision:r.decision,durationMs:Date.now()-s,version:n.version,source:"sync",changed:i.changed,hasUsableSnapshot:i.snapshot.complete})}catch(a){const n=a instanceof e.SDKError?a:new e.SDKError("Contact sync failed",e.ERROR_CODES.CONTACT_SYNC_SOCKET_FAILED,{details:{stage:"sync_page",cause:a instanceof Error?a.message:String(a)}}),o=n.details??{},i="string"==typeof o.stage?o.stage:"sync_page";this.dependencies.onFinish({error:F(i,n.code,n.message,!0)}),x({outcome:"fail",decision:r.decision,durationMs:Date.now()-s,version:r.version,stage:i,hasUsableSnapshot:t.cachedSnapshot.complete,source:t.cachedSnapshot.complete?t.cachedSnapshot.source:void 0})}}}const K={items:[],loaded:!1,source:"server"},V=e.mergeRuntimeErrorMaps(e.COMMON_ERROR_MAP,{common:{},apis:{getContactList:{range:"",errors:{}},addContact:{range:"110,204,210,1000,1001,1002",localErrors:{addContact:{validation_invalid:{code:110,retryable:!1}}},errors:{USER_NOT_FOUND:{code:204,httpStatus:404,retryable:!1},ALREADY_FRIEND:{code:1e3,retryable:!1},BLOCKED_BY_USER:{code:210,retryable:!1},CONTACT_REACH_LIMIT:{code:1001,httpStatus:403,retryable:!1,matchField:"error_description",matchPattern:"Inviter's contact max count"},CONTACT_REACH_LIMIT_PEER:{code:1002,httpStatus:403,retryable:!1,matchField:"error_description",matchPattern:"Invitee's contact max count"}}},deleteContact:{range:"110,204",localErrors:{deleteContact:{validation_invalid:{code:110,retryable:!1}}},errors:{USER_NOT_FOUND:{code:204,httpStatus:404,retryable:!1}}},acceptContactInvite:{range:"110,204,1001,1002",localErrors:{acceptContactInvite:{validation_invalid:{code:110,retryable:!1}}},errors:{USER_NOT_FOUND:{code:204,httpStatus:404,retryable:!1},CONTACT_REACH_LIMIT:{code:1001,httpStatus:403,retryable:!1,matchField:"error_description",matchPattern:"Inviter's contact max count"},CONTACT_REACH_LIMIT_PEER:{code:1002,httpStatus:403,retryable:!1,matchField:"error_description",matchPattern:"Invitee's contact max count"}}},declineContactInvite:{range:"110,204",localErrors:{declineContactInvite:{validation_invalid:{code:110,retryable:!1}}},errors:{USER_NOT_FOUND:{code:204,httpStatus:404,retryable:!1}}},setContactRemark:{range:"4,110,223",localErrors:{setContactRemark:{validation_invalid:{code:110,retryable:!1}}},errors:{illegal_argument:{code:223,httpStatus:400,retryable:!1,matchField:"error_description",matchPattern:"please add as a friend first"},remark_length_exceeded:{code:4,httpStatus:400,retryable:!1,matchField:"error_description",matchPattern:"remark length must less than"}}},getBlocklist:{range:"",errors:{}},addUsersToBlocklist:{range:"4,110,204",localErrors:{addUsersToBlocklist:{validation_invalid:{code:110,retryable:!1}}},errors:{service_resource_not_found:{code:204,httpStatus:404,retryable:!1},blocklist_limit_exceeded:{code:4,httpStatus:400,retryable:!1,matchField:"error_description",matchPattern:"almost reached or been greater than the upper range"}}},removeUserFromBlocklist:{range:"110",localErrors:{removeUserFromBlocklist:{validation_invalid:{code:110,retryable:!1}}},errors:{}}}}),G=class{constructor(){this.client=null,this.eventContext=null,this.restClient=null,this.restBaseUrl=null,this.restToken=null,this.blocklistSnapshot=K,this.blocklistSessionKey=null}bind(e,t){this.client=e,this.eventContext=t??null,this.blocklistSnapshot=K,this.blocklistSessionKey=null}getContacts(){return this.client?.getContactSnapshot()?.items??[]}async addContact(t){return this.runOperation("addContact",async()=>{const s=this.validateUserId(t.userId,"params.userId"),r=this.validateOptionalString(t.message,"params.message"),a=this.getRestContextOrThrow(),n=this.getRestClient(a);e.logger.debug("ContactManager addContact",{userId:s,hasMessage:"string"==typeof r&&r.length>0}),await(async(e,t,s)=>{const r=E(t),a=`/${r.orgName}/${r.appName}/users/${r.encodedUserId}/contacts/apply?resource=${r.encodedResource}`;await e.post(a,{usernames:[s.userId],reason:s.message??""},{operation:"addContact"})})(n,a,{userId:s,message:r})})}async deleteContact(t){return this.runOperation("deleteContact",async()=>{const s=this.validateUserId(t.userId,"params.userId"),r=this.getRestContextOrThrow(),a=this.getRestClient(r);e.logger.debug("ContactManager deleteContact",{userId:s}),await(async(e,t,s)=>{const r=E(t),a=`/${r.orgName}/${r.appName}/users/${r.encodedUserId}/contacts/users/${encodeURIComponent(s.userId)}?resource=${r.encodedResource}`;await e.delete(a,{operation:"deleteContact"})})(a,r,{userId:s});const n=this.client?.getCacheManager()?.removeContact(s);e.logger.debug("ContactManager deleteContact patched cache",{userId:s,changed:n?.changed??!1})})}async acceptContactInvite(t){return this.runOperation("acceptContactInvite",async()=>{const s=this.validateUserId(t.userId,"params.userId"),r=this.getRestContextOrThrow(),a=this.getRestClient(r);e.logger.debug("ContactManager acceptContactInvite",{userId:s}),await(async(e,t,s)=>{const r=E(t),a=`/${r.orgName}/${r.appName}/users/${r.encodedUserId}/contacts/accept/users/${encodeURIComponent(s.userId)}?resource=${r.encodedResource}`;await e.post(a,void 0,{operation:"acceptContactInvite"})})(a,r,{userId:s}),await this.requireClient().refreshContactSnapshot()})}async declineContactInvite(t){return this.runOperation("declineContactInvite",async()=>{const s=this.validateUserId(t.userId,"params.userId"),r=this.getRestContextOrThrow(),a=this.getRestClient(r);e.logger.debug("ContactManager declineContactInvite",{userId:s}),await(async(e,t,s)=>{const r=E(t),a=`/${r.orgName}/${r.appName}/users/${r.encodedUserId}/contacts/decline/users/${encodeURIComponent(s.userId)}?resource=${r.encodedResource}`;await e.post(a,void 0,{operation:"declineContactInvite"})})(a,r,{userId:s})})}async setContactRemark(t){return this.runOperation("setContactRemark",async()=>{const s=this.validateUserId(t.userId,"params.userId"),r=this.validateRemark(t.remark,"params.remark"),a=this.getRestContextOrThrow(),n=this.getRestClient(a);e.logger.debug("ContactManager setContactRemark",{userId:s,remarkLength:r.length}),await(async(e,t,s)=>{const r=E(t),a=`/${r.orgName}/${r.appName}/users/${r.encodedUserId}/contacts/users/${encodeURIComponent(s.userId)}?resource=${r.encodedResource}`;await e.put(a,{remark:s.remark},{operation:"setContactRemark"})})(n,a,{userId:s,remark:r});const o=this.client?.getCacheManager()?.updateContactRemark(s,r);this.client?.refreshConversationDisplayFromUserInfos([{userId:s}],"profile"),e.logger.debug("ContactManager setContactRemark patched cache",{userId:s,changed:o?.changed??!1})})}async getBlocklist(){return this.runOperation("getBlocklist",async()=>{const t=this.getRestContextOrThrow();this.ensureBlocklistSession(t);const s=this.getRestClient(t);if(this.blocklistSnapshot.loaded)return this.blocklistSnapshot.items;const r=await this.enrichBlocklistUsers(await f(s,t));return this.blocklistSnapshot={items:r,loaded:!0,source:"server"},e.logger.debug("ContactManager getBlocklist",{count:r.length}),r})}async addUsersToBlocklist(t){return this.runOperation("addUsersToBlocklist",async()=>{const s=this.getRestContextOrThrow();this.ensureBlocklistSession(s);const r=S(t,"params.userIds"),a=this.getRestClient(s);e.logger.debug("ContactManager addUsersToBlocklist",{userIds:r,inputCount:t.userIds.length,normalizedCount:r.length});const n=await v(a,s,r),o=await this.enrichBlocklistUsers(n.succeeded);return this.blocklistSnapshot=this.patchBlocklistSnapshotWithAdditions(o),{succeeded:o,failed:await this.enrichBlocklistUsers(n.failed)}})}async removeUserFromBlocklist(t){return this.runOperation("removeUserFromBlocklist",async()=>{const s=this.getRestContextOrThrow();this.ensureBlocklistSession(s);const r=S(t,"params.userIds"),a=this.getRestClient(s);e.logger.debug("ContactManager removeUserFromBlocklist",{userIds:r,inputCount:t.userIds.length,normalizedCount:r.length}),await(async(e,t,s)=>{const r=E(t),a=`/${r.orgName}/${r.appName}/sdk/user/${r.encodedUserId}/blocks?resource=${r.encodedResource}`;await e.request(a,{method:"DELETE",body:{usernames:s},operation:"removeUserFromBlocklist"})})(a,s,r),this.blocklistSnapshot=this.patchBlocklistSnapshotWithRemovals(r)})}addEventHandler(e,t){this.eventContext?.addEventHandler(e,t)}removeEventHandler(e){this.eventContext?.removeEventHandler(e)}async runOperation(t,s){try{return await s()}catch(r){const s=this.normalizeSdkError(t,r);throw e.logger.warn(`ContactManager ${t} failed`,{code:s.code,message:s.message,details:s.details}),s}}normalizeSdkError(t,s){return s instanceof e.SDKError?s:s instanceof Error?new e.SDKError(`ContactManager ${t} failed: ${s.message}`,e.ERROR_CODES.UNKNOWN):new e.SDKError(`ContactManager ${t} failed`,e.ERROR_CODES.UNKNOWN)}requireClient(){if(!this.client)throw this.buildValidationError("ContactManager is not bound to client",[{path:"contactManager.client",message:"ContactManager is not bound to client",rule:"required"}]);return this.client}getRestContextOrThrow(){return this.requireClient().getRestContext()}getRestClient(t){return this.restClient&&this.restBaseUrl===t.restBaseUrl&&this.restToken===t.token||(this.restClient=new e.RestClient(t.restBaseUrl,{errorMap:V,requestAdapter:this.requireClient().getRequestAdapter?.(),includeRequestId:!0}),this.restClient.setAuthToken(t.token),this.restBaseUrl=t.restBaseUrl,this.restToken=t.token),this.restClient}ensureBlocklistSession(e){const t=`${e.restBaseUrl}:${e.userId}:${e.token}`;this.blocklistSessionKey!==t&&(this.blocklistSessionKey=t,this.blocklistSnapshot=K)}patchBlocklistSnapshotWithAdditions(e){const t=new Map(this.blocklistSnapshot.items.map(e=>[e.userId,e]));for(const s of e)t.set(s.userId,s);return{items:Array.from(t.values()),loaded:this.blocklistSnapshot.loaded,source:"mutation_patch"}}patchBlocklistSnapshotWithRemovals(e){const t=new Map(this.blocklistSnapshot.items.map(e=>[e.userId,e]));for(const s of e)t.delete(s);return{items:Array.from(t.values()),loaded:this.blocklistSnapshot.loaded,source:"mutation_patch"}}validateUserId(e,t){if("string"!=typeof e)throw this.buildValidationError("userId must be a string",[{path:t,message:"userId must be a string",rule:"invalid_format"}]);const s=e.trim();if(!s)throw this.buildValidationError("userId is required",[{path:t,message:"userId is required",rule:"required"}]);return s}validateOptionalString(e,t){if(void 0!==e){if("string"!=typeof e)throw this.buildValidationError(`${t} must be a string`,[{path:t,message:`${t} must be a string`,rule:"invalid_format"}]);return e}}validateRemark(e,t){if("string"!=typeof e)throw this.buildValidationError("remark must be a string",[{path:t,message:"remark must be a string",rule:"invalid_format"}]);return e}buildValidationError(t,s){const r=s.some(e=>"invalid_format"===e.rule)?e.ERROR_CODES.VALIDATION_INVALID_FORMAT:e.ERROR_CODES.VALIDATION_REQUIRED;return new e.ValidationError(t,{code:r,details:{fields:s}})}async enrichBlocklistUsers(e){if(0===e.length||!this.requireClient().isUserInfoSyncEnabled())return e;const t=await c(e.map(e=>e.userId),{cacheManager:this.requireClient().getCacheManager(),fetchUserInfos:async({userIds:e})=>await this.fetchUserInfos(e)});return e.map(e=>t.get(e.userId)??e)}async fetchUserInfos(t){if(0===t.length)return[];try{const e=this.getUserInfoManager();return e?await e.getUserInfoByUserId({userIds:t}):await this.fetchUserInfosFromRest(t)}catch(s){return e.logger.warn("ContactManager user info fetch failed",{userIds:t,error:s}),[]}}async fetchUserInfosFromRest(e){const t=this.getRestContextOrThrow(),r=s.buildFetchUserInfoByUserIdRequest(e),a=await this.getRestClient(t).request(s.buildUserInfoFetchEndpoint(t),{method:"POST",body:r,operation:"getUserInfoByUserId"});return s.normalizeFetchedUserInfos(a,r.targets)}getUserInfoManager(){const e=this.requireClient();if(!this.hasUserInfoCapabilityProvider(e))return null;const t=e.getManagerByCapability("userInfo:read");return t&&this.hasUserInfoReadCapability(t)?t:null}hasUserInfoCapabilityProvider(e){return"function"==typeof e.getManagerByCapability}hasUserInfoReadCapability(e){return"function"==typeof e.getUserInfoByUserId}createSyncController(e){return new L(e)}};G.key="contactManager";let Y=G;exports.ContactManager=Y,exports.RosterMessageType=d,exports.resolveSingleContactUserInfo=async(e,t)=>((e,t,s)=>({userId:s,nickname:t?.nickname??e?.nickname,avatarUrl:t?.avatarUrl??e?.avatarUrl,mail:t?.mail??e?.mail,phone:t?.phone??e?.phone,gender:t?.gender??e?.gender,sign:t?.sign??e?.sign,birth:t?.birth??e?.birth,ext:t?.ext??e?.ext}))(void 0,(await c([e],t)).get(e),e);
|
|
1
|
+
"use strict";const e=require("./common-BIpcR2uQ.cjs"),t=require("./cache-utils-gowrxNr8.cjs"),s=require("./user-info-DsDDTJrw.cjs"),r=require("./reflection-proto-codec-CwrIKT1L.cjs"),a=require("./light-BcQg8h2W.cjs"),n=e=>({userId:e}),o=e=>({userId:e.userId,nickname:e.nickname,avatarUrl:e.avatarUrl,sign:e.sign,ext:e.ext}),i=e=>e,c=async(e,t)=>{const s=(e=>{const t=[],s=new Set;for(const r of e){const e=r.trim();e&&!s.has(e)&&(s.add(e),t.push(e))}return t})(e),r=new Map;if(0===s.length)return r;const a=t.cacheManager?.getUserInfoSummaries(s,!1)??[];for(const n of a)r.set(n.userId,o(n));const c=s.filter(e=>!r.has(e));if(c.length>0&&t.fetchUserInfos){const e=await t.fetchUserInfos({userIds:c});for(const t of e)r.set(t.userId,i(t))}for(const o of s)r.has(o)||r.set(o,n(o));return r},d={UNSPECIFIED:0,PING:1,PONG:2,REQUEST:3,RESPONSE:4,ERROR:5},l=0,u=0,h=1,p=1001,g=1002,m=1003,y=1004,R=1005,I=1101,E=t=>{const{orgName:s,appName:r}=e.parseAppKey(t.appKey);return{orgName:s,appName:r,encodedUserId:encodeURIComponent(t.userId),encodedResource:encodeURIComponent(t.clientResource)}},C=e=>t.isRecord(e)&&Array.isArray(e.data)?e.data.filter(e=>"string"==typeof e&&e.length>0):Array.isArray(e)?e.filter(e=>"string"==typeof e&&e.length>0):[],S=(s,r)=>{if(!Array.isArray(s.userIds)||0===s.userIds.length)throw new e.ValidationError(`${r} is required`,{code:e.ERROR_CODES.VALIDATION_REQUIRED,details:{fields:[{path:r,message:`${r} is required`,rule:"required"}]}});const a=s.userIds.map((t,s)=>{if("string"!=typeof t)throw new e.ValidationError(`${r}[${s}] must be a string`,{code:e.ERROR_CODES.VALIDATION_INVALID_FORMAT,details:{fields:[{path:`${r}[${s}]`,message:"userId must be a string",rule:"invalid_format"}]}});return t.trim()}),n=(e=>{const t=[],s=new Set;for(const r of e)r&&!s.has(r)&&(s.add(r),t.push(r));return t})(a);if(0===n.length)throw new e.ValidationError(`${r} is required`,{code:e.ERROR_CODES.VALIDATION_REQUIRED,details:{fields:[{path:r,message:`${r} is required`,rule:"required"}]}});return n.length!==a.length&&t.isRecord(s),n},f=async(e,t)=>{const s=E(t),r=`/${s.orgName}/${s.appName}/users/${s.encodedUserId}/blocks/users`,a=await e.get(r,{operation:"getBlocklist"});return C(a).map(e=>({userId:e}))},v=async(e,t,s)=>{const r=E(t),a=`/${r.orgName}/${r.appName}/sdk/user/${r.encodedUserId}/blocks?resource=${r.encodedResource}`,n=await e.post(a,{usernames:s},{operation:"addUsersToBlocklist"});return{succeeded:C(n).map(e=>({userId:e})),failed:[]}},_={nested:{easemob:{nested:{imfusion:{nested:{gateway:{nested:{v1:{nested:{MessageType:{values:{MESSAGE_TYPE_UNSPECIFIED:0,MESSAGE_TYPE_PING:1,MESSAGE_TYPE_PONG:2,MESSAGE_TYPE_ROSTER_REQUEST:3,MESSAGE_TYPE_ROSTER_RESPONSE:4,MESSAGE_TYPE_ERROR:5}},ServerStatus:{values:{SERVER_STATUS_OK:0,SERVER_STATUS_BUSY:1}},RosterResponseType:{values:{ROSTER_RESPONSE_TYPE_UNSPECIFIED:0,ROSTER_RESPONSE_TYPE_INCREMENTAL:1,ROSTER_RESPONSE_TYPE_FULL:2}},BaseMessage:{fields:{type:{type:"MessageType",id:1}}},GatewayHeader:{fields:{resource:{type:"string",id:1},timestamp:{type:"int64",id:2},requestId:{type:"string",id:3},protocolVersion:{type:"int32",id:4}}},PingRequest:{fields:{type:{type:"MessageType",id:1}}},PongResponse:{fields:{type:{type:"MessageType",id:1},status:{type:"ServerStatus",id:2}}},ErrorDetail:{fields:{type:{type:"MessageType",id:1},code:{type:"string",id:2},message:{type:"string",id:3},header:{type:"GatewayHeader",id:4}}},GetRosterRequest:{fields:{type:{type:"MessageType",id:1},header:{type:"GatewayHeader",id:2},org:{type:"string",id:3},app:{type:"string",id:4},username:{type:"string",id:5},version:{type:"string",id:6},cursor:{type:"uint64",id:7}}},RosterItem:{fields:{contact:{type:"string",id:1},remark:{type:"string",id:2},metadata:{type:"string",id:3},createdAt:{type:"int64",id:4},updatedAt:{type:"int64",id:5},metadataUpdatedAt:{type:"int64",id:6}}},GetRosterResponse:{fields:{type:{type:"MessageType",id:1},header:{type:"GatewayHeader",id:2},data:{rule:"repeated",type:"RosterItem",id:3},cursor:{type:"uint64",id:4},version:{type:"string",id:5},responseType:{type:"RosterResponseType",id:6}}}}}}}}}}}}};let O=!1,T=null;const U=()=>T||(O||(a.lightExports.util.Long=r.Long,a.lightExports.configure(),O=!0),r.installReflectionRuntime(),T=a.lightExports.Root.fromJSON(_),r.installReflectionCodecInNamespace(T),T),w=e=>"number"==typeof e?e:r.Long.isLong(e)?e.toNumber():0,b=e=>{if(!e||"object"!=typeof e)return;const t=e;return{resource:"string"==typeof t.resource?t.resource:"",timestamp:w(t.timestamp),requestId:"string"==typeof t.requestId?t.requestId:"",protocolVersion:w(t.protocolVersion)}};class N{encodeRequest(e){const t=U().lookupType("easemob.imfusion.gateway.v1.GetRosterRequest");return t.encode(t.create(e)).finish()}encodePong(e=l){const t=U().lookupType("easemob.imfusion.gateway.v1.PongResponse");return t.encode(t.create({type:d.PONG,status:e})).finish()}decode(e){const t=U(),s=t.lookupType("easemob.imfusion.gateway.v1.BaseMessage").decode(e);switch(s.type){case d.PING:return{type:d.PING};case d.PONG:{const s=t.lookupType("easemob.imfusion.gateway.v1.PongResponse").decode(e);return{type:d.PONG,status:w(s.status)}}case d.RESPONSE:{const s=t.lookupType("easemob.imfusion.gateway.v1.GetRosterResponse").decode(e);return{type:d.RESPONSE,header:b(s.header),data:Array.isArray(s.data)?s.data.map(e=>(e=>{const t=e&&"object"==typeof e?e:{};return{contact:"string"==typeof t.contact?t.contact:"",remark:"string"==typeof t.remark?t.remark:"",metadata:"string"==typeof t.metadata?t.metadata:"",createdAt:w(t.createdAt),updatedAt:w(t.updatedAt),metadataUpdatedAt:w(t.metadataUpdatedAt)}})(e)):[],cursor:w(s.cursor),version:"string"==typeof s.version?s.version:"",responseType:w(s.responseType)||u}}case d.ERROR:{const s=t.lookupType("easemob.imfusion.gateway.v1.ErrorDetail").decode(e);return{type:d.ERROR,header:b(s.header),code:"string"==typeof s.code?s.code:"",message:"string"==typeof s.message?s.message:"Unknown roster error"}}default:return{type:"number"==typeof s.type?s.type:d.UNSPECIFIED}}}}class k{constructor(e){this.pages=[],this.responseType=null,this.version="",this.nextCursor=0,this.pageCount=0,this.completed=!1,this.requestId=e}push(t){const s=t.header?.requestId;if(s&&s!==this.requestId)throw new e.SDKError("Roster response requestId mismatched",e.ERROR_CODES.CONTACT_SYNC_PROTO_DECODE_FAILED,{details:{stage:"response_decode",expectedRequestId:this.requestId,receivedRequestId:s}});if(this.completed)throw new e.SDKError("Roster response received after completion",e.ERROR_CODES.CONTACT_SYNC_CURSOR_INVALID,{details:{cursor:t.cursor}});if(null!==this.responseType&&this.responseType!==t.responseType)throw new e.SDKError("Roster response type changed in same session",e.ERROR_CODES.CONTACT_SYNC_CURSOR_INVALID,{details:{expected:this.responseType,received:t.responseType}});if(this.pages.length>0&&0!==t.cursor&&t.cursor===this.pages[this.pages.length-1]?.cursor)throw new e.SDKError("Roster cursor duplicated",e.ERROR_CODES.CONTACT_SYNC_CURSOR_INVALID,{details:{cursor:t.cursor}});return this.responseType=t.responseType,this.version=t.version||this.version,this.pages.push(t),this.nextCursor=t.cursor,this.pageCount+=1,this.completed=0===t.cursor,{done:this.completed,nextCursor:this.nextCursor,pageCount:this.pageCount}}getNextCursor(){return this.nextCursor}getPageCount(){return this.pageCount}hasPages(){return this.pages.length>0}isCompleted(){return this.completed}buildResult(){return{mode:this.responseType===h?"incremental":"full",version:this.version,pages:this.pages}}}const A=e=>e.type===d.RESPONSE,D=e=>"message"in e&&"code"in e;class M{constructor(e){this.codec=new N,this.sharedSession=e}async sync(e){const t=new k(e.request.header.requestId);return await this.syncWithSharedSession(e.request,t)}cancel(){this.sharedSession.cancel("contact-sync-cancelled")}async syncWithSharedSession(t,s){return await this.sharedSession.request({dataType:"contact",label:"Roster sync",requestId:t.header.requestId,encode:()=>{const e=this.buildAttemptRequest(t,s.getNextCursor());return this.codec.encodeRequest(e)},decode:e=>{const t=this.codec.decode(e);return{type:t.type,requestId:A(t)||D(t)?t.header?.requestId:void 0,frame:t}},onFrame:async(t,r)=>{try{if(t.type===d.PING)return void(await r.send(this.codec.encodePong()));if(A(t)){if(!s.push(t).done)return;return{done:!0,result:s.buildResult()}}if(D(t))throw(t=>{const s=t.header?.requestId,r=e=>({stage:"sync_page",serverCode:t.code,requestId:s,retryable:e});switch(Number.parseInt(t.code,10)){case g:return new e.AuthenticationError(t.message,{code:e.ERROR_CODES.AUTH_UNAUTHORIZED,details:r(!1)});case m:return new e.SDKError(t.message,e.ERROR_CODES.SERVICE_LIMIT_EXCEEDED,{details:r(!0)});case p:return new e.SDKError(t.message,e.ERROR_CODES.VALIDATION_REQUIRED,{details:r(!1)});case y:return new e.SDKError(t.message,e.ERROR_CODES.VALIDATION_INVALID_FORMAT,{details:r(!1)});case R:return new e.SDKError(t.message,e.ERROR_CODES.REST_BUSINESS_UNKNOWN,{details:r(!0)});case I:return new e.SDKError(t.message,e.ERROR_CODES.CONTACT_SYNC_SOCKET_FAILED,{details:r(!1)});default:return new e.SDKError(t.message,e.ERROR_CODES.CONTACT_SYNC_SOCKET_FAILED,{details:r(!0)})}})(t);return}catch(a){throw a instanceof e.SDKError?a:new e.SDKError("Roster frame decode failed",e.ERROR_CODES.CONTACT_SYNC_PROTO_DECODE_FAILED,{details:{stage:"response_decode",cause:a instanceof Error?a.message:String(a)}})}}})}buildAttemptRequest(e,t){return{...e,cursor:t,header:{...e.header,timestamp:Date.now(),requestId:e.header.requestId}}}}const q=e=>e.versionState.version?"incremental":"full",P=e=>{const{metadata:t,metadataFailed:s,state:r}=e,a=r.versionState.version;return s||!t?{decision:"complete"===r.cacheMeta.cacheIntegrity?q(r):"full",version:a}:t.requiresSync||"complete"!==r.cacheMeta.cacheIntegrity?t.requiresSync&&"complete"===r.cacheMeta.cacheIntegrity&&a?{decision:"incremental",version:t.version||a}:{decision:"full",version:t.version||a}:{decision:"skip",version:t.version||a}},$=e=>{if(!e)return{};try{const t=JSON.parse(e);return{nickname:"string"==typeof t.nickname?t.nickname:void 0,avatarUrl:"string"==typeof t.avatarUrl?t.avatarUrl:"string"==typeof t.avatarurl?t.avatarurl:void 0,sign:"string"==typeof t.sign?t.sign:void 0,ext:"string"==typeof t.ext?t.ext:void 0}}catch{return{}}},B=t=>{const s=(t=>{if(!(t instanceof e.SDKError&&t.details))return null;const s=t.details.httpStatus;return"number"==typeof s?s:null})(t);return 401===s||403===s||404===s},F=(e,t,s,r)=>({code:t,stage:e,message:`${e}: ${s}`,retryable:r}),x=t=>{e.logger.warn("Contact sync duration",t)};class L{constructor(e){this.running=null,this.dependencies=e}async sync(){if(this.running)return await this.running;this.running=this.runSync();try{await this.running}finally{this.running=null}}cancel(){this.dependencies.getSharedSyncSession().cancel("contact-sync-cancelled")}async runSync(){const t=this.dependencies.getContextState(),s=Date.now();let r;this.dependencies.onStart();try{const e=await this.dependencies.queryMetadata(t.versionState.version);if(r=P({metadata:e,state:t}),"skip"===r.decision)return this.dependencies.onFinish(),void x({outcome:"skip",decision:r.decision,durationMs:Date.now()-s,version:r.version,hasUsableSnapshot:t.cachedSnapshot.complete})}catch(a){if(B(a)){const r=P({metadataFailed:!0,state:t}),n=a instanceof e.SDKError?a:new e.SDKError("Contact metadata request failed",e.ERROR_CODES.CONTACT_SYNC_METADATA_FAILED,{details:{stage:"metadata"}});return this.dependencies.onFinish({error:F("metadata",n.code,n.message,!1)}),void x({outcome:"fail",decision:r.decision,durationMs:Date.now()-s,version:t.versionState.version,stage:"metadata",hasUsableSnapshot:t.cachedSnapshot.complete,source:t.cachedSnapshot.complete?t.cachedSnapshot.source:void 0})}if(r=P({metadataFailed:!0,state:t}),t.cachedSnapshot.complete)return this.dependencies.onFinish({error:F("metadata",e.ERROR_CODES.CONTACT_SYNC_METADATA_FAILED,a instanceof Error?a.message:String(a),!0)}),void x({outcome:"fail",decision:r.decision,durationMs:Date.now()-s,version:r.version,stage:"metadata",hasUsableSnapshot:!0,source:t.cachedSnapshot.source})}try{const e=await this.dependencies.getSyncUrls(),a=this.dependencies.buildRosterRequest({decision:r.decision,version:t.versionState.version}),n=await new M(this.dependencies.getSharedSyncSession()).sync({urls:e,request:a}),o=(e=>{const t=[];for(const s of e)for(const e of s.data){const s=$(e.metadata);t.push({relation:{userId:e.contact,remark:e.remark,sign:s.sign??"",addTs:e.createdAt,updatedAt:e.updatedAt,metadataUpdatedAt:e.metadataUpdatedAt},userInfo:{userId:e.contact,nickname:s.nickname,avatarUrl:s.avatarUrl,sign:s.sign,ext:s.ext}})}return t})(n.pages),i=this.dependencies.applySyncResult({mode:n.mode,relations:o.map(e=>e.relation),userInfos:o.map(e=>e.userInfo),version:n.version,lastSyncTs:Date.now()});this.dependencies.onFinish(),x({outcome:"finish",decision:r.decision,durationMs:Date.now()-s,version:n.version,source:"sync",changed:i.changed,hasUsableSnapshot:i.snapshot.complete})}catch(a){const n=a instanceof e.SDKError?a:new e.SDKError("Contact sync failed",e.ERROR_CODES.CONTACT_SYNC_SOCKET_FAILED,{details:{stage:"sync_page",cause:a instanceof Error?a.message:String(a)}}),o=n.details??{},i="string"==typeof o.stage?o.stage:"sync_page";this.dependencies.onFinish({error:F(i,n.code,n.message,!0)}),x({outcome:"fail",decision:r.decision,durationMs:Date.now()-s,version:r.version,stage:i,hasUsableSnapshot:t.cachedSnapshot.complete,source:t.cachedSnapshot.complete?t.cachedSnapshot.source:void 0})}}}const K={items:[],loaded:!1,source:"server"},V=e.mergeRuntimeErrorMaps(e.COMMON_ERROR_MAP,{common:{},apis:{getContactList:{range:"",errors:{}},addContact:{range:"110,204,210,1000,1001,1002",localErrors:{addContact:{validation_invalid:{code:110,retryable:!1}}},errors:{USER_NOT_FOUND:{code:204,httpStatus:404,retryable:!1},ALREADY_FRIEND:{code:1e3,retryable:!1},BLOCKED_BY_USER:{code:210,retryable:!1},CONTACT_REACH_LIMIT:{code:1001,httpStatus:403,retryable:!1,matchField:"error_description",matchPattern:"Inviter's contact max count"},CONTACT_REACH_LIMIT_PEER:{code:1002,httpStatus:403,retryable:!1,matchField:"error_description",matchPattern:"Invitee's contact max count"}}},deleteContact:{range:"110,204",localErrors:{deleteContact:{validation_invalid:{code:110,retryable:!1}}},errors:{USER_NOT_FOUND:{code:204,httpStatus:404,retryable:!1}}},acceptContactInvite:{range:"110,204,1001,1002",localErrors:{acceptContactInvite:{validation_invalid:{code:110,retryable:!1}}},errors:{USER_NOT_FOUND:{code:204,httpStatus:404,retryable:!1},CONTACT_REACH_LIMIT:{code:1001,httpStatus:403,retryable:!1,matchField:"error_description",matchPattern:"Inviter's contact max count"},CONTACT_REACH_LIMIT_PEER:{code:1002,httpStatus:403,retryable:!1,matchField:"error_description",matchPattern:"Invitee's contact max count"}}},declineContactInvite:{range:"110,204",localErrors:{declineContactInvite:{validation_invalid:{code:110,retryable:!1}}},errors:{USER_NOT_FOUND:{code:204,httpStatus:404,retryable:!1}}},setContactRemark:{range:"4,110,223",localErrors:{setContactRemark:{validation_invalid:{code:110,retryable:!1}}},errors:{illegal_argument:{code:223,httpStatus:400,retryable:!1,matchField:"error_description",matchPattern:"please add as a friend first"},remark_length_exceeded:{code:4,httpStatus:400,retryable:!1,matchField:"error_description",matchPattern:"remark length must less than"}}},getBlocklist:{range:"",errors:{}},addUsersToBlocklist:{range:"4,110,204",localErrors:{addUsersToBlocklist:{validation_invalid:{code:110,retryable:!1}}},errors:{service_resource_not_found:{code:204,httpStatus:404,retryable:!1},blocklist_limit_exceeded:{code:4,httpStatus:400,retryable:!1,matchField:"error_description",matchPattern:"almost reached or been greater than the upper range"}}},removeUserFromBlocklist:{range:"110",localErrors:{removeUserFromBlocklist:{validation_invalid:{code:110,retryable:!1}}},errors:{}}}}),G=class{constructor(){this.client=null,this.eventContext=null,this.restClient=null,this.restBaseUrl=null,this.restToken=null,this.blocklistSnapshot=K,this.blocklistSessionKey=null}bind(e,t){this.client=e,this.eventContext=t??null,this.blocklistSnapshot=K,this.blocklistSessionKey=null}getContacts(){return this.client?.getContactSnapshot()?.items??[]}async addContact(t){return this.runOperation("addContact",async()=>{const s=this.validateUserId(t.userId,"params.userId"),r=this.validateOptionalString(t.message,"params.message"),a=this.getRestContextOrThrow(),n=this.getRestClient(a);e.logger.debug("ContactManager addContact",{userId:s,hasMessage:"string"==typeof r&&r.length>0}),await(async(e,t,s)=>{const r=E(t),a=`/${r.orgName}/${r.appName}/users/${r.encodedUserId}/contacts/apply?resource=${r.encodedResource}`;await e.post(a,{usernames:[s.userId],reason:s.message??""},{operation:"addContact"})})(n,a,{userId:s,message:r})})}async deleteContact(t){return this.runOperation("deleteContact",async()=>{const s=this.validateUserId(t.userId,"params.userId"),r=this.getRestContextOrThrow(),a=this.getRestClient(r);e.logger.debug("ContactManager deleteContact",{userId:s}),await(async(e,t,s)=>{const r=E(t),a=`/${r.orgName}/${r.appName}/users/${r.encodedUserId}/contacts/users/${encodeURIComponent(s.userId)}?resource=${r.encodedResource}`;await e.delete(a,{operation:"deleteContact"})})(a,r,{userId:s});const n=this.client?.getCacheManager()?.removeContact(s);e.logger.debug("ContactManager deleteContact patched cache",{userId:s,changed:n?.changed??!1})})}async acceptContactInvite(t){return this.runOperation("acceptContactInvite",async()=>{const s=this.validateUserId(t.userId,"params.userId"),r=this.getRestContextOrThrow(),a=this.getRestClient(r);e.logger.debug("ContactManager acceptContactInvite",{userId:s}),await(async(e,t,s)=>{const r=E(t),a=`/${r.orgName}/${r.appName}/users/${r.encodedUserId}/contacts/accept/users/${encodeURIComponent(s.userId)}?resource=${r.encodedResource}`;await e.post(a,void 0,{operation:"acceptContactInvite"})})(a,r,{userId:s}),await this.requireClient().refreshContactSnapshot()})}async declineContactInvite(t){return this.runOperation("declineContactInvite",async()=>{const s=this.validateUserId(t.userId,"params.userId"),r=this.getRestContextOrThrow(),a=this.getRestClient(r);e.logger.debug("ContactManager declineContactInvite",{userId:s}),await(async(e,t,s)=>{const r=E(t),a=`/${r.orgName}/${r.appName}/users/${r.encodedUserId}/contacts/decline/users/${encodeURIComponent(s.userId)}?resource=${r.encodedResource}`;await e.post(a,void 0,{operation:"declineContactInvite"})})(a,r,{userId:s})})}async setContactRemark(t){return this.runOperation("setContactRemark",async()=>{const s=this.validateUserId(t.userId,"params.userId"),r=this.validateRemark(t.remark,"params.remark"),a=this.getRestContextOrThrow(),n=this.getRestClient(a);e.logger.debug("ContactManager setContactRemark",{userId:s,remarkLength:r.length}),await(async(e,t,s)=>{const r=E(t),a=`/${r.orgName}/${r.appName}/users/${r.encodedUserId}/contacts/users/${encodeURIComponent(s.userId)}?resource=${r.encodedResource}`;await e.put(a,{remark:s.remark},{operation:"setContactRemark"})})(n,a,{userId:s,remark:r});const o=this.client?.getCacheManager()?.updateContactRemark(s,r);this.client?.refreshConversationDisplayFromUserInfos([{userId:s}],"profile"),e.logger.debug("ContactManager setContactRemark patched cache",{userId:s,changed:o?.changed??!1})})}async getBlocklist(){return this.runOperation("getBlocklist",async()=>{const t=this.getRestContextOrThrow();this.ensureBlocklistSession(t);const s=this.getRestClient(t);if(this.blocklistSnapshot.loaded)return this.blocklistSnapshot.items;const r=await this.enrichBlocklistUsers(await f(s,t));return this.blocklistSnapshot={items:r,loaded:!0,source:"server"},e.logger.debug("ContactManager getBlocklist",{count:r.length}),r})}async addUsersToBlocklist(t){return this.runOperation("addUsersToBlocklist",async()=>{const s=this.getRestContextOrThrow();this.ensureBlocklistSession(s);const r=S(t,"params.userIds"),a=this.getRestClient(s);e.logger.debug("ContactManager addUsersToBlocklist",{userIds:r,inputCount:t.userIds.length,normalizedCount:r.length});const n=await v(a,s,r),o=await this.enrichBlocklistUsers(n.succeeded);return this.blocklistSnapshot=this.patchBlocklistSnapshotWithAdditions(o),{succeeded:o,failed:await this.enrichBlocklistUsers(n.failed)}})}async removeUserFromBlocklist(t){return this.runOperation("removeUserFromBlocklist",async()=>{const s=this.getRestContextOrThrow();this.ensureBlocklistSession(s);const r=S(t,"params.userIds"),a=this.getRestClient(s);e.logger.debug("ContactManager removeUserFromBlocklist",{userIds:r,inputCount:t.userIds.length,normalizedCount:r.length}),await(async(e,t,s)=>{const r=E(t),a=`/${r.orgName}/${r.appName}/sdk/user/${r.encodedUserId}/blocks?resource=${r.encodedResource}`;await e.request(a,{method:"DELETE",body:{usernames:s},operation:"removeUserFromBlocklist"})})(a,s,r),this.blocklistSnapshot=this.patchBlocklistSnapshotWithRemovals(r)})}addEventHandler(e,t){this.eventContext?.addEventHandler(e,t)}removeEventHandler(e){this.eventContext?.removeEventHandler(e)}async runOperation(t,s){try{return await s()}catch(r){const s=this.normalizeSdkError(t,r);throw e.logger.warn(`ContactManager ${t} failed`,{code:s.code,message:s.message,details:s.details}),s}}normalizeSdkError(t,s){return s instanceof e.SDKError?s:s instanceof Error?new e.SDKError(`ContactManager ${t} failed: ${s.message}`,e.ERROR_CODES.UNKNOWN):new e.SDKError(`ContactManager ${t} failed`,e.ERROR_CODES.UNKNOWN)}requireClient(){if(!this.client)throw this.buildValidationError("ContactManager is not bound to client",[{path:"contactManager.client",message:"ContactManager is not bound to client",rule:"required"}]);return this.client}getRestContextOrThrow(){return this.requireClient().getRestContext()}getRestClient(t){return this.restClient&&this.restBaseUrl===t.restBaseUrl&&this.restToken===t.token||(this.restClient=new e.RestClient(t.restBaseUrl,{errorMap:V,requestAdapter:this.requireClient().getRequestAdapter?.(),includeRequestId:!0}),this.restClient.setAuthToken(t.token),this.restBaseUrl=t.restBaseUrl,this.restToken=t.token),this.restClient}ensureBlocklistSession(e){const t=`${e.restBaseUrl}:${e.userId}:${e.token}`;this.blocklistSessionKey!==t&&(this.blocklistSessionKey=t,this.blocklistSnapshot=K)}patchBlocklistSnapshotWithAdditions(e){const t=new Map(this.blocklistSnapshot.items.map(e=>[e.userId,e]));for(const s of e)t.set(s.userId,s);return{items:Array.from(t.values()),loaded:this.blocklistSnapshot.loaded,source:"mutation_patch"}}patchBlocklistSnapshotWithRemovals(e){const t=new Map(this.blocklistSnapshot.items.map(e=>[e.userId,e]));for(const s of e)t.delete(s);return{items:Array.from(t.values()),loaded:this.blocklistSnapshot.loaded,source:"mutation_patch"}}validateUserId(e,t){if("string"!=typeof e)throw this.buildValidationError("userId must be a string",[{path:t,message:"userId must be a string",rule:"invalid_format"}]);const s=e.trim();if(!s)throw this.buildValidationError("userId is required",[{path:t,message:"userId is required",rule:"required"}]);return s}validateOptionalString(e,t){if(void 0!==e){if("string"!=typeof e)throw this.buildValidationError(`${t} must be a string`,[{path:t,message:`${t} must be a string`,rule:"invalid_format"}]);return e}}validateRemark(e,t){if("string"!=typeof e)throw this.buildValidationError("remark must be a string",[{path:t,message:"remark must be a string",rule:"invalid_format"}]);return e}buildValidationError(t,s){const r=s.some(e=>"invalid_format"===e.rule)?e.ERROR_CODES.VALIDATION_INVALID_FORMAT:e.ERROR_CODES.VALIDATION_REQUIRED;return new e.ValidationError(t,{code:r,details:{fields:s}})}async enrichBlocklistUsers(e){if(0===e.length||!this.requireClient().isUserInfoSyncEnabled())return e;const t=await c(e.map(e=>e.userId),{cacheManager:this.requireClient().getCacheManager(),fetchUserInfos:async({userIds:e})=>await this.fetchUserInfos(e)});return e.map(e=>t.get(e.userId)??e)}async fetchUserInfos(t){if(0===t.length)return[];try{const e=this.getUserInfoManager();return e?await e.getUserInfoByUserId({userIds:t}):await this.fetchUserInfosFromRest(t)}catch(s){return e.logger.warn("ContactManager user info fetch failed",{userIds:t,error:s}),[]}}async fetchUserInfosFromRest(e){const t=this.getRestContextOrThrow(),r=s.buildFetchUserInfoByUserIdRequest(e),a=await this.getRestClient(t).request(s.buildUserInfoFetchEndpoint(t),{method:"POST",body:r,operation:"getUserInfoByUserId"});return s.normalizeFetchedUserInfos(a,r.targets)}getUserInfoManager(){const e=this.requireClient();if(!this.hasUserInfoCapabilityProvider(e))return null;const t=e.getManagerByCapability("userInfo:read");return t&&this.hasUserInfoReadCapability(t)?t:null}hasUserInfoCapabilityProvider(e){return"function"==typeof e.getManagerByCapability}hasUserInfoReadCapability(e){return"function"==typeof e.getUserInfoByUserId}createSyncController(e){return new L(e)}};G.key="contactManager";let Y=G;exports.ContactManager=Y,exports.RosterMessageType=d,exports.resolveSingleContactUserInfo=async(e,t)=>((e,t,s)=>({userId:s,nickname:t?.nickname??e?.nickname,avatarUrl:t?.avatarUrl??e?.avatarUrl,mail:t?.mail??e?.mail,phone:t?.phone??e?.phone,gender:t?.gender??e?.gender,sign:t?.sign??e?.sign,birth:t?.birth??e?.birth,ext:t?.ext??e?.ext}))(void 0,(await c([e],t)).get(e),e);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{V as e,E as t,p as s,S as r,A as a,l as n,f as o,m as i,i as c}from"./common-D_DfwSd3.js";import{i as d}from"./cache-utils-B99glc0H.js";import{b as l,a as u,n as h}from"./user-info-DfbCp80h.js";import{a as p,b as g,L as m}from"./reflection-proto-codec-CjRraw85.js";import{l as y}from"./light-Dg9A1Xmd.js";const I=e=>({userId:e}),f=e=>({userId:e.userId,nickname:e.nickname,avatarUrl:e.avatarUrl,sign:e.sign,ext:e.ext}),C=e=>e,S=async(e,t)=>{const s=(e=>{const t=[],s=/* @__PURE__ */new Set;for(const r of e){const e=r.trim();e&&!s.has(e)&&(s.add(e),t.push(e))}return t})(e),r=/* @__PURE__ */new Map;if(0===s.length)return r;const a=t.cacheManager?.getUserInfoSummaries(s,!1)??[];for(const o of a)r.set(o.userId,f(o));const n=s.filter(e=>!r.has(e));if(n.length>0&&t.fetchUserInfos){const e=await t.fetchUserInfos({userIds:n});for(const t of e)r.set(t.userId,C(t))}for(const o of s)r.has(o)||r.set(o,I(o));return r},R=async(e,t)=>((e,t,s)=>({userId:s,nickname:t?.nickname??e?.nickname,avatarUrl:t?.avatarUrl??e?.avatarUrl,mail:t?.mail??e?.mail,phone:t?.phone??e?.phone,gender:t?.gender??e?.gender,sign:t?.sign??e?.sign,birth:t?.birth??e?.birth,ext:t?.ext??e?.ext}))(void 0,(await S([e],t)).get(e),e),v={UNSPECIFIED:0,PING:1,PONG:2,REQUEST:3,RESPONSE:4,ERROR:5},E=0,T=0,_=1,U=1001,w=1002,b=1003,k=1004,N=1005,A=1101,O=e=>{const{orgName:t,appName:r}=s(e.appKey);return{orgName:t,appName:r,encodedUserId:encodeURIComponent(e.userId),encodedResource:encodeURIComponent(e.clientResource)}},M=e=>d(e)&&Array.isArray(e.data)?e.data.filter(e=>"string"==typeof e&&e.length>0):Array.isArray(e)?e.filter(e=>"string"==typeof e&&e.length>0):[],q=(s,r)=>{if(!Array.isArray(s.userIds)||0===s.userIds.length)throw new e(`${r} is required`,{code:t.VALIDATION_REQUIRED,details:{fields:[{path:r,message:`${r} is required`,rule:"required"}]}});const a=s.userIds.map((s,a)=>{if("string"!=typeof s)throw new e(`${r}[${a}] must be a string`,{code:t.VALIDATION_INVALID_FORMAT,details:{fields:[{path:`${r}[${a}]`,message:"userId must be a string",rule:"invalid_format"}]}});return s.trim()}),n=(e=>{const t=[],s=/* @__PURE__ */new Set;for(const r of e)r&&!s.has(r)&&(s.add(r),t.push(r));return t})(a);if(0===n.length)throw new e(`${r} is required`,{code:t.VALIDATION_REQUIRED,details:{fields:[{path:r,message:`${r} is required`,rule:"required"}]}});return n.length!==a.length&&d(s),n},D=async(e,t)=>{const s=O(t),r=`/${s.orgName}/${s.appName}/users/${s.encodedUserId}/blocks/users`,a=await e.get(r,{operation:"getBlocklist"});return M(a).map(e=>({userId:e}))},$=async(e,t,s)=>{const r=O(t),a=`/${r.orgName}/${r.appName}/sdk/user/${r.encodedUserId}/blocks?resource=${r.encodedResource}`,n=await e.post(a,{usernames:s},{operation:"addUsersToBlocklist"});return{succeeded:M(n).map(e=>({userId:e})),failed:[]}},P={nested:{easemob:{nested:{imfusion:{nested:{gateway:{nested:{v1:{nested:{MessageType:{values:{MESSAGE_TYPE_UNSPECIFIED:0,MESSAGE_TYPE_PING:1,MESSAGE_TYPE_PONG:2,MESSAGE_TYPE_ROSTER_REQUEST:3,MESSAGE_TYPE_ROSTER_RESPONSE:4,MESSAGE_TYPE_ERROR:5}},ServerStatus:{values:{SERVER_STATUS_OK:0,SERVER_STATUS_BUSY:1}},RosterResponseType:{values:{ROSTER_RESPONSE_TYPE_UNSPECIFIED:0,ROSTER_RESPONSE_TYPE_INCREMENTAL:1,ROSTER_RESPONSE_TYPE_FULL:2}},BaseMessage:{fields:{type:{type:"MessageType",id:1}}},GatewayHeader:{fields:{resource:{type:"string",id:1},timestamp:{type:"int64",id:2},requestId:{type:"string",id:3},protocolVersion:{type:"int32",id:4}}},PingRequest:{fields:{type:{type:"MessageType",id:1}}},PongResponse:{fields:{type:{type:"MessageType",id:1},status:{type:"ServerStatus",id:2}}},ErrorDetail:{fields:{type:{type:"MessageType",id:1},code:{type:"string",id:2},message:{type:"string",id:3},header:{type:"GatewayHeader",id:4}}},GetRosterRequest:{fields:{type:{type:"MessageType",id:1},header:{type:"GatewayHeader",id:2},org:{type:"string",id:3},app:{type:"string",id:4},username:{type:"string",id:5},version:{type:"string",id:6},cursor:{type:"uint64",id:7}}},RosterItem:{fields:{contact:{type:"string",id:1},remark:{type:"string",id:2},metadata:{type:"string",id:3},createdAt:{type:"int64",id:4},updatedAt:{type:"int64",id:5},metadataUpdatedAt:{type:"int64",id:6}}},GetRosterResponse:{fields:{type:{type:"MessageType",id:1},header:{type:"GatewayHeader",id:2},data:{rule:"repeated",type:"RosterItem",id:3},cursor:{type:"uint64",id:4},version:{type:"string",id:5},responseType:{type:"RosterResponseType",id:6}}}}}}}}}}}}};let B=!1,F=null;const x=()=>F||(B||(y.util.Long=m,y.configure(),B=!0),p(),F=y.Root.fromJSON(P),g(F),F),L=e=>"number"==typeof e?e:m.isLong(e)?e.toNumber():0,V=e=>{if(!e||"object"!=typeof e)return;const t=e;return{resource:"string"==typeof t.resource?t.resource:"",timestamp:L(t.timestamp),requestId:"string"==typeof t.requestId?t.requestId:"",protocolVersion:L(t.protocolVersion)}};class G{encodeRequest(e){const t=x().lookupType("easemob.imfusion.gateway.v1.GetRosterRequest");return t.encode(t.create(e)).finish()}encodePong(e=E){const t=x().lookupType("easemob.imfusion.gateway.v1.PongResponse");return t.encode(t.create({type:v.PONG,status:e})).finish()}decode(e){const t=x(),s=t.lookupType("easemob.imfusion.gateway.v1.BaseMessage").decode(e);switch(s.type){case v.PING:return{type:v.PING};case v.PONG:{const s=t.lookupType("easemob.imfusion.gateway.v1.PongResponse").decode(e);return{type:v.PONG,status:L(s.status)}}case v.RESPONSE:{const s=t.lookupType("easemob.imfusion.gateway.v1.GetRosterResponse").decode(e);return{type:v.RESPONSE,header:V(s.header),data:Array.isArray(s.data)?s.data.map(e=>(e=>{const t=e&&"object"==typeof e?e:{};return{contact:"string"==typeof t.contact?t.contact:"",remark:"string"==typeof t.remark?t.remark:"",metadata:"string"==typeof t.metadata?t.metadata:"",createdAt:L(t.createdAt),updatedAt:L(t.updatedAt),metadataUpdatedAt:L(t.metadataUpdatedAt)}})(e)):[],cursor:L(s.cursor),version:"string"==typeof s.version?s.version:"",responseType:L(s.responseType)||T}}case v.ERROR:{const s=t.lookupType("easemob.imfusion.gateway.v1.ErrorDetail").decode(e);return{type:v.ERROR,header:V(s.header),code:"string"==typeof s.code?s.code:"",message:"string"==typeof s.message?s.message:"Unknown roster error"}}default:return{type:"number"==typeof s.type?s.type:v.UNSPECIFIED}}}}class Y{constructor(e){this.pages=[],this.responseType=null,this.version="",this.nextCursor=0,this.pageCount=0,this.completed=!1,this.requestId=e}push(e){const s=e.header?.requestId;if(s&&s!==this.requestId)throw new r("Roster response requestId mismatched",t.CONTACT_SYNC_PROTO_DECODE_FAILED,{details:{stage:"response_decode",expectedRequestId:this.requestId,receivedRequestId:s}});if(this.completed)throw new r("Roster response received after completion",t.CONTACT_SYNC_CURSOR_INVALID,{details:{cursor:e.cursor}});if(null!==this.responseType&&this.responseType!==e.responseType)throw new r("Roster response type changed in same session",t.CONTACT_SYNC_CURSOR_INVALID,{details:{expected:this.responseType,received:e.responseType}});if(this.pages.length>0&&0!==e.cursor&&e.cursor===this.pages[this.pages.length-1]?.cursor)throw new r("Roster cursor duplicated",t.CONTACT_SYNC_CURSOR_INVALID,{details:{cursor:e.cursor}});return this.responseType=e.responseType,this.version=e.version||this.version,this.pages.push(e),this.nextCursor=e.cursor,this.pageCount+=1,this.completed=0===e.cursor,{done:this.completed,nextCursor:this.nextCursor,pageCount:this.pageCount}}getNextCursor(){return this.nextCursor}getPageCount(){return this.pageCount}hasPages(){return this.pages.length>0}isCompleted(){return this.completed}buildResult(){return{mode:this.responseType===_?"incremental":"full",version:this.version,pages:this.pages}}}const H=e=>e.type===v.RESPONSE,K=e=>"message"in e&&"code"in e;class W{constructor(e){this.codec=new G,this.sharedSession=e}async sync(e){const t=new Y(e.request.header.requestId);return await this.syncWithSharedSession(e.request,t)}cancel(){this.sharedSession.cancel("contact-sync-cancelled")}async syncWithSharedSession(e,s){return await this.sharedSession.request({dataType:"contact",label:"Roster sync",requestId:e.header.requestId,encode:()=>{const t=this.buildAttemptRequest(e,s.getNextCursor());return this.codec.encodeRequest(t)},decode:e=>{const t=this.codec.decode(e);return{type:t.type,requestId:H(t)||K(t)?t.header?.requestId:void 0,frame:t}},onFrame:async(e,n)=>{try{if(e.type===v.PING)return void(await n.send(this.codec.encodePong()));if(H(e)){if(!s.push(e).done)return;return{done:!0,result:s.buildResult()}}if(K(e))throw(e=>{const s=e.header?.requestId,n=t=>({stage:"sync_page",serverCode:e.code,requestId:s,retryable:t});switch(Number.parseInt(e.code,10)){case w:return new a(e.message,{code:t.AUTH_UNAUTHORIZED,details:n(!1)});case b:return new r(e.message,t.SERVICE_LIMIT_EXCEEDED,{details:n(!0)});case U:return new r(e.message,t.VALIDATION_REQUIRED,{details:n(!1)});case k:return new r(e.message,t.VALIDATION_INVALID_FORMAT,{details:n(!1)});case N:return new r(e.message,t.REST_BUSINESS_UNKNOWN,{details:n(!0)});case A:return new r(e.message,t.CONTACT_SYNC_SOCKET_FAILED,{details:n(!1)});default:return new r(e.message,t.CONTACT_SYNC_SOCKET_FAILED,{details:n(!0)})}})(e);return}catch(o){throw o instanceof r?o:new r("Roster frame decode failed",t.CONTACT_SYNC_PROTO_DECODE_FAILED,{details:{stage:"response_decode",cause:o instanceof Error?o.message:String(o)}})}}})}buildAttemptRequest(e,t){return{...e,cursor:t,header:{...e.header,timestamp:Date.now(),requestId:e.header.requestId}}}}const j=e=>e.versionState.version?"incremental":"full",Q=e=>{const{metadata:t,metadataFailed:s,state:r}=e,a=r.versionState.version;return s||!t?{decision:"complete"===r.cacheMeta.cacheIntegrity?j(r):"full",version:a}:t.requiresSync||"complete"!==r.cacheMeta.cacheIntegrity?t.requiresSync&&"complete"===r.cacheMeta.cacheIntegrity&&a?{decision:"incremental",version:t.version||a}:{decision:"full",version:t.version||a}:{decision:"skip",version:t.version||a}},z=e=>{if(!e)return{};try{const t=JSON.parse(e);return{nickname:"string"==typeof t.nickname?t.nickname:void 0,avatarUrl:"string"==typeof t.avatarUrl?t.avatarUrl:"string"==typeof t.avatarurl?t.avatarurl:void 0,sign:"string"==typeof t.sign?t.sign:void 0,ext:"string"==typeof t.ext?t.ext:void 0}}catch{return{}}},J=e=>{const t=(e=>{if(!(e instanceof r&&e.details))return null;const t=e.details.httpStatus;return"number"==typeof t?t:null})(e);return 401===t||403===t||404===t},X=(e,t,s,r)=>({code:t,stage:e,message:`${e}: ${s}`,retryable:r}),Z=e=>{n.warn("Contact sync duration",e)};class ee{constructor(e){this.running=null,this.dependencies=e}async sync(){if(this.running)return await this.running;this.running=this.runSync();try{await this.running}finally{this.running=null}}cancel(){this.dependencies.getSharedSyncSession().cancel("contact-sync-cancelled")}async runSync(){const e=this.dependencies.getContextState(),s=Date.now();let a;this.dependencies.onStart();try{const t=await this.dependencies.queryMetadata(e.versionState.version);if(a=Q({metadata:t,state:e}),"skip"===a.decision)return this.dependencies.onFinish(),void Z({outcome:"skip",decision:a.decision,durationMs:Date.now()-s,version:a.version,hasUsableSnapshot:e.cachedSnapshot.complete})}catch(n){if(J(n)){const a=Q({metadataFailed:!0,state:e}),o=n instanceof r?n:new r("Contact metadata request failed",t.CONTACT_SYNC_METADATA_FAILED,{details:{stage:"metadata"}});return this.dependencies.onFinish({error:X("metadata",o.code,o.message,!1)}),void Z({outcome:"fail",decision:a.decision,durationMs:Date.now()-s,version:e.versionState.version,stage:"metadata",hasUsableSnapshot:e.cachedSnapshot.complete,source:e.cachedSnapshot.complete?e.cachedSnapshot.source:void 0})}if(a=Q({metadataFailed:!0,state:e}),e.cachedSnapshot.complete)return this.dependencies.onFinish({error:X("metadata",t.CONTACT_SYNC_METADATA_FAILED,n instanceof Error?n.message:String(n),!0)}),void Z({outcome:"fail",decision:a.decision,durationMs:Date.now()-s,version:a.version,stage:"metadata",hasUsableSnapshot:!0,source:e.cachedSnapshot.source})}try{const t=await this.dependencies.getSyncUrls(),r=this.dependencies.buildRosterRequest({decision:a.decision,version:e.versionState.version}),n=await new W(this.dependencies.getSharedSyncSession()).sync({urls:t,request:r}),o=(e=>{const t=[];for(const s of e)for(const e of s.data){const s=z(e.metadata);t.push({relation:{userId:e.contact,remark:e.remark,sign:s.sign??"",addTs:e.createdAt,updatedAt:e.updatedAt,metadataUpdatedAt:e.metadataUpdatedAt},userInfo:{userId:e.contact,nickname:s.nickname,avatarUrl:s.avatarUrl,sign:s.sign,ext:s.ext}})}return t})(n.pages),i=this.dependencies.applySyncResult({mode:n.mode,relations:o.map(e=>e.relation),userInfos:o.map(e=>e.userInfo),version:n.version,lastSyncTs:Date.now()});this.dependencies.onFinish(),Z({outcome:"finish",decision:a.decision,durationMs:Date.now()-s,version:n.version,source:"sync",changed:i.changed,hasUsableSnapshot:i.snapshot.complete})}catch(n){const o=n instanceof r?n:new r("Contact sync failed",t.CONTACT_SYNC_SOCKET_FAILED,{details:{stage:"sync_page",cause:n instanceof Error?n.message:String(n)}}),i=o.details??{},c="string"==typeof i.stage?i.stage:"sync_page";this.dependencies.onFinish({error:X(c,o.code,o.message,!0)}),Z({outcome:"fail",decision:a.decision,durationMs:Date.now()-s,version:a.version,stage:c,hasUsableSnapshot:e.cachedSnapshot.complete,source:e.cachedSnapshot.complete?e.cachedSnapshot.source:void 0})}}}const te={items:[],loaded:!1,source:"server"},se=i(c,{common:{},apis:{getContactList:{range:"",errors:{}},addContact:{range:"110,204,210,1000,1001,1002",localErrors:{addContact:{validation_invalid:{code:110,retryable:!1}}},errors:{USER_NOT_FOUND:{code:204,httpStatus:404,retryable:!1},ALREADY_FRIEND:{code:1e3,retryable:!1},BLOCKED_BY_USER:{code:210,retryable:!1},CONTACT_REACH_LIMIT:{code:1001,httpStatus:403,retryable:!1,matchField:"error_description",matchPattern:"Inviter's contact max count"},CONTACT_REACH_LIMIT_PEER:{code:1002,httpStatus:403,retryable:!1,matchField:"error_description",matchPattern:"Invitee's contact max count"}}},deleteContact:{range:"110,204",localErrors:{deleteContact:{validation_invalid:{code:110,retryable:!1}}},errors:{USER_NOT_FOUND:{code:204,httpStatus:404,retryable:!1}}},acceptContactInvite:{range:"110,204,1001,1002",localErrors:{acceptContactInvite:{validation_invalid:{code:110,retryable:!1}}},errors:{USER_NOT_FOUND:{code:204,httpStatus:404,retryable:!1},CONTACT_REACH_LIMIT:{code:1001,httpStatus:403,retryable:!1,matchField:"error_description",matchPattern:"Inviter's contact max count"},CONTACT_REACH_LIMIT_PEER:{code:1002,httpStatus:403,retryable:!1,matchField:"error_description",matchPattern:"Invitee's contact max count"}}},declineContactInvite:{range:"110,204",localErrors:{declineContactInvite:{validation_invalid:{code:110,retryable:!1}}},errors:{USER_NOT_FOUND:{code:204,httpStatus:404,retryable:!1}}},setContactRemark:{range:"4,110,223",localErrors:{setContactRemark:{validation_invalid:{code:110,retryable:!1}}},errors:{illegal_argument:{code:223,httpStatus:400,retryable:!1,matchField:"error_description",matchPattern:"please add as a friend first"},remark_length_exceeded:{code:4,httpStatus:400,retryable:!1,matchField:"error_description",matchPattern:"remark length must less than"}}},getBlocklist:{range:"",errors:{}},addUsersToBlocklist:{range:"4,110,204",localErrors:{addUsersToBlocklist:{validation_invalid:{code:110,retryable:!1}}},errors:{service_resource_not_found:{code:204,httpStatus:404,retryable:!1},blocklist_limit_exceeded:{code:4,httpStatus:400,retryable:!1,matchField:"error_description",matchPattern:"almost reached or been greater than the upper range"}}},removeUserFromBlocklist:{range:"110",localErrors:{removeUserFromBlocklist:{validation_invalid:{code:110,retryable:!1}}},errors:{}}}}),re=class{constructor(){this.client=null,this.eventContext=null,this.restClient=null,this.restBaseUrl=null,this.restToken=null,this.blocklistSnapshot=te,this.blocklistSessionKey=null}bind(e,t){this.client=e,this.eventContext=t??null,this.blocklistSnapshot=te,this.blocklistSessionKey=null}getContacts(){return this.client?.getContactSnapshot()?.items??[]}async addContact(e){return this.runOperation("addContact",async()=>{const t=this.validateUserId(e.userId,"params.userId"),s=this.validateOptionalString(e.message,"params.message"),r=this.getRestContextOrThrow(),a=this.getRestClient(r);n.debug("ContactManager addContact",{userId:t,hasMessage:"string"==typeof s&&s.length>0}),await(async(e,t,s)=>{const r=O(t),a=`/${r.orgName}/${r.appName}/users/${r.encodedUserId}/contacts/apply?resource=${r.encodedResource}`;await e.post(a,{usernames:[s.userId],reason:s.message??""},{operation:"addContact"})})(a,r,{userId:t,message:s})})}async deleteContact(e){return this.runOperation("deleteContact",async()=>{const t=this.validateUserId(e.userId,"params.userId"),s=this.getRestContextOrThrow(),r=this.getRestClient(s);n.debug("ContactManager deleteContact",{userId:t}),await(async(e,t,s)=>{const r=O(t),a=`/${r.orgName}/${r.appName}/users/${r.encodedUserId}/contacts/users/${encodeURIComponent(s.userId)}?resource=${r.encodedResource}`;await e.delete(a,{operation:"deleteContact"})})(r,s,{userId:t});const a=this.client?.getCacheManager()?.removeContact(t);n.debug("ContactManager deleteContact patched cache",{userId:t,changed:a?.changed??!1})})}async acceptContactInvite(e){return this.runOperation("acceptContactInvite",async()=>{const t=this.validateUserId(e.userId,"params.userId"),s=this.getRestContextOrThrow(),r=this.getRestClient(s);n.debug("ContactManager acceptContactInvite",{userId:t}),await(async(e,t,s)=>{const r=O(t),a=`/${r.orgName}/${r.appName}/users/${r.encodedUserId}/contacts/accept/users/${encodeURIComponent(s.userId)}?resource=${r.encodedResource}`;await e.post(a,void 0,{operation:"acceptContactInvite"})})(r,s,{userId:t}),await this.requireClient().refreshContactSnapshot()})}async declineContactInvite(e){return this.runOperation("declineContactInvite",async()=>{const t=this.validateUserId(e.userId,"params.userId"),s=this.getRestContextOrThrow(),r=this.getRestClient(s);n.debug("ContactManager declineContactInvite",{userId:t}),await(async(e,t,s)=>{const r=O(t),a=`/${r.orgName}/${r.appName}/users/${r.encodedUserId}/contacts/decline/users/${encodeURIComponent(s.userId)}?resource=${r.encodedResource}`;await e.post(a,void 0,{operation:"declineContactInvite"})})(r,s,{userId:t})})}async setContactRemark(e){return this.runOperation("setContactRemark",async()=>{const t=this.validateUserId(e.userId,"params.userId"),s=this.validateRemark(e.remark,"params.remark"),r=this.getRestContextOrThrow(),a=this.getRestClient(r);n.debug("ContactManager setContactRemark",{userId:t,remarkLength:s.length}),await(async(e,t,s)=>{const r=O(t),a=`/${r.orgName}/${r.appName}/users/${r.encodedUserId}/contacts/users/${encodeURIComponent(s.userId)}?resource=${r.encodedResource}`;await e.put(a,{remark:s.remark},{operation:"setContactRemark"})})(a,r,{userId:t,remark:s});const o=this.client?.getCacheManager()?.updateContactRemark(t,s);this.client?.refreshConversationDisplayFromUserInfos([{userId:t}],"profile"),n.debug("ContactManager setContactRemark patched cache",{userId:t,changed:o?.changed??!1})})}async getBlocklist(){return this.runOperation("getBlocklist",async()=>{const e=this.getRestContextOrThrow();this.ensureBlocklistSession(e);const t=this.getRestClient(e);if(this.blocklistSnapshot.loaded)return this.blocklistSnapshot.items;const s=await this.enrichBlocklistUsers(await D(t,e));return this.blocklistSnapshot={items:s,loaded:!0,source:"server"},n.debug("ContactManager getBlocklist",{count:s.length}),s})}async addUsersToBlocklist(e){return this.runOperation("addUsersToBlocklist",async()=>{const t=this.getRestContextOrThrow();this.ensureBlocklistSession(t);const s=q(e,"params.userIds"),r=this.getRestClient(t);n.debug("ContactManager addUsersToBlocklist",{userIds:s,inputCount:e.userIds.length,normalizedCount:s.length});const a=await $(r,t,s),o=await this.enrichBlocklistUsers(a.succeeded);return this.blocklistSnapshot=this.patchBlocklistSnapshotWithAdditions(o),{succeeded:o,failed:await this.enrichBlocklistUsers(a.failed)}})}async removeUserFromBlocklist(e){return this.runOperation("removeUserFromBlocklist",async()=>{const t=this.getRestContextOrThrow();this.ensureBlocklistSession(t);const s=q(e,"params.userIds"),r=this.getRestClient(t);n.debug("ContactManager removeUserFromBlocklist",{userIds:s,inputCount:e.userIds.length,normalizedCount:s.length}),await(async(e,t,s)=>{const r=O(t),a=`/${r.orgName}/${r.appName}/sdk/user/${r.encodedUserId}/blocks?resource=${r.encodedResource}`;await e.request(a,{method:"DELETE",body:{usernames:s},operation:"removeUserFromBlocklist"})})(r,t,s),this.blocklistSnapshot=this.patchBlocklistSnapshotWithRemovals(s)})}addEventHandler(e,t){this.eventContext?.addEventHandler(e,t)}removeEventHandler(e){this.eventContext?.removeEventHandler(e)}async runOperation(e,t){try{return await t()}catch(s){const t=this.normalizeSdkError(e,s);throw n.warn(`ContactManager ${e} failed`,{code:t.code,message:t.message,details:t.details}),t}}normalizeSdkError(e,s){return s instanceof r?s:s instanceof Error?new r(`ContactManager ${e} failed: ${s.message}`,t.UNKNOWN):new r(`ContactManager ${e} failed`,t.UNKNOWN)}requireClient(){if(!this.client)throw this.buildValidationError("ContactManager is not bound to client",[{path:"contactManager.client",message:"ContactManager is not bound to client",rule:"required"}]);return this.client}getRestContextOrThrow(){return this.requireClient().getRestContext()}getRestClient(e){return this.restClient&&this.restBaseUrl===e.restBaseUrl&&this.restToken===e.token||(this.restClient=new o(e.restBaseUrl,{errorMap:se,requestAdapter:this.requireClient().getRequestAdapter?.(),includeRequestId:!0}),this.restClient.setAuthToken(e.token),this.restBaseUrl=e.restBaseUrl,this.restToken=e.token),this.restClient}ensureBlocklistSession(e){const t=`${e.restBaseUrl}:${e.userId}:${e.token}`;this.blocklistSessionKey!==t&&(this.blocklistSessionKey=t,this.blocklistSnapshot=te)}patchBlocklistSnapshotWithAdditions(e){const t=new Map(this.blocklistSnapshot.items.map(e=>[e.userId,e]));for(const s of e)t.set(s.userId,s);return{items:Array.from(t.values()),loaded:this.blocklistSnapshot.loaded,source:"mutation_patch"}}patchBlocklistSnapshotWithRemovals(e){const t=new Map(this.blocklistSnapshot.items.map(e=>[e.userId,e]));for(const s of e)t.delete(s);return{items:Array.from(t.values()),loaded:this.blocklistSnapshot.loaded,source:"mutation_patch"}}validateUserId(e,t){if("string"!=typeof e)throw this.buildValidationError("userId must be a string",[{path:t,message:"userId must be a string",rule:"invalid_format"}]);const s=e.trim();if(!s)throw this.buildValidationError("userId is required",[{path:t,message:"userId is required",rule:"required"}]);return s}validateOptionalString(e,t){if(void 0!==e){if("string"!=typeof e)throw this.buildValidationError(`${t} must be a string`,[{path:t,message:`${t} must be a string`,rule:"invalid_format"}]);return e}}validateRemark(e,t){if("string"!=typeof e)throw this.buildValidationError("remark must be a string",[{path:t,message:"remark must be a string",rule:"invalid_format"}]);return e}buildValidationError(s,r){const a=r.some(e=>"invalid_format"===e.rule)?t.VALIDATION_INVALID_FORMAT:t.VALIDATION_REQUIRED;return new e(s,{code:a,details:{fields:r}})}async enrichBlocklistUsers(e){if(0===e.length||!this.requireClient().isUserInfoSyncEnabled())return e;const t=await S(e.map(e=>e.userId),{cacheManager:this.requireClient().getCacheManager(),fetchUserInfos:async({userIds:e})=>await this.fetchUserInfos(e)});return e.map(e=>t.get(e.userId)??e)}async fetchUserInfos(e){if(0===e.length)return[];try{const t=this.getUserInfoManager();return t?await t.getUserInfoByUserId({userIds:e}):await this.fetchUserInfosFromRest(e)}catch(t){return n.warn("ContactManager user info fetch failed",{userIds:e,error:t}),[]}}async fetchUserInfosFromRest(e){const t=this.getRestContextOrThrow(),s=l(e),r=await this.getRestClient(t).request(u(t),{method:"POST",body:s,operation:"getUserInfoByUserId"});return h(r,s.targets)}getUserInfoManager(){const e=this.requireClient();if(!this.hasUserInfoCapabilityProvider(e))return null;const t=e.getManagerByCapability("userInfo:read");return t&&this.hasUserInfoReadCapability(t)?t:null}hasUserInfoCapabilityProvider(e){return"function"==typeof e.getManagerByCapability}hasUserInfoReadCapability(e){return"function"==typeof e.getUserInfoByUserId}createSyncController(e){return new ee(e)}};re.key="contactManager";let ae=re;export{ae as C,v as R,R as r};
|
|
1
|
+
import{V as e,E as t,p as s,S as r,A as a,l as n,f as o,m as i,i as c}from"./common-D_DfwSd3.js";import{i as d}from"./cache-utils-B99glc0H.js";import{b as l,a as u,n as h}from"./user-info-DfbCp80h.js";import{a as p,b as g,L as m}from"./reflection-proto-codec-7r8Sei3y.js";import{l as y}from"./light-DImBnNes.js";const I=e=>({userId:e}),f=e=>({userId:e.userId,nickname:e.nickname,avatarUrl:e.avatarUrl,sign:e.sign,ext:e.ext}),C=e=>e,S=async(e,t)=>{const s=(e=>{const t=[],s=/* @__PURE__ */new Set;for(const r of e){const e=r.trim();e&&!s.has(e)&&(s.add(e),t.push(e))}return t})(e),r=/* @__PURE__ */new Map;if(0===s.length)return r;const a=t.cacheManager?.getUserInfoSummaries(s,!1)??[];for(const o of a)r.set(o.userId,f(o));const n=s.filter(e=>!r.has(e));if(n.length>0&&t.fetchUserInfos){const e=await t.fetchUserInfos({userIds:n});for(const t of e)r.set(t.userId,C(t))}for(const o of s)r.has(o)||r.set(o,I(o));return r},R=async(e,t)=>((e,t,s)=>({userId:s,nickname:t?.nickname??e?.nickname,avatarUrl:t?.avatarUrl??e?.avatarUrl,mail:t?.mail??e?.mail,phone:t?.phone??e?.phone,gender:t?.gender??e?.gender,sign:t?.sign??e?.sign,birth:t?.birth??e?.birth,ext:t?.ext??e?.ext}))(void 0,(await S([e],t)).get(e),e),v={UNSPECIFIED:0,PING:1,PONG:2,REQUEST:3,RESPONSE:4,ERROR:5},E=0,T=0,_=1,U=1001,w=1002,b=1003,k=1004,N=1005,A=1101,O=e=>{const{orgName:t,appName:r}=s(e.appKey);return{orgName:t,appName:r,encodedUserId:encodeURIComponent(e.userId),encodedResource:encodeURIComponent(e.clientResource)}},M=e=>d(e)&&Array.isArray(e.data)?e.data.filter(e=>"string"==typeof e&&e.length>0):Array.isArray(e)?e.filter(e=>"string"==typeof e&&e.length>0):[],q=(s,r)=>{if(!Array.isArray(s.userIds)||0===s.userIds.length)throw new e(`${r} is required`,{code:t.VALIDATION_REQUIRED,details:{fields:[{path:r,message:`${r} is required`,rule:"required"}]}});const a=s.userIds.map((s,a)=>{if("string"!=typeof s)throw new e(`${r}[${a}] must be a string`,{code:t.VALIDATION_INVALID_FORMAT,details:{fields:[{path:`${r}[${a}]`,message:"userId must be a string",rule:"invalid_format"}]}});return s.trim()}),n=(e=>{const t=[],s=/* @__PURE__ */new Set;for(const r of e)r&&!s.has(r)&&(s.add(r),t.push(r));return t})(a);if(0===n.length)throw new e(`${r} is required`,{code:t.VALIDATION_REQUIRED,details:{fields:[{path:r,message:`${r} is required`,rule:"required"}]}});return n.length!==a.length&&d(s),n},D=async(e,t)=>{const s=O(t),r=`/${s.orgName}/${s.appName}/users/${s.encodedUserId}/blocks/users`,a=await e.get(r,{operation:"getBlocklist"});return M(a).map(e=>({userId:e}))},$=async(e,t,s)=>{const r=O(t),a=`/${r.orgName}/${r.appName}/sdk/user/${r.encodedUserId}/blocks?resource=${r.encodedResource}`,n=await e.post(a,{usernames:s},{operation:"addUsersToBlocklist"});return{succeeded:M(n).map(e=>({userId:e})),failed:[]}},P={nested:{easemob:{nested:{imfusion:{nested:{gateway:{nested:{v1:{nested:{MessageType:{values:{MESSAGE_TYPE_UNSPECIFIED:0,MESSAGE_TYPE_PING:1,MESSAGE_TYPE_PONG:2,MESSAGE_TYPE_ROSTER_REQUEST:3,MESSAGE_TYPE_ROSTER_RESPONSE:4,MESSAGE_TYPE_ERROR:5}},ServerStatus:{values:{SERVER_STATUS_OK:0,SERVER_STATUS_BUSY:1}},RosterResponseType:{values:{ROSTER_RESPONSE_TYPE_UNSPECIFIED:0,ROSTER_RESPONSE_TYPE_INCREMENTAL:1,ROSTER_RESPONSE_TYPE_FULL:2}},BaseMessage:{fields:{type:{type:"MessageType",id:1}}},GatewayHeader:{fields:{resource:{type:"string",id:1},timestamp:{type:"int64",id:2},requestId:{type:"string",id:3},protocolVersion:{type:"int32",id:4}}},PingRequest:{fields:{type:{type:"MessageType",id:1}}},PongResponse:{fields:{type:{type:"MessageType",id:1},status:{type:"ServerStatus",id:2}}},ErrorDetail:{fields:{type:{type:"MessageType",id:1},code:{type:"string",id:2},message:{type:"string",id:3},header:{type:"GatewayHeader",id:4}}},GetRosterRequest:{fields:{type:{type:"MessageType",id:1},header:{type:"GatewayHeader",id:2},org:{type:"string",id:3},app:{type:"string",id:4},username:{type:"string",id:5},version:{type:"string",id:6},cursor:{type:"uint64",id:7}}},RosterItem:{fields:{contact:{type:"string",id:1},remark:{type:"string",id:2},metadata:{type:"string",id:3},createdAt:{type:"int64",id:4},updatedAt:{type:"int64",id:5},metadataUpdatedAt:{type:"int64",id:6}}},GetRosterResponse:{fields:{type:{type:"MessageType",id:1},header:{type:"GatewayHeader",id:2},data:{rule:"repeated",type:"RosterItem",id:3},cursor:{type:"uint64",id:4},version:{type:"string",id:5},responseType:{type:"RosterResponseType",id:6}}}}}}}}}}}}};let B=!1,F=null;const x=()=>F||(B||(y.util.Long=m,y.configure(),B=!0),p(),F=y.Root.fromJSON(P),g(F),F),L=e=>"number"==typeof e?e:m.isLong(e)?e.toNumber():0,V=e=>{if(!e||"object"!=typeof e)return;const t=e;return{resource:"string"==typeof t.resource?t.resource:"",timestamp:L(t.timestamp),requestId:"string"==typeof t.requestId?t.requestId:"",protocolVersion:L(t.protocolVersion)}};class G{encodeRequest(e){const t=x().lookupType("easemob.imfusion.gateway.v1.GetRosterRequest");return t.encode(t.create(e)).finish()}encodePong(e=E){const t=x().lookupType("easemob.imfusion.gateway.v1.PongResponse");return t.encode(t.create({type:v.PONG,status:e})).finish()}decode(e){const t=x(),s=t.lookupType("easemob.imfusion.gateway.v1.BaseMessage").decode(e);switch(s.type){case v.PING:return{type:v.PING};case v.PONG:{const s=t.lookupType("easemob.imfusion.gateway.v1.PongResponse").decode(e);return{type:v.PONG,status:L(s.status)}}case v.RESPONSE:{const s=t.lookupType("easemob.imfusion.gateway.v1.GetRosterResponse").decode(e);return{type:v.RESPONSE,header:V(s.header),data:Array.isArray(s.data)?s.data.map(e=>(e=>{const t=e&&"object"==typeof e?e:{};return{contact:"string"==typeof t.contact?t.contact:"",remark:"string"==typeof t.remark?t.remark:"",metadata:"string"==typeof t.metadata?t.metadata:"",createdAt:L(t.createdAt),updatedAt:L(t.updatedAt),metadataUpdatedAt:L(t.metadataUpdatedAt)}})(e)):[],cursor:L(s.cursor),version:"string"==typeof s.version?s.version:"",responseType:L(s.responseType)||T}}case v.ERROR:{const s=t.lookupType("easemob.imfusion.gateway.v1.ErrorDetail").decode(e);return{type:v.ERROR,header:V(s.header),code:"string"==typeof s.code?s.code:"",message:"string"==typeof s.message?s.message:"Unknown roster error"}}default:return{type:"number"==typeof s.type?s.type:v.UNSPECIFIED}}}}class Y{constructor(e){this.pages=[],this.responseType=null,this.version="",this.nextCursor=0,this.pageCount=0,this.completed=!1,this.requestId=e}push(e){const s=e.header?.requestId;if(s&&s!==this.requestId)throw new r("Roster response requestId mismatched",t.CONTACT_SYNC_PROTO_DECODE_FAILED,{details:{stage:"response_decode",expectedRequestId:this.requestId,receivedRequestId:s}});if(this.completed)throw new r("Roster response received after completion",t.CONTACT_SYNC_CURSOR_INVALID,{details:{cursor:e.cursor}});if(null!==this.responseType&&this.responseType!==e.responseType)throw new r("Roster response type changed in same session",t.CONTACT_SYNC_CURSOR_INVALID,{details:{expected:this.responseType,received:e.responseType}});if(this.pages.length>0&&0!==e.cursor&&e.cursor===this.pages[this.pages.length-1]?.cursor)throw new r("Roster cursor duplicated",t.CONTACT_SYNC_CURSOR_INVALID,{details:{cursor:e.cursor}});return this.responseType=e.responseType,this.version=e.version||this.version,this.pages.push(e),this.nextCursor=e.cursor,this.pageCount+=1,this.completed=0===e.cursor,{done:this.completed,nextCursor:this.nextCursor,pageCount:this.pageCount}}getNextCursor(){return this.nextCursor}getPageCount(){return this.pageCount}hasPages(){return this.pages.length>0}isCompleted(){return this.completed}buildResult(){return{mode:this.responseType===_?"incremental":"full",version:this.version,pages:this.pages}}}const H=e=>e.type===v.RESPONSE,K=e=>"message"in e&&"code"in e;class W{constructor(e){this.codec=new G,this.sharedSession=e}async sync(e){const t=new Y(e.request.header.requestId);return await this.syncWithSharedSession(e.request,t)}cancel(){this.sharedSession.cancel("contact-sync-cancelled")}async syncWithSharedSession(e,s){return await this.sharedSession.request({dataType:"contact",label:"Roster sync",requestId:e.header.requestId,encode:()=>{const t=this.buildAttemptRequest(e,s.getNextCursor());return this.codec.encodeRequest(t)},decode:e=>{const t=this.codec.decode(e);return{type:t.type,requestId:H(t)||K(t)?t.header?.requestId:void 0,frame:t}},onFrame:async(e,n)=>{try{if(e.type===v.PING)return void(await n.send(this.codec.encodePong()));if(H(e)){if(!s.push(e).done)return;return{done:!0,result:s.buildResult()}}if(K(e))throw(e=>{const s=e.header?.requestId,n=t=>({stage:"sync_page",serverCode:e.code,requestId:s,retryable:t});switch(Number.parseInt(e.code,10)){case w:return new a(e.message,{code:t.AUTH_UNAUTHORIZED,details:n(!1)});case b:return new r(e.message,t.SERVICE_LIMIT_EXCEEDED,{details:n(!0)});case U:return new r(e.message,t.VALIDATION_REQUIRED,{details:n(!1)});case k:return new r(e.message,t.VALIDATION_INVALID_FORMAT,{details:n(!1)});case N:return new r(e.message,t.REST_BUSINESS_UNKNOWN,{details:n(!0)});case A:return new r(e.message,t.CONTACT_SYNC_SOCKET_FAILED,{details:n(!1)});default:return new r(e.message,t.CONTACT_SYNC_SOCKET_FAILED,{details:n(!0)})}})(e);return}catch(o){throw o instanceof r?o:new r("Roster frame decode failed",t.CONTACT_SYNC_PROTO_DECODE_FAILED,{details:{stage:"response_decode",cause:o instanceof Error?o.message:String(o)}})}}})}buildAttemptRequest(e,t){return{...e,cursor:t,header:{...e.header,timestamp:Date.now(),requestId:e.header.requestId}}}}const j=e=>e.versionState.version?"incremental":"full",Q=e=>{const{metadata:t,metadataFailed:s,state:r}=e,a=r.versionState.version;return s||!t?{decision:"complete"===r.cacheMeta.cacheIntegrity?j(r):"full",version:a}:t.requiresSync||"complete"!==r.cacheMeta.cacheIntegrity?t.requiresSync&&"complete"===r.cacheMeta.cacheIntegrity&&a?{decision:"incremental",version:t.version||a}:{decision:"full",version:t.version||a}:{decision:"skip",version:t.version||a}},z=e=>{if(!e)return{};try{const t=JSON.parse(e);return{nickname:"string"==typeof t.nickname?t.nickname:void 0,avatarUrl:"string"==typeof t.avatarUrl?t.avatarUrl:"string"==typeof t.avatarurl?t.avatarurl:void 0,sign:"string"==typeof t.sign?t.sign:void 0,ext:"string"==typeof t.ext?t.ext:void 0}}catch{return{}}},J=e=>{const t=(e=>{if(!(e instanceof r&&e.details))return null;const t=e.details.httpStatus;return"number"==typeof t?t:null})(e);return 401===t||403===t||404===t},X=(e,t,s,r)=>({code:t,stage:e,message:`${e}: ${s}`,retryable:r}),Z=e=>{n.warn("Contact sync duration",e)};class ee{constructor(e){this.running=null,this.dependencies=e}async sync(){if(this.running)return await this.running;this.running=this.runSync();try{await this.running}finally{this.running=null}}cancel(){this.dependencies.getSharedSyncSession().cancel("contact-sync-cancelled")}async runSync(){const e=this.dependencies.getContextState(),s=Date.now();let a;this.dependencies.onStart();try{const t=await this.dependencies.queryMetadata(e.versionState.version);if(a=Q({metadata:t,state:e}),"skip"===a.decision)return this.dependencies.onFinish(),void Z({outcome:"skip",decision:a.decision,durationMs:Date.now()-s,version:a.version,hasUsableSnapshot:e.cachedSnapshot.complete})}catch(n){if(J(n)){const a=Q({metadataFailed:!0,state:e}),o=n instanceof r?n:new r("Contact metadata request failed",t.CONTACT_SYNC_METADATA_FAILED,{details:{stage:"metadata"}});return this.dependencies.onFinish({error:X("metadata",o.code,o.message,!1)}),void Z({outcome:"fail",decision:a.decision,durationMs:Date.now()-s,version:e.versionState.version,stage:"metadata",hasUsableSnapshot:e.cachedSnapshot.complete,source:e.cachedSnapshot.complete?e.cachedSnapshot.source:void 0})}if(a=Q({metadataFailed:!0,state:e}),e.cachedSnapshot.complete)return this.dependencies.onFinish({error:X("metadata",t.CONTACT_SYNC_METADATA_FAILED,n instanceof Error?n.message:String(n),!0)}),void Z({outcome:"fail",decision:a.decision,durationMs:Date.now()-s,version:a.version,stage:"metadata",hasUsableSnapshot:!0,source:e.cachedSnapshot.source})}try{const t=await this.dependencies.getSyncUrls(),r=this.dependencies.buildRosterRequest({decision:a.decision,version:e.versionState.version}),n=await new W(this.dependencies.getSharedSyncSession()).sync({urls:t,request:r}),o=(e=>{const t=[];for(const s of e)for(const e of s.data){const s=z(e.metadata);t.push({relation:{userId:e.contact,remark:e.remark,sign:s.sign??"",addTs:e.createdAt,updatedAt:e.updatedAt,metadataUpdatedAt:e.metadataUpdatedAt},userInfo:{userId:e.contact,nickname:s.nickname,avatarUrl:s.avatarUrl,sign:s.sign,ext:s.ext}})}return t})(n.pages),i=this.dependencies.applySyncResult({mode:n.mode,relations:o.map(e=>e.relation),userInfos:o.map(e=>e.userInfo),version:n.version,lastSyncTs:Date.now()});this.dependencies.onFinish(),Z({outcome:"finish",decision:a.decision,durationMs:Date.now()-s,version:n.version,source:"sync",changed:i.changed,hasUsableSnapshot:i.snapshot.complete})}catch(n){const o=n instanceof r?n:new r("Contact sync failed",t.CONTACT_SYNC_SOCKET_FAILED,{details:{stage:"sync_page",cause:n instanceof Error?n.message:String(n)}}),i=o.details??{},c="string"==typeof i.stage?i.stage:"sync_page";this.dependencies.onFinish({error:X(c,o.code,o.message,!0)}),Z({outcome:"fail",decision:a.decision,durationMs:Date.now()-s,version:a.version,stage:c,hasUsableSnapshot:e.cachedSnapshot.complete,source:e.cachedSnapshot.complete?e.cachedSnapshot.source:void 0})}}}const te={items:[],loaded:!1,source:"server"},se=i(c,{common:{},apis:{getContactList:{range:"",errors:{}},addContact:{range:"110,204,210,1000,1001,1002",localErrors:{addContact:{validation_invalid:{code:110,retryable:!1}}},errors:{USER_NOT_FOUND:{code:204,httpStatus:404,retryable:!1},ALREADY_FRIEND:{code:1e3,retryable:!1},BLOCKED_BY_USER:{code:210,retryable:!1},CONTACT_REACH_LIMIT:{code:1001,httpStatus:403,retryable:!1,matchField:"error_description",matchPattern:"Inviter's contact max count"},CONTACT_REACH_LIMIT_PEER:{code:1002,httpStatus:403,retryable:!1,matchField:"error_description",matchPattern:"Invitee's contact max count"}}},deleteContact:{range:"110,204",localErrors:{deleteContact:{validation_invalid:{code:110,retryable:!1}}},errors:{USER_NOT_FOUND:{code:204,httpStatus:404,retryable:!1}}},acceptContactInvite:{range:"110,204,1001,1002",localErrors:{acceptContactInvite:{validation_invalid:{code:110,retryable:!1}}},errors:{USER_NOT_FOUND:{code:204,httpStatus:404,retryable:!1},CONTACT_REACH_LIMIT:{code:1001,httpStatus:403,retryable:!1,matchField:"error_description",matchPattern:"Inviter's contact max count"},CONTACT_REACH_LIMIT_PEER:{code:1002,httpStatus:403,retryable:!1,matchField:"error_description",matchPattern:"Invitee's contact max count"}}},declineContactInvite:{range:"110,204",localErrors:{declineContactInvite:{validation_invalid:{code:110,retryable:!1}}},errors:{USER_NOT_FOUND:{code:204,httpStatus:404,retryable:!1}}},setContactRemark:{range:"4,110,223",localErrors:{setContactRemark:{validation_invalid:{code:110,retryable:!1}}},errors:{illegal_argument:{code:223,httpStatus:400,retryable:!1,matchField:"error_description",matchPattern:"please add as a friend first"},remark_length_exceeded:{code:4,httpStatus:400,retryable:!1,matchField:"error_description",matchPattern:"remark length must less than"}}},getBlocklist:{range:"",errors:{}},addUsersToBlocklist:{range:"4,110,204",localErrors:{addUsersToBlocklist:{validation_invalid:{code:110,retryable:!1}}},errors:{service_resource_not_found:{code:204,httpStatus:404,retryable:!1},blocklist_limit_exceeded:{code:4,httpStatus:400,retryable:!1,matchField:"error_description",matchPattern:"almost reached or been greater than the upper range"}}},removeUserFromBlocklist:{range:"110",localErrors:{removeUserFromBlocklist:{validation_invalid:{code:110,retryable:!1}}},errors:{}}}}),re=class{constructor(){this.client=null,this.eventContext=null,this.restClient=null,this.restBaseUrl=null,this.restToken=null,this.blocklistSnapshot=te,this.blocklistSessionKey=null}bind(e,t){this.client=e,this.eventContext=t??null,this.blocklistSnapshot=te,this.blocklistSessionKey=null}getContacts(){return this.client?.getContactSnapshot()?.items??[]}async addContact(e){return this.runOperation("addContact",async()=>{const t=this.validateUserId(e.userId,"params.userId"),s=this.validateOptionalString(e.message,"params.message"),r=this.getRestContextOrThrow(),a=this.getRestClient(r);n.debug("ContactManager addContact",{userId:t,hasMessage:"string"==typeof s&&s.length>0}),await(async(e,t,s)=>{const r=O(t),a=`/${r.orgName}/${r.appName}/users/${r.encodedUserId}/contacts/apply?resource=${r.encodedResource}`;await e.post(a,{usernames:[s.userId],reason:s.message??""},{operation:"addContact"})})(a,r,{userId:t,message:s})})}async deleteContact(e){return this.runOperation("deleteContact",async()=>{const t=this.validateUserId(e.userId,"params.userId"),s=this.getRestContextOrThrow(),r=this.getRestClient(s);n.debug("ContactManager deleteContact",{userId:t}),await(async(e,t,s)=>{const r=O(t),a=`/${r.orgName}/${r.appName}/users/${r.encodedUserId}/contacts/users/${encodeURIComponent(s.userId)}?resource=${r.encodedResource}`;await e.delete(a,{operation:"deleteContact"})})(r,s,{userId:t});const a=this.client?.getCacheManager()?.removeContact(t);n.debug("ContactManager deleteContact patched cache",{userId:t,changed:a?.changed??!1})})}async acceptContactInvite(e){return this.runOperation("acceptContactInvite",async()=>{const t=this.validateUserId(e.userId,"params.userId"),s=this.getRestContextOrThrow(),r=this.getRestClient(s);n.debug("ContactManager acceptContactInvite",{userId:t}),await(async(e,t,s)=>{const r=O(t),a=`/${r.orgName}/${r.appName}/users/${r.encodedUserId}/contacts/accept/users/${encodeURIComponent(s.userId)}?resource=${r.encodedResource}`;await e.post(a,void 0,{operation:"acceptContactInvite"})})(r,s,{userId:t}),await this.requireClient().refreshContactSnapshot()})}async declineContactInvite(e){return this.runOperation("declineContactInvite",async()=>{const t=this.validateUserId(e.userId,"params.userId"),s=this.getRestContextOrThrow(),r=this.getRestClient(s);n.debug("ContactManager declineContactInvite",{userId:t}),await(async(e,t,s)=>{const r=O(t),a=`/${r.orgName}/${r.appName}/users/${r.encodedUserId}/contacts/decline/users/${encodeURIComponent(s.userId)}?resource=${r.encodedResource}`;await e.post(a,void 0,{operation:"declineContactInvite"})})(r,s,{userId:t})})}async setContactRemark(e){return this.runOperation("setContactRemark",async()=>{const t=this.validateUserId(e.userId,"params.userId"),s=this.validateRemark(e.remark,"params.remark"),r=this.getRestContextOrThrow(),a=this.getRestClient(r);n.debug("ContactManager setContactRemark",{userId:t,remarkLength:s.length}),await(async(e,t,s)=>{const r=O(t),a=`/${r.orgName}/${r.appName}/users/${r.encodedUserId}/contacts/users/${encodeURIComponent(s.userId)}?resource=${r.encodedResource}`;await e.put(a,{remark:s.remark},{operation:"setContactRemark"})})(a,r,{userId:t,remark:s});const o=this.client?.getCacheManager()?.updateContactRemark(t,s);this.client?.refreshConversationDisplayFromUserInfos([{userId:t}],"profile"),n.debug("ContactManager setContactRemark patched cache",{userId:t,changed:o?.changed??!1})})}async getBlocklist(){return this.runOperation("getBlocklist",async()=>{const e=this.getRestContextOrThrow();this.ensureBlocklistSession(e);const t=this.getRestClient(e);if(this.blocklistSnapshot.loaded)return this.blocklistSnapshot.items;const s=await this.enrichBlocklistUsers(await D(t,e));return this.blocklistSnapshot={items:s,loaded:!0,source:"server"},n.debug("ContactManager getBlocklist",{count:s.length}),s})}async addUsersToBlocklist(e){return this.runOperation("addUsersToBlocklist",async()=>{const t=this.getRestContextOrThrow();this.ensureBlocklistSession(t);const s=q(e,"params.userIds"),r=this.getRestClient(t);n.debug("ContactManager addUsersToBlocklist",{userIds:s,inputCount:e.userIds.length,normalizedCount:s.length});const a=await $(r,t,s),o=await this.enrichBlocklistUsers(a.succeeded);return this.blocklistSnapshot=this.patchBlocklistSnapshotWithAdditions(o),{succeeded:o,failed:await this.enrichBlocklistUsers(a.failed)}})}async removeUserFromBlocklist(e){return this.runOperation("removeUserFromBlocklist",async()=>{const t=this.getRestContextOrThrow();this.ensureBlocklistSession(t);const s=q(e,"params.userIds"),r=this.getRestClient(t);n.debug("ContactManager removeUserFromBlocklist",{userIds:s,inputCount:e.userIds.length,normalizedCount:s.length}),await(async(e,t,s)=>{const r=O(t),a=`/${r.orgName}/${r.appName}/sdk/user/${r.encodedUserId}/blocks?resource=${r.encodedResource}`;await e.request(a,{method:"DELETE",body:{usernames:s},operation:"removeUserFromBlocklist"})})(r,t,s),this.blocklistSnapshot=this.patchBlocklistSnapshotWithRemovals(s)})}addEventHandler(e,t){this.eventContext?.addEventHandler(e,t)}removeEventHandler(e){this.eventContext?.removeEventHandler(e)}async runOperation(e,t){try{return await t()}catch(s){const t=this.normalizeSdkError(e,s);throw n.warn(`ContactManager ${e} failed`,{code:t.code,message:t.message,details:t.details}),t}}normalizeSdkError(e,s){return s instanceof r?s:s instanceof Error?new r(`ContactManager ${e} failed: ${s.message}`,t.UNKNOWN):new r(`ContactManager ${e} failed`,t.UNKNOWN)}requireClient(){if(!this.client)throw this.buildValidationError("ContactManager is not bound to client",[{path:"contactManager.client",message:"ContactManager is not bound to client",rule:"required"}]);return this.client}getRestContextOrThrow(){return this.requireClient().getRestContext()}getRestClient(e){return this.restClient&&this.restBaseUrl===e.restBaseUrl&&this.restToken===e.token||(this.restClient=new o(e.restBaseUrl,{errorMap:se,requestAdapter:this.requireClient().getRequestAdapter?.(),includeRequestId:!0}),this.restClient.setAuthToken(e.token),this.restBaseUrl=e.restBaseUrl,this.restToken=e.token),this.restClient}ensureBlocklistSession(e){const t=`${e.restBaseUrl}:${e.userId}:${e.token}`;this.blocklistSessionKey!==t&&(this.blocklistSessionKey=t,this.blocklistSnapshot=te)}patchBlocklistSnapshotWithAdditions(e){const t=new Map(this.blocklistSnapshot.items.map(e=>[e.userId,e]));for(const s of e)t.set(s.userId,s);return{items:Array.from(t.values()),loaded:this.blocklistSnapshot.loaded,source:"mutation_patch"}}patchBlocklistSnapshotWithRemovals(e){const t=new Map(this.blocklistSnapshot.items.map(e=>[e.userId,e]));for(const s of e)t.delete(s);return{items:Array.from(t.values()),loaded:this.blocklistSnapshot.loaded,source:"mutation_patch"}}validateUserId(e,t){if("string"!=typeof e)throw this.buildValidationError("userId must be a string",[{path:t,message:"userId must be a string",rule:"invalid_format"}]);const s=e.trim();if(!s)throw this.buildValidationError("userId is required",[{path:t,message:"userId is required",rule:"required"}]);return s}validateOptionalString(e,t){if(void 0!==e){if("string"!=typeof e)throw this.buildValidationError(`${t} must be a string`,[{path:t,message:`${t} must be a string`,rule:"invalid_format"}]);return e}}validateRemark(e,t){if("string"!=typeof e)throw this.buildValidationError("remark must be a string",[{path:t,message:"remark must be a string",rule:"invalid_format"}]);return e}buildValidationError(s,r){const a=r.some(e=>"invalid_format"===e.rule)?t.VALIDATION_INVALID_FORMAT:t.VALIDATION_REQUIRED;return new e(s,{code:a,details:{fields:r}})}async enrichBlocklistUsers(e){if(0===e.length||!this.requireClient().isUserInfoSyncEnabled())return e;const t=await S(e.map(e=>e.userId),{cacheManager:this.requireClient().getCacheManager(),fetchUserInfos:async({userIds:e})=>await this.fetchUserInfos(e)});return e.map(e=>t.get(e.userId)??e)}async fetchUserInfos(e){if(0===e.length)return[];try{const t=this.getUserInfoManager();return t?await t.getUserInfoByUserId({userIds:e}):await this.fetchUserInfosFromRest(e)}catch(t){return n.warn("ContactManager user info fetch failed",{userIds:e,error:t}),[]}}async fetchUserInfosFromRest(e){const t=this.getRestContextOrThrow(),s=l(e),r=await this.getRestClient(t).request(u(t),{method:"POST",body:s,operation:"getUserInfoByUserId"});return h(r,s.targets)}getUserInfoManager(){const e=this.requireClient();if(!this.hasUserInfoCapabilityProvider(e))return null;const t=e.getManagerByCapability("userInfo:read");return t&&this.hasUserInfoReadCapability(t)?t:null}hasUserInfoCapabilityProvider(e){return"function"==typeof e.getManagerByCapability}hasUserInfoReadCapability(e){return"function"==typeof e.getUserInfoByUserId}createSyncController(e){return new ee(e)}};re.key="contactManager";let ae=re;export{ae as C,v as R,R as r};
|