@k-msg/channel 0.25.1 → 0.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +2 -2
- package/dist/index.js.map +3 -3
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +3 -3
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var{defineProperty:I,getOwnPropertyNames:Z,getOwnPropertyDescriptor:X}=Object,z=Object.prototype.hasOwnProperty;var Y=new WeakMap,ee=(e)=>{var t=Y.get(e),r;if(t)return t;if(t=I({},"__esModule",{value:!0}),e&&typeof e==="object"||typeof e==="function")Z(e).map((i)=>!z.call(t,i)&&I(t,i,{get:()=>e[i],enumerable:!(r=X(e,i))||r.enumerable}));return Y.set(e,t),t};var te=(e,t)=>{for(var r in t)I(e,r,{get:t[r],enumerable:!0,configurable:!0,set:(i)=>t[r]=()=>i})};var le={};te(le,{KakaoChannelLifecycleService:()=>_,KakaoChannelCapabilityService:()=>S,KakaoChannelBindingResolver:()=>M});module.exports=ee(le);var ne={["INVALID_REQUEST"]:{ko:"잘못된 요청입니다",en:"Invalid request"},["AUTHENTICATION_FAILED"]:{ko:"인증에 실패했습니다",en:"Authentication failed"},["INSUFFICIENT_BALANCE"]:{ko:"잔액이 부족합니다",en:"Insufficient balance"},["TEMPLATE_NOT_FOUND"]:{ko:"템플릿을 찾을 수 없습니다",en:"Template not found"},["RATE_LIMIT_EXCEEDED"]:{ko:"요청 한도를 초과했습니다",en:"Rate limit exceeded"},["NETWORK_ERROR"]:{ko:"네트워크 오류가 발생했습니다",en:"Network error"},["NETWORK_TIMEOUT"]:{ko:"네트워크 요청 시간이 초과되었습니다",en:"Network timeout"},["NETWORK_SERVICE_UNAVAILABLE"]:{ko:"서비스를 일시적으로 사용할 수 없습니다",en:"Service temporarily unavailable"},["PROVIDER_ERROR"]:{ko:"제공자 오류가 발생했습니다",en:"Provider error"},["MESSAGE_SEND_FAILED"]:{ko:"메시지 전송에 실패했습니다",en:"Message send failed"},["CRYPTO_CONFIG_ERROR"]:{ko:"암호화 설정 오류가 발생했습니다",en:"Crypto configuration error"},["CRYPTO_ENCRYPT_FAILED"]:{ko:"암호화에 실패했습니다",en:"Encryption failed"},["CRYPTO_DECRYPT_FAILED"]:{ko:"복호화에 실패했습니다",en:"Decryption failed"},["CRYPTO_HASH_FAILED"]:{ko:"해시 생성에 실패했습니다",en:"Hash generation failed"},["CRYPTO_POLICY_VIOLATION"]:{ko:"암호화 정책 위반이 발생했습니다",en:"Crypto policy violation"},["UNKNOWN_ERROR"]:{ko:"알 수 없는 오류가 발생했습니다",en:"Unknown error"}};var x=(e)=>{if(typeof e!=="number"||Number.isNaN(e)||!Number.isFinite(e))return;return Math.trunc(e)};class c extends Error{code;details;providerErrorCode;providerErrorText;httpStatus;requestId;retryAfterMs;attempt;causeChain;constructor(e,t,r,i={}){super(t);if(this.name="KMsgError",this.code=e,this.details=r,this.providerErrorCode=i.providerErrorCode,this.providerErrorText=i.providerErrorText,this.httpStatus=x(i.httpStatus),this.requestId=typeof i.requestId==="string"?i.requestId:void 0,this.retryAfterMs=x(i.retryAfterMs),this.attempt=x(i.attempt),Array.isArray(i.causeChain))this.causeChain=i.causeChain;else if(i.causeChain!==void 0)this.causeChain=[i.causeChain];if(Error.captureStackTrace)Error.captureStackTrace(this,c)}getLocalizedMessage(e="ko"){let t=ne[this.code];if(t?.[e])return t[e];return this.message}toJSON(){return{name:this.name,code:this.code,message:this.message,details:this.details,providerErrorCode:this.providerErrorCode,providerErrorText:this.providerErrorText,httpStatus:this.httpStatus,requestId:this.requestId,retryAfterMs:this.retryAfterMs,attempt:this.attempt,causeChain:this.causeChain}}}var O=(e)=>({isSuccess:!0,isFailure:!1,value:e}),f=(e)=>({isSuccess:!1,isFailure:!0,error:e});function n(e){if(typeof e!=="string")return;let t=e.trim();return t.length>0?t:void 0}function E(e){if(!e)return;let t=e.trim();return t.length>0?t.toLowerCase():void 0}function Q(e){let t=e.config&&typeof e.config==="object"?e.config:{},r=n(t.senderKey)??n(t.kakaoPfId)??n(t.profileId),i=n(t.plusId);if(E(e.type)==="solapi")return{senderKey:n(t.kakaoPfId)??r,...i?{plusId:i}:{}};return{...r?{senderKey:r}:{},...i?{plusId:i}:{}}}function se(e){return[e.providerId??"",e.senderKey??"",e.plusId??"",e.source].join("|")}function W(e){if(!Array.isArray(e)||e.length!==1)return;return n(e[0]?.id)}class M{config;constructor(e){this.config=e}list(e){let t=n(e?.providerId),r=this.config.aliases?.kakaoChannels??{},i=[],s=new Set,K=(o)=>{if(t&&o.providerId!==t)return;let a=se(o);if(s.has(a))return;s.add(a),i.push(o)};for(let[o,a]of Object.entries(r)){let d=n(a.providerId);if(!d)continue;let v=n(a.senderKey),P=n(a.plusId);if(!v&&!P)continue;K({source:"config",alias:o,providerId:d,...v?{senderKey:v}:{},...P?{plusId:P}:{},...n(a.name)?{name:n(a.name)}:{}})}let p=this.config.defaults?.kakao,y=n(p?.channel),l=y?r[y]:void 0,A=n(l?.providerId)??n(this.config.routing?.defaultProviderId)??W(this.config.providers),C=n(p?.senderKey)??n(l?.senderKey),k=n(p?.plusId)??n(l?.plusId);if(A&&(C||k))K({source:"config",...y?{alias:y}:{},providerId:A,...C?{senderKey:C}:{},...k?{plusId:k}:{},...n(l?.name)?{name:n(l?.name)}:{}});for(let o of this.config.providers??[]){let a=n(o.id);if(!a)continue;let d=Q(o);if(!d.senderKey&&!d.plusId)continue;K({source:"config",providerId:a,...d.senderKey?{senderKey:d.senderKey}:{},...d.plusId?{plusId:d.plusId}:{}})}return i}resolve(e){let t=this.config.aliases?.kakaoChannels??{},r=n(e?.channelAlias),i=r?t[r]:void 0;if(r&&e?.strictAlias===!0&&!i)throw new c("INVALID_REQUEST",`Unknown kakao channel alias: ${r}`);let s=this.config.defaults?.kakao,K=n(s?.channel),p=K?t[K]:void 0,y=n(e?.providerId),l=n(i?.providerId),A=n(p?.providerId),C=n(this.config.routing?.defaultProviderId),k=W(this.config.providers),o,a="unknown";if(y)o=y,a="explicit";else if(l)o=l,a="alias";else if(A)o=A,a="defaults";else if(C)o=C,a="routing";else if(k)o=k,a="single_provider";let d=o?(this.config.providers??[]).find((L)=>L.id===o):void 0,v=d?Q(d):{},P=n(e?.senderKey),q=n(i?.senderKey),N=n(s?.senderKey),U=n(p?.senderKey),$=n(v.senderKey),H=n(e?.plusId),j=n(i?.plusId),G=n(s?.plusId),J=n(p?.plusId),V=n(v.plusId),u,h;if(P)u=P,h="explicit";else if(q)u=q,h="alias";else if(N)u=N,h="defaults";else if(U)u=U,h="defaults";else if($)u=$,h="provider_config";let g,m;if(H)g=H,m="explicit";else if(j)g=j,m="alias";else if(G)g=G,m="defaults";else if(J)g=J,m="defaults";else if(V)g=V,m="provider_config";return{...r?{alias:r}:{},...o?{providerId:o}:{},...E(d?.type)?{providerType:E(d?.type)}:{},...u?{senderKey:u}:{},...g?{plusId:g}:{},...n(i?.name)?{name:n(i?.name)}:n(p?.name)?{name:n(p?.name)}:{},providerIdSource:a,...h?{senderKeySource:h}:{},...m?{plusIdSource:m}:{}}}getAlias(e){let t=n(e);if(!t)return;return this.config.aliases?.kakaoChannels?.[t]}}function w(e){return typeof e==="function"}function oe(e){if(!w(e.getOnboardingSpec))return;try{return e.getOnboardingSpec()}catch{return}}function ae(e){if(typeof e!=="string")return;let t=e.trim();return t.length>0?t.toLowerCase():void 0}function de(e,t){if(e?.channelOnboarding){if(e.channelOnboarding==="api"&&!t)return"none";return e.channelOnboarding}return t?"api":"none"}class S{resolve(e){let t=oe(e),r={list:w(e.listKakaoChannels),categories:w(e.listKakaoChannelCategories),auth:w(e.requestKakaoChannelAuth),add:w(e.addKakaoChannel)},i=ae(t?.providerId),s=de(t,r.list);return{providerId:e.id,...i?{providerType:i}:{},mode:s,supports:r}}}function R(e,t){return new c("INVALID_REQUEST",`Provider '${e}' does not support kakao channel api operation '${t}'`,{providerId:e,operation:t})}class F{provider;constructor(e){this.provider=e}async list(e){let t=this.provider.listKakaoChannels;if(typeof t!=="function")return f(R(this.provider.id,"list"));return t.call(this.provider,e)}async categories(){let e=this.provider.listKakaoChannelCategories;if(typeof e!=="function")return f(R(this.provider.id,"categories"));return e.call(this.provider)}async auth(e){let t=this.provider.requestKakaoChannelAuth;if(typeof t!=="function")return f(R(this.provider.id,"auth"));return t.call(this.provider,e)}async add(e){let t=this.provider.addKakaoChannel;if(typeof t!=="function")return f(R(this.provider.id,"add"));return t.call(this.provider,e)}}class T{provider;mode="manual";constructor(e){this.provider=e}unsupportedMessage(e){return`Provider '${this.provider.id}' uses manual Kakao channel onboarding. Operation '${e}' is not available via API.`}}class D extends F{constructor(e){super(e)}}class B{provider;mode="none";constructor(e){this.provider=e}unsupportedMessage(e){return`Provider '${this.provider.id}' does not expose Kakao channel onboarding API. Operation '${e}' is unsupported.`}}function ce(e){if(typeof e!=="string")return;let t=e.trim();return t.length>0?t.toLowerCase():void 0}function pe(e,t){switch(e){case"aligo":return new F(t);case"mock":return new D(t);default:return typeof t.listKakaoChannels==="function"?new F(t):void 0}}class _{provider;capability;providerType;apiAdapter;iwinvAdapter;solapiAdapter;constructor(e,t=new S){this.provider=e;if(this.capability=t.resolve(e),this.providerType=ce(this.capability.providerType),this.capability.mode==="api")this.apiAdapter=pe(this.providerType,this.provider);else if(this.providerType==="iwinv")this.iwinvAdapter=new T(this.provider);else if(this.providerType==="solapi")this.solapiAdapter=new B(this.provider)}getCapability(){return this.capability}unsupported(e){let t=(()=>{if(this.capability.mode==="manual"){if(this.iwinvAdapter)return this.iwinvAdapter.unsupportedMessage(e);return`Provider '${this.provider.id}' requires manual Kakao channel onboarding. Operation '${e}' is unavailable via API.`}if(this.capability.mode==="none"){if(this.solapiAdapter)return this.solapiAdapter.unsupportedMessage(e);return`Provider '${this.provider.id}' does not support Kakao channel onboarding API operation '${e}'.`}return`Provider '${this.provider.id}' does not support Kakao channel onboarding API operation '${e}'.`})();return f(new c("INVALID_REQUEST",t,{providerId:this.provider.id,mode:this.capability.mode,operation:e}))}ensureApi(e){if(this.capability.mode!=="api")return this.unsupported(e);if(!this.apiAdapter)return f(new c("INVALID_REQUEST",`Provider '${this.provider.id}' is marked as api mode but does not expose kakao channel operations`,{providerId:this.provider.id,mode:this.capability.mode,operation:e}));return O(void 0)}async list(e){let t=this.ensureApi("list");if(t.isFailure)return t;let r=this.apiAdapter;if(!r)return this.unsupported("list");let i=await r.list(e);if(i.isFailure)return i;return O(i.value.map((s)=>({source:"api",providerId:s.providerId||this.provider.id,senderKey:s.senderKey,...s.plusId?{plusId:s.plusId}:{},...s.name?{name:s.name}:{},...s.status?{status:s.status}:{}})))}async categories(){let e=this.ensureApi("categories");if(e.isFailure)return e;let t=this.apiAdapter;if(!t)return this.unsupported("categories");return t.categories()}async auth(e){let t=this.ensureApi("auth");if(t.isFailure)return t;let r=this.apiAdapter;if(!r)return this.unsupported("auth");return r.auth(e)}async add(e){let t=this.ensureApi("add");if(t.isFailure)return t;let r=this.apiAdapter;if(!r)return this.unsupported("add");return r.add(e)}}
|
|
1
|
+
var{defineProperty:L,getOwnPropertyNames:o,getOwnPropertyDescriptor:e}=Object,r=Object.prototype.hasOwnProperty;var m=new WeakMap,nn=(n)=>{var f=m.get(n),i;if(f)return f;if(f=L({},"__esModule",{value:!0}),n&&typeof n==="object"||typeof n==="function")o(n).map((K)=>!r.call(f,K)&&L(f,K,{get:()=>n[K],enumerable:!(i=e(n,K))||i.enumerable}));return m.set(n,f),f};var fn=(n,f)=>{for(var i in f)L(n,i,{get:f[i],enumerable:!0,configurable:!0,set:(K)=>f[i]=()=>K})};var yn={};fn(yn,{KakaoChannelLifecycleService:()=>x,KakaoChannelCapabilityService:()=>Y,KakaoChannelBindingResolver:()=>_});module.exports=nn(yn);var D;((I)=>{I.INVALID_REQUEST="INVALID_REQUEST";I.AUTHENTICATION_FAILED="AUTHENTICATION_FAILED";I.INSUFFICIENT_BALANCE="INSUFFICIENT_BALANCE";I.TEMPLATE_NOT_FOUND="TEMPLATE_NOT_FOUND";I.RATE_LIMIT_EXCEEDED="RATE_LIMIT_EXCEEDED";I.NETWORK_ERROR="NETWORK_ERROR";I.NETWORK_TIMEOUT="NETWORK_TIMEOUT";I.NETWORK_SERVICE_UNAVAILABLE="NETWORK_SERVICE_UNAVAILABLE";I.PROVIDER_ERROR="PROVIDER_ERROR";I.MESSAGE_SEND_FAILED="MESSAGE_SEND_FAILED";I.CRYPTO_CONFIG_ERROR="CRYPTO_CONFIG_ERROR";I.CRYPTO_ENCRYPT_FAILED="CRYPTO_ENCRYPT_FAILED";I.CRYPTO_DECRYPT_FAILED="CRYPTO_DECRYPT_FAILED";I.CRYPTO_HASH_FAILED="CRYPTO_HASH_FAILED";I.CRYPTO_POLICY_VIOLATION="CRYPTO_POLICY_VIOLATION";I.UNKNOWN_ERROR="UNKNOWN_ERROR"})(D||={});var kn={["INVALID_REQUEST"]:{ko:"잘못된 요청입니다",en:"Invalid request"},["AUTHENTICATION_FAILED"]:{ko:"인증에 실패했습니다",en:"Authentication failed"},["INSUFFICIENT_BALANCE"]:{ko:"잔액이 부족합니다",en:"Insufficient balance"},["TEMPLATE_NOT_FOUND"]:{ko:"템플릿을 찾을 수 없습니다",en:"Template not found"},["RATE_LIMIT_EXCEEDED"]:{ko:"요청 한도를 초과했습니다",en:"Rate limit exceeded"},["NETWORK_ERROR"]:{ko:"네트워크 오류가 발생했습니다",en:"Network error"},["NETWORK_TIMEOUT"]:{ko:"네트워크 요청 시간이 초과되었습니다",en:"Network timeout"},["NETWORK_SERVICE_UNAVAILABLE"]:{ko:"서비스를 일시적으로 사용할 수 없습니다",en:"Service temporarily unavailable"},["PROVIDER_ERROR"]:{ko:"제공자 오류가 발생했습니다",en:"Provider error"},["MESSAGE_SEND_FAILED"]:{ko:"메시지 전송에 실패했습니다",en:"Message send failed"},["CRYPTO_CONFIG_ERROR"]:{ko:"암호화 설정 오류가 발생했습니다",en:"Crypto configuration error"},["CRYPTO_ENCRYPT_FAILED"]:{ko:"암호화에 실패했습니다",en:"Encryption failed"},["CRYPTO_DECRYPT_FAILED"]:{ko:"복호화에 실패했습니다",en:"Decryption failed"},["CRYPTO_HASH_FAILED"]:{ko:"해시 생성에 실패했습니다",en:"Hash generation failed"},["CRYPTO_POLICY_VIOLATION"]:{ko:"암호화 정책 위반이 발생했습니다",en:"Crypto policy violation"},["UNKNOWN_ERROR"]:{ko:"알 수 없는 오류가 발생했습니다",en:"Unknown error"}},$n=new Set(Object.values(D));var R=(n)=>{if(typeof n!=="number"||Number.isNaN(n)||!Number.isFinite(n))return;return Math.trunc(n)};class A extends Error{code;details;providerErrorCode;providerErrorText;httpStatus;requestId;retryAfterMs;attempt;causeChain;constructor(n,f,i,K={}){super(f);if(this.name="KMsgError",this.code=n,this.details=i,this.providerErrorCode=K.providerErrorCode,this.providerErrorText=K.providerErrorText,this.httpStatus=R(K.httpStatus),this.requestId=typeof K.requestId==="string"?K.requestId:void 0,this.retryAfterMs=R(K.retryAfterMs),this.attempt=R(K.attempt),Array.isArray(K.causeChain))this.causeChain=K.causeChain;else if(K.causeChain!==void 0)this.causeChain=[K.causeChain];if(Error.captureStackTrace)Error.captureStackTrace(this,A)}getLocalizedMessage(n="ko"){let f=kn[this.code];if(f?.[n])return f[n];return this.message}toJSON(){return{name:this.name,code:this.code,message:this.message,details:this.details,providerErrorCode:this.providerErrorCode,providerErrorText:this.providerErrorText,httpStatus:this.httpStatus,requestId:this.requestId,retryAfterMs:this.retryAfterMs,attempt:this.attempt,causeChain:this.causeChain}}}var F=(n)=>({isSuccess:!0,isFailure:!1,value:n}),w=(n)=>({isSuccess:!1,isFailure:!0,error:n});function k(n){if(typeof n!=="string")return;let f=n.trim();return f.length>0?f:void 0}function j(n){if(!n)return;let f=n.trim();return f.length>0?f.toLowerCase():void 0}function t(n){let f=n.config&&typeof n.config==="object"?n.config:{},i=k(f.senderKey)??k(f.kakaoPfId)??k(f.profileId),K=k(f.plusId);if(j(n.type)==="solapi")return{senderKey:k(f.kakaoPfId)??i,...K?{plusId:K}:{}};return{...i?{senderKey:i}:{},...K?{plusId:K}:{}}}function Kn(n){return[n.providerId??"",n.senderKey??"",n.plusId??"",n.source].join("|")}function s(n){if(!Array.isArray(n)||n.length!==1)return;return k(n[0]?.id)}class _{config;constructor(n){this.config=n}list(n){let f=k(n?.providerId),i=this.config.aliases?.kakaoChannels??{},K=[],P=new Set,V=(h)=>{if(f&&h.providerId!==f)return;let g=Kn(h);if(P.has(g))return;P.add(g),K.push(h)};for(let[h,g]of Object.entries(i)){let C=k(g.providerId);if(!C)continue;let O=k(g.senderKey),I=k(g.plusId);if(!O&&!I)continue;V({source:"config",alias:h,providerId:C,...O?{senderKey:O}:{},...I?{plusId:I}:{},...k(g.name)?{name:k(g.name)}:{}})}let y=this.config.defaults?.kakao,B=k(y?.channel),$=B?i[B]:void 0,q=k($?.providerId)??k(this.config.routing?.defaultProviderId)??s(this.config.providers),X=k(y?.senderKey)??k($?.senderKey),Z=k(y?.plusId)??k($?.plusId);if(q&&(X||Z))V({source:"config",...B?{alias:B}:{},providerId:q,...X?{senderKey:X}:{},...Z?{plusId:Z}:{},...k($?.name)?{name:k($?.name)}:{}});for(let h of this.config.providers??[]){let g=k(h.id);if(!g)continue;let C=t(h);if(!C.senderKey&&!C.plusId)continue;V({source:"config",providerId:g,...C.senderKey?{senderKey:C.senderKey}:{},...C.plusId?{plusId:C.plusId}:{}})}return K}resolve(n){let f=this.config.aliases?.kakaoChannels??{},i=k(n?.channelAlias),K=i?f[i]:void 0;if(i&&n?.strictAlias===!0&&!K)throw new A("INVALID_REQUEST",`Unknown kakao channel alias: ${i}`);let P=this.config.defaults?.kakao,V=k(P?.channel),y=V?f[V]:void 0,B=k(n?.providerId),$=k(K?.providerId),q=k(y?.providerId),X=k(this.config.routing?.defaultProviderId),Z=s(this.config.providers),h,g="unknown";if(B)h=B,g="explicit";else if($)h=$,g="alias";else if(q)h=q,g="defaults";else if(X)h=X,g="routing";else if(Z)h=Z,g="single_provider";let C=h?(this.config.providers??[]).find((a)=>a.id===h):void 0,O=C?t(C):{},I=k(n?.senderKey),d=k(K?.senderKey),p=k(P?.senderKey),v=k(y?.senderKey),M=k(O.senderKey),z=k(n?.plusId),E=k(K?.plusId),c=k(P?.plusId),l=k(y?.plusId),u=k(O.plusId),H,Q;if(I)H=I,Q="explicit";else if(d)H=d,Q="alias";else if(p)H=p,Q="defaults";else if(v)H=v,Q="defaults";else if(M)H=M,Q="provider_config";let G,J;if(z)G=z,J="explicit";else if(E)G=E,J="alias";else if(c)G=c,J="defaults";else if(l)G=l,J="defaults";else if(u)G=u,J="provider_config";return{...i?{alias:i}:{},...h?{providerId:h}:{},...j(C?.type)?{providerType:j(C?.type)}:{},...H?{senderKey:H}:{},...G?{plusId:G}:{},...k(K?.name)?{name:k(K?.name)}:k(y?.name)?{name:k(y?.name)}:{},providerIdSource:g,...Q?{senderKeySource:Q}:{},...J?{plusIdSource:J}:{}}}getAlias(n){let f=k(n);if(!f)return;return this.config.aliases?.kakaoChannels?.[f]}}function U(n){return typeof n==="function"}function In(n){if(!U(n.getOnboardingSpec))return;try{return n.getOnboardingSpec()}catch{return}}function Pn(n){if(typeof n!=="string")return;let f=n.trim();return f.length>0?f.toLowerCase():void 0}function hn(n,f){if(n?.channelOnboarding){if(n.channelOnboarding==="api"&&!f)return"none";return n.channelOnboarding}return f?"api":"none"}class Y{resolve(n){let f=In(n),i={list:U(n.listKakaoChannels),categories:U(n.listKakaoChannelCategories),auth:U(n.requestKakaoChannelAuth),add:U(n.addKakaoChannel)},K=Pn(f?.providerId),P=hn(f,i.list);return{providerId:n.id,...K?{providerType:K}:{},mode:P,supports:i}}}function S(n,f){return new A("INVALID_REQUEST",`Provider '${n}' does not support kakao channel api operation '${f}'`,{providerId:n,operation:f})}class W{provider;constructor(n){this.provider=n}async list(n){let f=this.provider.listKakaoChannels;if(typeof f!=="function")return w(S(this.provider.id,"list"));return f.call(this.provider,n)}async categories(){let n=this.provider.listKakaoChannelCategories;if(typeof n!=="function")return w(S(this.provider.id,"categories"));return n.call(this.provider)}async auth(n){let f=this.provider.requestKakaoChannelAuth;if(typeof f!=="function")return w(S(this.provider.id,"auth"));return f.call(this.provider,n)}async add(n){let f=this.provider.addKakaoChannel;if(typeof f!=="function")return w(S(this.provider.id,"add"));return f.call(this.provider,n)}}class T{provider;mode="manual";constructor(n){this.provider=n}unsupportedMessage(n){return`Provider '${this.provider.id}' uses manual Kakao channel onboarding. Operation '${n}' is not available via API.`}}class b extends W{constructor(n){super(n)}}class N{provider;mode="none";constructor(n){this.provider=n}unsupportedMessage(n){return`Provider '${this.provider.id}' does not expose Kakao channel onboarding API. Operation '${n}' is unsupported.`}}function gn(n){if(typeof n!=="string")return;let f=n.trim();return f.length>0?f.toLowerCase():void 0}function Cn(n,f){switch(n){case"aligo":return new W(f);case"mock":return new b(f);default:return typeof f.listKakaoChannels==="function"?new W(f):void 0}}class x{provider;capability;providerType;apiAdapter;iwinvAdapter;solapiAdapter;constructor(n,f=new Y){this.provider=n;if(this.capability=f.resolve(n),this.providerType=gn(this.capability.providerType),this.capability.mode==="api")this.apiAdapter=Cn(this.providerType,this.provider);else if(this.providerType==="iwinv")this.iwinvAdapter=new T(this.provider);else if(this.providerType==="solapi")this.solapiAdapter=new N(this.provider)}getCapability(){return this.capability}unsupported(n){let f=(()=>{if(this.capability.mode==="manual"){if(this.iwinvAdapter)return this.iwinvAdapter.unsupportedMessage(n);return`Provider '${this.provider.id}' requires manual Kakao channel onboarding. Operation '${n}' is unavailable via API.`}if(this.capability.mode==="none"){if(this.solapiAdapter)return this.solapiAdapter.unsupportedMessage(n);return`Provider '${this.provider.id}' does not support Kakao channel onboarding API operation '${n}'.`}return`Provider '${this.provider.id}' does not support Kakao channel onboarding API operation '${n}'.`})();return w(new A("INVALID_REQUEST",f,{providerId:this.provider.id,mode:this.capability.mode,operation:n}))}ensureApi(n){if(this.capability.mode!=="api")return this.unsupported(n);if(!this.apiAdapter)return w(new A("INVALID_REQUEST",`Provider '${this.provider.id}' is marked as api mode but does not expose kakao channel operations`,{providerId:this.provider.id,mode:this.capability.mode,operation:n}));return F(void 0)}async list(n){let f=this.ensureApi("list");if(f.isFailure)return f;let i=this.apiAdapter;if(!i)return this.unsupported("list");let K=await i.list(n);if(K.isFailure)return K;return F(K.value.map((P)=>({source:"api",providerId:P.providerId||this.provider.id,senderKey:P.senderKey,...P.plusId?{plusId:P.plusId}:{},...P.name?{name:P.name}:{},...P.status?{status:P.status}:{}})))}async categories(){let n=this.ensureApi("categories");if(n.isFailure)return n;let f=this.apiAdapter;if(!f)return this.unsupported("categories");return f.categories()}async auth(n){let f=this.ensureApi("auth");if(f.isFailure)return f;let i=this.apiAdapter;if(!i)return this.unsupported("auth");return i.auth(n)}async add(n){let f=this.ensureApi("add");if(f.isFailure)return f;let i=this.apiAdapter;if(!i)return this.unsupported("add");return i.add(n)}}
|
|
2
2
|
|
|
3
|
-
//# debugId=
|
|
3
|
+
//# debugId=32A104C9BC685D0564756E2164756E21
|
|
4
4
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../core/src/errors.ts", "../../core/src/result.ts", "../src/runtime/kakao-channel-binding-resolver.ts", "../src/runtime/kakao-channel-capability.service.ts", "../src/runtime/adapters/aligo.adapter.ts", "../src/runtime/adapters/iwinv.adapter.ts", "../src/runtime/adapters/mock.adapter.ts", "../src/runtime/adapters/solapi.adapter.ts", "../src/runtime/kakao-channel-lifecycle.service.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"export type Locale = \"ko\" | \"en\";\n\nexport enum KMsgErrorCode {\n INVALID_REQUEST = \"INVALID_REQUEST\",\n AUTHENTICATION_FAILED = \"AUTHENTICATION_FAILED\",\n INSUFFICIENT_BALANCE = \"INSUFFICIENT_BALANCE\",\n TEMPLATE_NOT_FOUND = \"TEMPLATE_NOT_FOUND\",\n RATE_LIMIT_EXCEEDED = \"RATE_LIMIT_EXCEEDED\",\n NETWORK_ERROR = \"NETWORK_ERROR\",\n NETWORK_TIMEOUT = \"NETWORK_TIMEOUT\",\n NETWORK_SERVICE_UNAVAILABLE = \"NETWORK_SERVICE_UNAVAILABLE\",\n PROVIDER_ERROR = \"PROVIDER_ERROR\",\n MESSAGE_SEND_FAILED = \"MESSAGE_SEND_FAILED\",\n CRYPTO_CONFIG_ERROR = \"CRYPTO_CONFIG_ERROR\",\n CRYPTO_ENCRYPT_FAILED = \"CRYPTO_ENCRYPT_FAILED\",\n CRYPTO_DECRYPT_FAILED = \"CRYPTO_DECRYPT_FAILED\",\n CRYPTO_HASH_FAILED = \"CRYPTO_HASH_FAILED\",\n CRYPTO_POLICY_VIOLATION = \"CRYPTO_POLICY_VIOLATION\",\n UNKNOWN_ERROR = \"UNKNOWN_ERROR\",\n}\n\nconst DEFAULT_LOCALE: Locale = \"ko\";\n\nconst ERROR_MESSAGES: Record<KMsgErrorCode, { ko: string; en: string }> = {\n [KMsgErrorCode.INVALID_REQUEST]: {\n ko: \"잘못된 요청입니다\",\n en: \"Invalid request\",\n },\n [KMsgErrorCode.AUTHENTICATION_FAILED]: {\n ko: \"인증에 실패했습니다\",\n en: \"Authentication failed\",\n },\n [KMsgErrorCode.INSUFFICIENT_BALANCE]: {\n ko: \"잔액이 부족합니다\",\n en: \"Insufficient balance\",\n },\n [KMsgErrorCode.TEMPLATE_NOT_FOUND]: {\n ko: \"템플릿을 찾을 수 없습니다\",\n en: \"Template not found\",\n },\n [KMsgErrorCode.RATE_LIMIT_EXCEEDED]: {\n ko: \"요청 한도를 초과했습니다\",\n en: \"Rate limit exceeded\",\n },\n [KMsgErrorCode.NETWORK_ERROR]: {\n ko: \"네트워크 오류가 발생했습니다\",\n en: \"Network error\",\n },\n [KMsgErrorCode.NETWORK_TIMEOUT]: {\n ko: \"네트워크 요청 시간이 초과되었습니다\",\n en: \"Network timeout\",\n },\n [KMsgErrorCode.NETWORK_SERVICE_UNAVAILABLE]: {\n ko: \"서비스를 일시적으로 사용할 수 없습니다\",\n en: \"Service temporarily unavailable\",\n },\n [KMsgErrorCode.PROVIDER_ERROR]: {\n ko: \"제공자 오류가 발생했습니다\",\n en: \"Provider error\",\n },\n [KMsgErrorCode.MESSAGE_SEND_FAILED]: {\n ko: \"메시지 전송에 실패했습니다\",\n en: \"Message send failed\",\n },\n [KMsgErrorCode.CRYPTO_CONFIG_ERROR]: {\n ko: \"암호화 설정 오류가 발생했습니다\",\n en: \"Crypto configuration error\",\n },\n [KMsgErrorCode.CRYPTO_ENCRYPT_FAILED]: {\n ko: \"암호화에 실패했습니다\",\n en: \"Encryption failed\",\n },\n [KMsgErrorCode.CRYPTO_DECRYPT_FAILED]: {\n ko: \"복호화에 실패했습니다\",\n en: \"Decryption failed\",\n },\n [KMsgErrorCode.CRYPTO_HASH_FAILED]: {\n ko: \"해시 생성에 실패했습니다\",\n en: \"Hash generation failed\",\n },\n [KMsgErrorCode.CRYPTO_POLICY_VIOLATION]: {\n ko: \"암호화 정책 위반이 발생했습니다\",\n en: \"Crypto policy violation\",\n },\n [KMsgErrorCode.UNKNOWN_ERROR]: {\n ko: \"알 수 없는 오류가 발생했습니다\",\n en: \"Unknown error\",\n },\n};\n\nexport type RetryPolicyErrorCode = KMsgErrorCode;\n\nexport type ProviderRetryHint = \"retryable\" | \"non_retryable\";\n\nexport interface KMsgErrorMetadata {\n providerErrorCode?: string;\n providerErrorText?: string;\n httpStatus?: number;\n requestId?: string;\n retryAfterMs?: number;\n attempt?: number;\n causeChain?: unknown[];\n}\n\nexport interface ErrorRetryPolicy {\n retryableCodes?: readonly KMsgErrorCode[];\n nonRetryableCodes?: readonly KMsgErrorCode[];\n classifyByStatusCode?: (status: number) => ProviderRetryHint;\n classifyByMessage?: (message: string) => ProviderRetryHint | undefined;\n /**\n * Optional override for retry hint inference.\n */\n fallback?: ProviderRetryHint;\n /**\n * Optional custom retry delay in milliseconds.\n */\n retryAfterMs?: (error: KMsgError) => number | undefined;\n}\n\nconst DEFAULT_RETRYABLE_ERROR_CODES: ReadonlySet<RetryPolicyErrorCode> =\n new Set([\n KMsgErrorCode.NETWORK_ERROR,\n KMsgErrorCode.RATE_LIMIT_EXCEEDED,\n KMsgErrorCode.NETWORK_TIMEOUT,\n KMsgErrorCode.NETWORK_SERVICE_UNAVAILABLE,\n KMsgErrorCode.PROVIDER_ERROR,\n KMsgErrorCode.UNKNOWN_ERROR,\n ]);\n\nconst DEFAULT_NON_RETRYABLE_ERROR_CODES: ReadonlySet<RetryPolicyErrorCode> =\n new Set([\n KMsgErrorCode.INVALID_REQUEST,\n KMsgErrorCode.AUTHENTICATION_FAILED,\n KMsgErrorCode.INSUFFICIENT_BALANCE,\n KMsgErrorCode.TEMPLATE_NOT_FOUND,\n KMsgErrorCode.MESSAGE_SEND_FAILED,\n KMsgErrorCode.CRYPTO_CONFIG_ERROR,\n KMsgErrorCode.CRYPTO_ENCRYPT_FAILED,\n KMsgErrorCode.CRYPTO_DECRYPT_FAILED,\n KMsgErrorCode.CRYPTO_HASH_FAILED,\n KMsgErrorCode.CRYPTO_POLICY_VIOLATION,\n ]);\n\nconst normalizeNumber = (value: unknown): number | undefined => {\n if (\n typeof value !== \"number\" ||\n Number.isNaN(value) ||\n !Number.isFinite(value)\n ) {\n return undefined;\n }\n\n return Math.trunc(value);\n};\n\nexport const normalizeRetryAfterMs = (value: unknown): number | undefined => {\n const normalized = normalizeNumber(value);\n if (normalized === undefined || normalized < 0) {\n return undefined;\n }\n\n return normalized;\n};\n\nconst toLowerString = (value: unknown): string | undefined => {\n if (typeof value !== \"string\") {\n return undefined;\n }\n\n return value.toLowerCase().trim();\n};\n\nconst classifyByHttpStatus = (status: number): ProviderRetryHint => {\n if (status >= 500) {\n return \"retryable\";\n }\n\n if (status === 408 || status === 425 || status === 429) {\n return \"retryable\";\n }\n\n return \"non_retryable\";\n};\n\nconst classifyByMessage = (message: string): ProviderRetryHint | undefined => {\n const normalized = message.toLowerCase();\n\n if (\n normalized.includes(\"timeout\") ||\n normalized.includes(\"temporar\") ||\n normalized.includes(\"network\") ||\n normalized.includes(\"retry\")\n ) {\n return \"retryable\";\n }\n\n return undefined;\n};\n\nexport class KMsgError extends Error {\n public readonly code: KMsgErrorCode;\n public readonly details?: Record<string, unknown>;\n public readonly providerErrorCode?: string;\n public readonly providerErrorText?: string;\n public readonly httpStatus?: number;\n public readonly requestId?: string;\n public readonly retryAfterMs?: number;\n public readonly attempt?: number;\n public readonly causeChain?: unknown[];\n\n constructor(\n code: KMsgErrorCode,\n message: string,\n details?: Record<string, unknown>,\n metadata: KMsgErrorMetadata = {},\n ) {\n super(message);\n this.name = \"KMsgError\";\n this.code = code;\n this.details = details;\n\n this.providerErrorCode = metadata.providerErrorCode;\n this.providerErrorText = metadata.providerErrorText;\n this.httpStatus = normalizeNumber(metadata.httpStatus);\n this.requestId =\n typeof metadata.requestId === \"string\" ? metadata.requestId : undefined;\n this.retryAfterMs = normalizeNumber(metadata.retryAfterMs);\n this.attempt = normalizeNumber(metadata.attempt);\n\n if (Array.isArray(metadata.causeChain)) {\n this.causeChain = metadata.causeChain;\n } else if (metadata.causeChain !== undefined) {\n this.causeChain = [metadata.causeChain];\n }\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, KMsgError);\n }\n }\n\n /**\n * Returns a localized error message based on the provided locale.\n * Falls back to Korean (default) if locale is not provided.\n * Falls back to the original message if no localized message exists.\n */\n getLocalizedMessage(locale: Locale = DEFAULT_LOCALE): string {\n const messages = ERROR_MESSAGES[this.code];\n if (messages?.[locale]) {\n return messages[locale];\n }\n return this.message;\n }\n\n toJSON() {\n return {\n name: this.name,\n code: this.code,\n message: this.message,\n details: this.details,\n providerErrorCode: this.providerErrorCode,\n providerErrorText: this.providerErrorText,\n httpStatus: this.httpStatus,\n requestId: this.requestId,\n retryAfterMs: this.retryAfterMs,\n attempt: this.attempt,\n causeChain: this.causeChain,\n };\n }\n}\n\nexport const ErrorUtils = {\n isRetryable(error: unknown, policy: ErrorRetryPolicy = {}): boolean {\n return ErrorUtils.classifyForRetry(error, policy) === \"retryable\";\n },\n\n classifyForRetry(\n error: unknown,\n policy: ErrorRetryPolicy = {},\n ): ProviderRetryHint {\n if (error instanceof KMsgError) {\n const retryableCodes = new Set(\n policy.retryableCodes ?? Array.from(DEFAULT_RETRYABLE_ERROR_CODES),\n );\n if (retryableCodes.has(error.code)) {\n return \"retryable\";\n }\n\n const nonRetryableCodes = new Set(\n policy.nonRetryableCodes ??\n Array.from(DEFAULT_NON_RETRYABLE_ERROR_CODES),\n );\n if (nonRetryableCodes.has(error.code)) {\n return \"non_retryable\";\n }\n\n if (error.httpStatus !== undefined) {\n return classifyByHttpStatus(error.httpStatus);\n }\n\n const classifiedByMessage = classifyByMessage(error.message);\n if (classifiedByMessage) {\n return classifiedByMessage;\n }\n\n if (policy.classifyByMessage && error.message) {\n const classified = policy.classifyByMessage(error.message);\n if (classified) {\n return classified;\n }\n }\n\n if (policy.fallback) {\n return policy.fallback;\n }\n\n return \"non_retryable\";\n }\n\n const candidate =\n error && typeof error === \"object\"\n ? (error as {\n status?: unknown;\n statusCode?: unknown;\n httpStatus?: unknown;\n code?: unknown;\n message?: unknown;\n })\n : undefined;\n\n const status =\n toLowerString(candidate?.status) ??\n toLowerString(candidate?.statusCode) ??\n toLowerString(candidate?.code);\n const statusCode =\n normalizeNumber(candidate?.status) ??\n normalizeNumber(candidate?.statusCode) ??\n normalizeNumber(candidate?.httpStatus);\n\n if (typeof status === \"string\" && status.startsWith(\"5\")) {\n return \"retryable\";\n }\n\n if (statusCode !== undefined) {\n if (policy.classifyByStatusCode) {\n return policy.classifyByStatusCode(statusCode);\n }\n\n return classifyByHttpStatus(statusCode);\n }\n\n const classifiedByMessage =\n typeof candidate?.message === \"string\"\n ? classifyByMessage(candidate.message)\n : undefined;\n\n if (classifiedByMessage) {\n return classifiedByMessage;\n }\n\n if (policy.classifyByMessage && typeof candidate?.message === \"string\") {\n const classified = policy.classifyByMessage(candidate.message);\n if (classified) {\n return classified;\n }\n }\n\n return policy.fallback ?? \"non_retryable\";\n },\n\n resolveRetryAfterMs(\n error: KMsgError,\n policy?: ErrorRetryPolicy,\n ): number | undefined {\n if (policy?.retryAfterMs) {\n const override = policy.retryAfterMs(error);\n const normalized = normalizeRetryAfterMs(override);\n if (normalized !== undefined) {\n return normalized;\n }\n }\n\n if (error.retryAfterMs !== undefined) {\n return normalizeRetryAfterMs(error.retryAfterMs);\n }\n\n if (\n error.code === KMsgErrorCode.RATE_LIMIT_EXCEEDED &&\n error.retryAfterMs === undefined\n ) {\n return undefined;\n }\n\n return undefined;\n },\n\n isUnknownStatus: (statusCode: number | undefined): boolean => {\n if (\n statusCode === undefined ||\n Number.isNaN(statusCode) ||\n !Number.isFinite(statusCode)\n ) {\n return false;\n }\n\n return statusCode < 500;\n },\n\n toRetryMetadata(error: KMsgError): KMsgErrorMetadata {\n return {\n providerErrorCode: error.providerErrorCode,\n providerErrorText: error.providerErrorText,\n httpStatus: error.httpStatus,\n requestId: error.requestId,\n retryAfterMs: error.retryAfterMs,\n attempt: error.attempt,\n causeChain: error.causeChain,\n };\n },\n\n withAttempt(error: KMsgError, attempt: number): KMsgError {\n return new KMsgError(error.code, error.message, error.details, {\n ...ErrorUtils.toRetryMetadata(error),\n attempt: normalizeNumber(attempt),\n });\n },\n\n DEFAULT_RETRYABLE_ERROR_CODES,\n DEFAULT_NON_RETRYABLE_ERROR_CODES,\n};\n",
|
|
5
|
+
"export type Locale = \"ko\" | \"en\";\n\nexport enum KMsgErrorCode {\n INVALID_REQUEST = \"INVALID_REQUEST\",\n AUTHENTICATION_FAILED = \"AUTHENTICATION_FAILED\",\n INSUFFICIENT_BALANCE = \"INSUFFICIENT_BALANCE\",\n TEMPLATE_NOT_FOUND = \"TEMPLATE_NOT_FOUND\",\n RATE_LIMIT_EXCEEDED = \"RATE_LIMIT_EXCEEDED\",\n NETWORK_ERROR = \"NETWORK_ERROR\",\n NETWORK_TIMEOUT = \"NETWORK_TIMEOUT\",\n NETWORK_SERVICE_UNAVAILABLE = \"NETWORK_SERVICE_UNAVAILABLE\",\n PROVIDER_ERROR = \"PROVIDER_ERROR\",\n MESSAGE_SEND_FAILED = \"MESSAGE_SEND_FAILED\",\n CRYPTO_CONFIG_ERROR = \"CRYPTO_CONFIG_ERROR\",\n CRYPTO_ENCRYPT_FAILED = \"CRYPTO_ENCRYPT_FAILED\",\n CRYPTO_DECRYPT_FAILED = \"CRYPTO_DECRYPT_FAILED\",\n CRYPTO_HASH_FAILED = \"CRYPTO_HASH_FAILED\",\n CRYPTO_POLICY_VIOLATION = \"CRYPTO_POLICY_VIOLATION\",\n UNKNOWN_ERROR = \"UNKNOWN_ERROR\",\n}\n\nconst DEFAULT_LOCALE: Locale = \"ko\";\n\nconst ERROR_MESSAGES: Record<KMsgErrorCode, { ko: string; en: string }> = {\n [KMsgErrorCode.INVALID_REQUEST]: {\n ko: \"잘못된 요청입니다\",\n en: \"Invalid request\",\n },\n [KMsgErrorCode.AUTHENTICATION_FAILED]: {\n ko: \"인증에 실패했습니다\",\n en: \"Authentication failed\",\n },\n [KMsgErrorCode.INSUFFICIENT_BALANCE]: {\n ko: \"잔액이 부족합니다\",\n en: \"Insufficient balance\",\n },\n [KMsgErrorCode.TEMPLATE_NOT_FOUND]: {\n ko: \"템플릿을 찾을 수 없습니다\",\n en: \"Template not found\",\n },\n [KMsgErrorCode.RATE_LIMIT_EXCEEDED]: {\n ko: \"요청 한도를 초과했습니다\",\n en: \"Rate limit exceeded\",\n },\n [KMsgErrorCode.NETWORK_ERROR]: {\n ko: \"네트워크 오류가 발생했습니다\",\n en: \"Network error\",\n },\n [KMsgErrorCode.NETWORK_TIMEOUT]: {\n ko: \"네트워크 요청 시간이 초과되었습니다\",\n en: \"Network timeout\",\n },\n [KMsgErrorCode.NETWORK_SERVICE_UNAVAILABLE]: {\n ko: \"서비스를 일시적으로 사용할 수 없습니다\",\n en: \"Service temporarily unavailable\",\n },\n [KMsgErrorCode.PROVIDER_ERROR]: {\n ko: \"제공자 오류가 발생했습니다\",\n en: \"Provider error\",\n },\n [KMsgErrorCode.MESSAGE_SEND_FAILED]: {\n ko: \"메시지 전송에 실패했습니다\",\n en: \"Message send failed\",\n },\n [KMsgErrorCode.CRYPTO_CONFIG_ERROR]: {\n ko: \"암호화 설정 오류가 발생했습니다\",\n en: \"Crypto configuration error\",\n },\n [KMsgErrorCode.CRYPTO_ENCRYPT_FAILED]: {\n ko: \"암호화에 실패했습니다\",\n en: \"Encryption failed\",\n },\n [KMsgErrorCode.CRYPTO_DECRYPT_FAILED]: {\n ko: \"복호화에 실패했습니다\",\n en: \"Decryption failed\",\n },\n [KMsgErrorCode.CRYPTO_HASH_FAILED]: {\n ko: \"해시 생성에 실패했습니다\",\n en: \"Hash generation failed\",\n },\n [KMsgErrorCode.CRYPTO_POLICY_VIOLATION]: {\n ko: \"암호화 정책 위반이 발생했습니다\",\n en: \"Crypto policy violation\",\n },\n [KMsgErrorCode.UNKNOWN_ERROR]: {\n ko: \"알 수 없는 오류가 발생했습니다\",\n en: \"Unknown error\",\n },\n};\n\nexport type RetryPolicyErrorCode = KMsgErrorCode;\n\nexport type ProviderRetryHint = \"retryable\" | \"non_retryable\";\n\nexport interface KMsgErrorMetadata {\n providerErrorCode?: string;\n providerErrorText?: string;\n httpStatus?: number;\n requestId?: string;\n retryAfterMs?: number;\n attempt?: number;\n causeChain?: unknown[];\n}\n\nexport interface ErrorRetryPolicy {\n retryableCodes?: readonly KMsgErrorCode[];\n nonRetryableCodes?: readonly KMsgErrorCode[];\n classifyByStatusCode?: (status: number) => ProviderRetryHint;\n classifyByMessage?: (message: string) => ProviderRetryHint | undefined;\n /**\n * Optional override for retry hint inference.\n */\n fallback?: ProviderRetryHint;\n /**\n * Optional custom retry delay in milliseconds.\n */\n retryAfterMs?: (error: KMsgError) => number | undefined;\n}\n\nexport type ErrorRetryPolicyMode = \"safe\" | \"compat\";\n\nexport interface ErrorRetryPolicyIssue {\n code: string;\n message: string;\n path: string;\n}\n\nexport interface ErrorRetryPolicyValidationResult {\n policy: ErrorRetryPolicy | null;\n issues: ErrorRetryPolicyIssue[];\n}\n\nexport interface ErrorRetryPolicyNormalizeOptions {\n mode?: ErrorRetryPolicyMode;\n}\n\nexport type ProviderErrorSource =\n | \"metadata\"\n | \"details\"\n | \"http\"\n | \"fallback\"\n | \"policy\"\n | \"input\";\n\nexport interface NormalizedProviderErrorSources {\n code: ProviderErrorSource;\n classification: ProviderErrorSource;\n providerErrorCode?: ProviderErrorSource;\n providerErrorText?: ProviderErrorSource;\n httpStatus?: ProviderErrorSource;\n requestId?: ProviderErrorSource;\n retryAfterMs?: ProviderErrorSource;\n causeChain?: ProviderErrorSource;\n attempt?: ProviderErrorSource;\n}\n\nexport interface NormalizedProviderError {\n code: KMsgErrorCode;\n classification: ProviderRetryHint;\n providerErrorCode?: string;\n providerErrorText?: string;\n httpStatus?: number;\n requestId?: string;\n retryAfterMs?: number;\n causeChain?: unknown[];\n attempt?: number;\n sources: NormalizedProviderErrorSources;\n}\n\nexport interface NormalizeProviderErrorOptions {\n mode?: ErrorRetryPolicyMode;\n policy?: ErrorRetryPolicy;\n attempt?: number;\n defaultCode?: KMsgErrorCode;\n}\n\nconst KNOWN_KMSG_ERROR_CODES: ReadonlySet<string> = new Set(\n Object.values(KMsgErrorCode),\n);\n\nconst DEFAULT_RETRYABLE_ERROR_CODES: ReadonlySet<RetryPolicyErrorCode> =\n new Set([\n KMsgErrorCode.NETWORK_ERROR,\n KMsgErrorCode.RATE_LIMIT_EXCEEDED,\n KMsgErrorCode.NETWORK_TIMEOUT,\n KMsgErrorCode.NETWORK_SERVICE_UNAVAILABLE,\n KMsgErrorCode.PROVIDER_ERROR,\n KMsgErrorCode.UNKNOWN_ERROR,\n ]);\n\nconst DEFAULT_NON_RETRYABLE_ERROR_CODES: ReadonlySet<RetryPolicyErrorCode> =\n new Set([\n KMsgErrorCode.INVALID_REQUEST,\n KMsgErrorCode.AUTHENTICATION_FAILED,\n KMsgErrorCode.INSUFFICIENT_BALANCE,\n KMsgErrorCode.TEMPLATE_NOT_FOUND,\n KMsgErrorCode.MESSAGE_SEND_FAILED,\n KMsgErrorCode.CRYPTO_CONFIG_ERROR,\n KMsgErrorCode.CRYPTO_ENCRYPT_FAILED,\n KMsgErrorCode.CRYPTO_DECRYPT_FAILED,\n KMsgErrorCode.CRYPTO_HASH_FAILED,\n KMsgErrorCode.CRYPTO_POLICY_VIOLATION,\n ]);\n\nconst normalizeNumber = (value: unknown): number | undefined => {\n if (\n typeof value !== \"number\" ||\n Number.isNaN(value) ||\n !Number.isFinite(value)\n ) {\n return undefined;\n }\n\n return Math.trunc(value);\n};\n\nexport const normalizeRetryAfterMs = (value: unknown): number | undefined => {\n const normalized = normalizeNumber(value);\n if (normalized === undefined || normalized < 0) {\n return undefined;\n }\n\n return normalized;\n};\n\nconst toLowerString = (value: unknown): string | undefined => {\n if (typeof value !== \"string\") {\n return undefined;\n }\n\n return value.toLowerCase().trim();\n};\n\nconst toTrimmedString = (value: unknown): string | undefined => {\n if (typeof value !== \"string\") {\n return undefined;\n }\n\n const normalized = value.trim();\n return normalized.length > 0 ? normalized : undefined;\n};\n\nconst isObjectRecord = (value: unknown): value is Record<string, unknown> => {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n};\n\nconst pickByKey = (\n value: Record<string, unknown>,\n keys: readonly string[],\n): unknown => {\n for (const key of keys) {\n if (key in value) {\n return value[key];\n }\n }\n return undefined;\n};\n\nconst ensureIssuePath = (path: string): string => {\n return path.length > 0 ? path : \"$\";\n};\n\nconst normalizePolicyMode = (\n mode: ErrorRetryPolicyMode | undefined,\n): ErrorRetryPolicyMode => {\n return mode === \"compat\" ? \"compat\" : \"safe\";\n};\n\nconst classifyByHttpStatus = (status: number): ProviderRetryHint => {\n if (status >= 500) {\n return \"retryable\";\n }\n\n if (status === 408 || status === 425 || status === 429) {\n return \"retryable\";\n }\n\n return \"non_retryable\";\n};\n\nconst classifyByMessage = (message: string): ProviderRetryHint | undefined => {\n const normalized = message.toLowerCase();\n\n if (\n normalized.includes(\"timeout\") ||\n normalized.includes(\"temporar\") ||\n normalized.includes(\"network\") ||\n normalized.includes(\"retry\")\n ) {\n return \"retryable\";\n }\n\n return undefined;\n};\n\nexport class KMsgError extends Error {\n public readonly code: KMsgErrorCode;\n public readonly details?: Record<string, unknown>;\n public readonly providerErrorCode?: string;\n public readonly providerErrorText?: string;\n public readonly httpStatus?: number;\n public readonly requestId?: string;\n public readonly retryAfterMs?: number;\n public readonly attempt?: number;\n public readonly causeChain?: unknown[];\n\n constructor(\n code: KMsgErrorCode,\n message: string,\n details?: Record<string, unknown>,\n metadata: KMsgErrorMetadata = {},\n ) {\n super(message);\n this.name = \"KMsgError\";\n this.code = code;\n this.details = details;\n\n this.providerErrorCode = metadata.providerErrorCode;\n this.providerErrorText = metadata.providerErrorText;\n this.httpStatus = normalizeNumber(metadata.httpStatus);\n this.requestId =\n typeof metadata.requestId === \"string\" ? metadata.requestId : undefined;\n this.retryAfterMs = normalizeNumber(metadata.retryAfterMs);\n this.attempt = normalizeNumber(metadata.attempt);\n\n if (Array.isArray(metadata.causeChain)) {\n this.causeChain = metadata.causeChain;\n } else if (metadata.causeChain !== undefined) {\n this.causeChain = [metadata.causeChain];\n }\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, KMsgError);\n }\n }\n\n /**\n * Returns a localized error message based on the provided locale.\n * Falls back to Korean (default) if locale is not provided.\n * Falls back to the original message if no localized message exists.\n */\n getLocalizedMessage(locale: Locale = DEFAULT_LOCALE): string {\n const messages = ERROR_MESSAGES[this.code];\n if (messages?.[locale]) {\n return messages[locale];\n }\n return this.message;\n }\n\n toJSON() {\n return {\n name: this.name,\n code: this.code,\n message: this.message,\n details: this.details,\n providerErrorCode: this.providerErrorCode,\n providerErrorText: this.providerErrorText,\n httpStatus: this.httpStatus,\n requestId: this.requestId,\n retryAfterMs: this.retryAfterMs,\n attempt: this.attempt,\n causeChain: this.causeChain,\n };\n }\n}\n\nconst normalizeIntegerLike = (\n value: unknown,\n mode: ErrorRetryPolicyMode,\n): number | undefined => {\n const normalized = normalizeNumber(value);\n if (normalized !== undefined) return normalized;\n\n if (mode === \"compat\" && typeof value === \"string\") {\n const parsed = Number(value.trim());\n if (Number.isFinite(parsed)) {\n return Math.trunc(parsed);\n }\n }\n\n return undefined;\n};\n\nconst normalizeStringLike = (\n value: unknown,\n mode: ErrorRetryPolicyMode,\n): string | undefined => {\n const fromString = toTrimmedString(value);\n if (fromString) return fromString;\n\n if (\n mode === \"compat\" &&\n (typeof value === \"number\" || typeof value === \"boolean\")\n ) {\n return String(value);\n }\n\n return undefined;\n};\n\nconst normalizeKMsgErrorCode = (value: unknown): KMsgErrorCode | undefined => {\n if (typeof value !== \"string\") {\n return undefined;\n }\n\n const normalized = value.trim().toUpperCase();\n if (!KNOWN_KMSG_ERROR_CODES.has(normalized)) {\n return undefined;\n }\n\n return normalized as KMsgErrorCode;\n};\n\nconst pushPolicyIssue = (\n issues: ErrorRetryPolicyIssue[],\n issue: ErrorRetryPolicyIssue,\n) => {\n issues.push({\n ...issue,\n path: ensureIssuePath(issue.path),\n });\n};\n\nconst normalizePolicyCodeList = (\n value: unknown,\n path: string,\n mode: ErrorRetryPolicyMode,\n issues: ErrorRetryPolicyIssue[],\n): KMsgErrorCode[] => {\n if (value === undefined) return [];\n\n const items: unknown[] = (() => {\n if (Array.isArray(value)) return value;\n if (mode === \"compat\" && typeof value === \"string\") {\n return value\n .split(\",\")\n .map((item) => item.trim())\n .filter((item) => item.length > 0);\n }\n\n pushPolicyIssue(issues, {\n code: \"invalid_type\",\n message: \"expected array of KMsgErrorCode values\",\n path,\n });\n return [];\n })();\n\n const out: KMsgErrorCode[] = [];\n const seen = new Set<KMsgErrorCode>();\n\n for (let index = 0; index < items.length; index += 1) {\n const item = items[index];\n const code = normalizeKMsgErrorCode(\n typeof item === \"string\" ? item : mode === \"compat\" ? String(item) : item,\n );\n\n if (!code) {\n pushPolicyIssue(issues, {\n code: \"unknown_code\",\n message: `unknown retry policy code: ${String(item)}`,\n path: `${path}[${index}]`,\n });\n continue;\n }\n\n if (seen.has(code)) {\n pushPolicyIssue(issues, {\n code: \"duplicate_code\",\n message: `duplicate retry policy code: ${code}`,\n path: `${path}[${index}]`,\n });\n continue;\n }\n\n seen.add(code);\n out.push(code);\n }\n\n return out;\n};\n\nconst normalizeRetryFallback = (\n value: unknown,\n mode: ErrorRetryPolicyMode,\n issues: ErrorRetryPolicyIssue[],\n): ProviderRetryHint | undefined => {\n if (value === undefined) return undefined;\n\n if (typeof value === \"string\") {\n const normalized = value.trim().toLowerCase();\n if (normalized === \"retryable\") return \"retryable\";\n if (normalized === \"non_retryable\" || normalized === \"non-retryable\") {\n return \"non_retryable\";\n }\n }\n\n if (mode === \"compat\" && typeof value === \"boolean\") {\n return value ? \"retryable\" : \"non_retryable\";\n }\n\n pushPolicyIssue(issues, {\n code: \"invalid_fallback\",\n message: `invalid fallback value: ${String(value)}`,\n path: \"fallback\",\n });\n return undefined;\n};\n\nexport function validateErrorRetryPolicy(\n input: unknown,\n options: ErrorRetryPolicyNormalizeOptions = {},\n): ErrorRetryPolicyValidationResult {\n const mode = normalizePolicyMode(options.mode);\n const issues: ErrorRetryPolicyIssue[] = [];\n\n if (!isObjectRecord(input)) {\n pushPolicyIssue(issues, {\n code: \"invalid_root\",\n message: \"retry policy must be an object\",\n path: \"$\",\n });\n return { policy: null, issues };\n }\n\n const knownKeys = new Set([\n \"retryableCodes\",\n \"nonRetryableCodes\",\n \"fallback\",\n ]);\n for (const key of Object.keys(input)) {\n if (knownKeys.has(key)) continue;\n pushPolicyIssue(issues, {\n code: \"unknown_field\",\n message: `unknown retry policy field: ${key}`,\n path: key,\n });\n }\n\n const retryableCodes = normalizePolicyCodeList(\n input.retryableCodes,\n \"retryableCodes\",\n mode,\n issues,\n );\n const nonRetryableCodes = normalizePolicyCodeList(\n input.nonRetryableCodes,\n \"nonRetryableCodes\",\n mode,\n issues,\n );\n const fallback = normalizeRetryFallback(input.fallback, mode, issues);\n\n const retryableSet = new Set(retryableCodes);\n const nonRetryableSet = new Set(nonRetryableCodes);\n\n for (const code of retryableSet) {\n if (!nonRetryableSet.has(code)) continue;\n retryableSet.delete(code);\n pushPolicyIssue(issues, {\n code: \"conflicting_code\",\n message: `code '${code}' is both retryable and nonRetryable; nonRetryable wins`,\n path: \"retryableCodes\",\n });\n }\n\n const policy: ErrorRetryPolicy = {\n ...(retryableSet.size > 0\n ? { retryableCodes: Array.from(retryableSet) }\n : {}),\n ...(nonRetryableSet.size > 0\n ? { nonRetryableCodes: Array.from(nonRetryableSet) }\n : {}),\n ...(fallback ? { fallback } : {}),\n };\n\n const hasConfig =\n policy.retryableCodes !== undefined ||\n policy.nonRetryableCodes !== undefined ||\n policy.fallback !== undefined;\n\n return {\n policy: hasConfig ? policy : null,\n issues,\n };\n}\n\nexport function normalizeErrorRetryPolicy(\n input: unknown,\n options: ErrorRetryPolicyNormalizeOptions = {},\n): ErrorRetryPolicy | null {\n return validateErrorRetryPolicy(input, options).policy;\n}\n\nexport function parseErrorRetryPolicyFromJson(\n raw: string,\n options: ErrorRetryPolicyNormalizeOptions = {},\n): ErrorRetryPolicy | null {\n if (typeof raw !== \"string\" || raw.trim().length === 0) {\n return null;\n }\n\n try {\n const parsed = JSON.parse(raw);\n return normalizeErrorRetryPolicy(parsed, options);\n } catch {\n return null;\n }\n}\n\nconst resolveNestedHttpStatus = (\n record: Record<string, unknown>,\n mode: ErrorRetryPolicyMode,\n): number | undefined => {\n const response = record.response;\n if (!isObjectRecord(response)) {\n return undefined;\n }\n\n return normalizeIntegerLike(\n pickByKey(response, [\"status\", \"statusCode\", \"httpStatus\"]),\n mode,\n );\n};\n\nconst resolveCauseChain = (\n error: unknown,\n mode: ErrorRetryPolicyMode,\n): unknown[] | undefined => {\n if (error instanceof KMsgError && Array.isArray(error.causeChain)) {\n return error.causeChain.slice();\n }\n\n if (isObjectRecord(error)) {\n const fromChain = error.causeChain;\n if (Array.isArray(fromChain)) {\n return fromChain.slice();\n }\n\n const details = error.details;\n if (mode === \"compat\" && isObjectRecord(details)) {\n const detailChain = details.causeChain;\n if (Array.isArray(detailChain)) {\n return detailChain.slice();\n }\n if (detailChain !== undefined) {\n return [detailChain];\n }\n }\n }\n\n const chain: unknown[] = [];\n const seen = new Set<unknown>();\n let cursor: unknown = error;\n\n for (let depth = 0; depth < 8; depth += 1) {\n if (!isObjectRecord(cursor)) break;\n const cause = cursor.cause;\n if (cause === undefined || seen.has(cause)) break;\n seen.add(cause);\n chain.push(cause);\n cursor = cause;\n }\n\n return chain.length > 0 ? chain : undefined;\n};\n\nconst resolveErrorMessage = (error: unknown): string => {\n if (error instanceof Error && typeof error.message === \"string\") {\n return error.message;\n }\n\n if (isObjectRecord(error) && typeof error.message === \"string\") {\n return error.message;\n }\n\n return typeof error === \"string\" ? error : \"Unknown error\";\n};\n\nexport function normalizeProviderError(\n error: unknown,\n options: NormalizeProviderErrorOptions = {},\n): NormalizedProviderError {\n const mode = normalizePolicyMode(options.mode);\n const defaultCode = options.defaultCode ?? KMsgErrorCode.UNKNOWN_ERROR;\n\n let code = defaultCode;\n const sources: NormalizedProviderErrorSources = {\n code: \"fallback\",\n classification: options.policy ? \"policy\" : \"fallback\",\n };\n\n let providerErrorCode: string | undefined;\n let providerErrorText: string | undefined;\n let httpStatus: number | undefined;\n let requestId: string | undefined;\n let retryAfterMs: number | undefined;\n let attempt: number | undefined;\n let causeChain: unknown[] | undefined;\n\n const assignFromMetadata = (candidate: KMsgError) => {\n if (candidate.providerErrorCode !== undefined) {\n providerErrorCode = candidate.providerErrorCode;\n sources.providerErrorCode = \"metadata\";\n }\n if (candidate.providerErrorText !== undefined) {\n providerErrorText = candidate.providerErrorText;\n sources.providerErrorText = \"metadata\";\n }\n if (candidate.httpStatus !== undefined) {\n httpStatus = candidate.httpStatus;\n sources.httpStatus = \"metadata\";\n }\n if (candidate.requestId !== undefined) {\n requestId = candidate.requestId;\n sources.requestId = \"metadata\";\n }\n if (candidate.retryAfterMs !== undefined) {\n retryAfterMs = normalizeRetryAfterMs(candidate.retryAfterMs);\n sources.retryAfterMs = \"metadata\";\n }\n if (candidate.attempt !== undefined) {\n attempt = normalizeIntegerLike(candidate.attempt, mode);\n sources.attempt = \"metadata\";\n }\n if (Array.isArray(candidate.causeChain)) {\n causeChain = candidate.causeChain.slice();\n sources.causeChain = \"metadata\";\n }\n };\n\n const assignFromRecord = (\n record: Record<string, unknown>,\n source: ProviderErrorSource,\n ) => {\n if (providerErrorCode === undefined) {\n const next = normalizeStringLike(\n pickByKey(record, [\"providerErrorCode\", \"errorCode\", \"resultCode\"]),\n mode,\n );\n if (next !== undefined) {\n providerErrorCode = next;\n sources.providerErrorCode = source;\n }\n }\n\n if (providerErrorText === undefined) {\n const next = normalizeStringLike(\n pickByKey(record, [\n \"providerErrorText\",\n \"errorMessage\",\n \"msg\",\n \"message\",\n ]),\n mode,\n );\n if (next !== undefined) {\n providerErrorText = next;\n sources.providerErrorText = source;\n }\n }\n\n if (httpStatus === undefined) {\n const next =\n normalizeIntegerLike(\n pickByKey(record, [\"httpStatus\", \"statusCode\", \"status\"]),\n mode,\n ) ?? resolveNestedHttpStatus(record, mode);\n if (next !== undefined) {\n httpStatus = next;\n sources.httpStatus = source === \"details\" ? \"details\" : \"http\";\n }\n }\n\n if (requestId === undefined) {\n const next = normalizeStringLike(\n pickByKey(record, [\"requestId\", \"request_id\", \"reqId\", \"traceId\"]),\n mode,\n );\n if (next !== undefined) {\n requestId = next;\n sources.requestId = source;\n }\n }\n\n if (retryAfterMs === undefined) {\n const next = normalizeRetryAfterMs(\n normalizeIntegerLike(\n pickByKey(record, [\"retryAfterMs\", \"retry_after_ms\", \"retryAfter\"]),\n mode,\n ),\n );\n if (next !== undefined) {\n retryAfterMs = next;\n sources.retryAfterMs = source;\n }\n }\n\n if (attempt === undefined) {\n const next = normalizeIntegerLike(record.attempt, mode);\n if (next !== undefined && next > 0) {\n attempt = next;\n sources.attempt = source;\n }\n }\n };\n\n if (error instanceof KMsgError) {\n code = error.code;\n sources.code = \"input\";\n assignFromMetadata(error);\n\n if (mode === \"compat\" && isObjectRecord(error.details)) {\n assignFromRecord(error.details, \"details\");\n }\n } else if (isObjectRecord(error)) {\n const candidateCode = normalizeKMsgErrorCode(\n pickByKey(error, [\"code\", \"errorCode\", \"resultCode\"]),\n );\n if (candidateCode !== undefined) {\n code = candidateCode;\n sources.code = \"input\";\n } else if (httpStatus === undefined) {\n const nextStatus =\n normalizeIntegerLike(\n pickByKey(error, [\"httpStatus\", \"statusCode\", \"status\"]),\n mode,\n ) ?? resolveNestedHttpStatus(error, mode);\n if (nextStatus !== undefined && nextStatus >= 500) {\n code = KMsgErrorCode.PROVIDER_ERROR;\n sources.code = \"http\";\n }\n }\n\n assignFromRecord(error, \"input\");\n if (mode === \"compat\" && isObjectRecord(error.details)) {\n assignFromRecord(error.details, \"details\");\n }\n }\n\n if (causeChain === undefined) {\n const nextCauseChain = resolveCauseChain(error, mode);\n if (nextCauseChain !== undefined) {\n causeChain = nextCauseChain;\n sources.causeChain = \"input\";\n }\n }\n\n if (\n options.attempt !== undefined &&\n normalizeIntegerLike(options.attempt, mode) !== undefined\n ) {\n const normalizedAttempt = normalizeIntegerLike(options.attempt, mode);\n if (normalizedAttempt !== undefined && normalizedAttempt > 0) {\n attempt = normalizedAttempt;\n sources.attempt = \"input\";\n }\n }\n\n const classificationProbe = new KMsgError(\n code,\n resolveErrorMessage(error),\n undefined,\n {\n providerErrorCode,\n providerErrorText,\n httpStatus,\n requestId,\n retryAfterMs,\n attempt,\n causeChain,\n },\n );\n const classification = ErrorUtils.classifyForRetry(\n classificationProbe,\n options.policy,\n );\n\n return {\n code,\n classification,\n ...(providerErrorCode !== undefined ? { providerErrorCode } : {}),\n ...(providerErrorText !== undefined ? { providerErrorText } : {}),\n ...(httpStatus !== undefined ? { httpStatus } : {}),\n ...(requestId !== undefined ? { requestId } : {}),\n ...(retryAfterMs !== undefined ? { retryAfterMs } : {}),\n ...(attempt !== undefined ? { attempt } : {}),\n ...(causeChain !== undefined ? { causeChain } : {}),\n sources,\n };\n}\n\nexport const ErrorUtils = {\n isRetryable(error: unknown, policy: ErrorRetryPolicy = {}): boolean {\n return ErrorUtils.classifyForRetry(error, policy) === \"retryable\";\n },\n\n classifyForRetry(\n error: unknown,\n policy: ErrorRetryPolicy = {},\n ): ProviderRetryHint {\n if (error instanceof KMsgError) {\n const retryableCodes = new Set(\n policy.retryableCodes ?? Array.from(DEFAULT_RETRYABLE_ERROR_CODES),\n );\n if (retryableCodes.has(error.code)) {\n return \"retryable\";\n }\n\n const nonRetryableCodes = new Set(\n policy.nonRetryableCodes ??\n Array.from(DEFAULT_NON_RETRYABLE_ERROR_CODES),\n );\n if (nonRetryableCodes.has(error.code)) {\n return \"non_retryable\";\n }\n\n if (error.httpStatus !== undefined) {\n return classifyByHttpStatus(error.httpStatus);\n }\n\n const classifiedByMessage = classifyByMessage(error.message);\n if (classifiedByMessage) {\n return classifiedByMessage;\n }\n\n if (policy.classifyByMessage && error.message) {\n const classified = policy.classifyByMessage(error.message);\n if (classified) {\n return classified;\n }\n }\n\n if (policy.fallback) {\n return policy.fallback;\n }\n\n return \"non_retryable\";\n }\n\n const candidate =\n error && typeof error === \"object\"\n ? (error as {\n status?: unknown;\n statusCode?: unknown;\n httpStatus?: unknown;\n code?: unknown;\n message?: unknown;\n })\n : undefined;\n\n const status =\n toLowerString(candidate?.status) ??\n toLowerString(candidate?.statusCode) ??\n toLowerString(candidate?.code);\n const statusCode =\n normalizeNumber(candidate?.status) ??\n normalizeNumber(candidate?.statusCode) ??\n normalizeNumber(candidate?.httpStatus);\n\n if (typeof status === \"string\" && status.startsWith(\"5\")) {\n return \"retryable\";\n }\n\n if (statusCode !== undefined) {\n if (policy.classifyByStatusCode) {\n return policy.classifyByStatusCode(statusCode);\n }\n\n return classifyByHttpStatus(statusCode);\n }\n\n const classifiedByMessage =\n typeof candidate?.message === \"string\"\n ? classifyByMessage(candidate.message)\n : undefined;\n\n if (classifiedByMessage) {\n return classifiedByMessage;\n }\n\n if (policy.classifyByMessage && typeof candidate?.message === \"string\") {\n const classified = policy.classifyByMessage(candidate.message);\n if (classified) {\n return classified;\n }\n }\n\n return policy.fallback ?? \"non_retryable\";\n },\n\n resolveRetryAfterMs(\n error: KMsgError,\n policy?: ErrorRetryPolicy,\n ): number | undefined {\n if (policy?.retryAfterMs) {\n const override = policy.retryAfterMs(error);\n const normalized = normalizeRetryAfterMs(override);\n if (normalized !== undefined) {\n return normalized;\n }\n }\n\n if (error.retryAfterMs !== undefined) {\n return normalizeRetryAfterMs(error.retryAfterMs);\n }\n\n if (\n error.code === KMsgErrorCode.RATE_LIMIT_EXCEEDED &&\n error.retryAfterMs === undefined\n ) {\n return undefined;\n }\n\n return undefined;\n },\n\n isUnknownStatus: (statusCode: number | undefined): boolean => {\n if (\n statusCode === undefined ||\n Number.isNaN(statusCode) ||\n !Number.isFinite(statusCode)\n ) {\n return false;\n }\n\n return statusCode < 500;\n },\n\n toRetryMetadata(error: KMsgError): KMsgErrorMetadata {\n return {\n providerErrorCode: error.providerErrorCode,\n providerErrorText: error.providerErrorText,\n httpStatus: error.httpStatus,\n requestId: error.requestId,\n retryAfterMs: error.retryAfterMs,\n attempt: error.attempt,\n causeChain: error.causeChain,\n };\n },\n\n withAttempt(error: KMsgError, attempt: number): KMsgError {\n return new KMsgError(error.code, error.message, error.details, {\n ...ErrorUtils.toRetryMetadata(error),\n attempt: normalizeNumber(attempt),\n });\n },\n\n DEFAULT_RETRYABLE_ERROR_CODES,\n DEFAULT_NON_RETRYABLE_ERROR_CODES,\n};\n",
|
|
6
6
|
"/**\n * Represents a successful result containing a value.\n */\nexport type Ok<T> = {\n /** Always true for successful results. */\n readonly isSuccess: true;\n /** Always false for successful results. */\n readonly isFailure: false;\n /** The contained success value. */\n readonly value: T;\n};\n\n/**\n * Represents a failed result containing an error.\n */\nexport type Fail<E> = {\n /** Always false for failed results. */\n readonly isSuccess: false;\n /** Always true for failed results. */\n readonly isFailure: true;\n /** The contained error. */\n readonly error: E;\n};\n\n/**\n * A result type that represents either success (Ok) or failure (Fail).\n * Used throughout k-msg for explicit error handling without exceptions.\n *\n * @template T - The type of the success value\n * @template E - The type of the error (defaults to Error)\n *\n * @example\n * ```ts\n * function divide(a: number, b: number): Result<number, string> {\n * if (b === 0) return fail(\"division by zero\");\n * return ok(a / b);\n * }\n *\n * const result = divide(10, 2);\n * if (result.isSuccess) {\n * console.log(result.value); // 5\n * } else {\n * console.error(result.error);\n * }\n * ```\n */\nexport type Result<T, E = Error> = Ok<T> | Fail<E>;\n\n/**\n * Create a successful result containing the given value.\n * @param value - The success value to wrap\n * @returns An Ok result containing the value\n */\nexport const ok = <T>(value: T): Ok<T> => ({\n isSuccess: true,\n isFailure: false,\n value,\n});\n\n/**\n * Create a failed result containing the given error.\n * @param error - The error to wrap\n * @returns A Fail result containing the error\n */\nexport const fail = <E>(error: E): Fail<E> => ({\n isSuccess: false,\n isFailure: true,\n error,\n});\n\n/**\n * Result utility functions for chaining and transformation\n */\nexport const Result = {\n /**\n * Transform the success value of a Result\n */\n map<T, U, E>(result: Result<T, E>, fn: (value: T) => U): Result<U, E> {\n if (result.isSuccess) {\n return ok(fn(result.value));\n }\n return result;\n },\n\n /**\n * Chain Result-returning operations\n */\n flatMap<T, U, E>(\n result: Result<T, E>,\n fn: (value: T) => Result<U, E>,\n ): Result<U, E> {\n if (result.isSuccess) {\n return fn(result.value);\n }\n return result;\n },\n\n /**\n * Transform the error of a Result\n */\n mapError<T, E, F>(result: Result<T, E>, fn: (error: E) => F): Result<T, F> {\n if (result.isFailure) {\n return fail(fn(result.error));\n }\n return result;\n },\n\n /**\n * Extract the value or throw the error\n */\n unwrap<T, E>(result: Result<T, E>): T {\n if (result.isSuccess) {\n return result.value;\n }\n throw result.error;\n },\n\n /**\n * Extract the value or return a default\n */\n unwrapOr<T, E>(result: Result<T, E>, defaultValue: T): T {\n if (result.isSuccess) {\n return result.value;\n }\n return defaultValue;\n },\n\n /**\n * Extract the value or compute a default from the error\n */\n unwrapOrElse<T, E>(result: Result<T, E>, fn: (error: E) => T): T {\n if (result.isSuccess) {\n return result.value;\n }\n return fn(result.error);\n },\n\n /**\n * Pattern match on a Result\n */\n match<T, E, U>(\n result: Result<T, E>,\n handlers: { ok: (value: T) => U; fail: (error: E) => U },\n ): U {\n if (result.isSuccess) {\n return handlers.ok(result.value);\n }\n return handlers.fail(result.error);\n },\n\n /**\n * Convert a Promise to a Result\n */\n async fromPromise<T, E = Error>(promise: Promise<T>): Promise<Result<T, E>> {\n try {\n const value = await promise;\n return ok(value);\n } catch (error) {\n return fail(error as E);\n }\n },\n\n /**\n * Check if a Result is Ok\n */\n isOk<T, E>(result: Result<T, E>): result is Ok<T> {\n return result.isSuccess;\n },\n\n /**\n * Check if a Result is Fail\n */\n isFail<T, E>(result: Result<T, E>): result is Fail<E> {\n return result.isFailure;\n },\n\n /**\n * Execute a side-effect without breaking the chain.\n * Calls fn with the result (ok or fail) and returns the same result.\n *\n * @param result - The Result to tap\n * @param fn - Side-effect function called with the result\n * @returns The same Result for chaining\n *\n * @example\n * ```ts\n * const result = await provider.send(options);\n * Result.tap(result, r => console.log('Completed:', r));\n * ```\n */\n tap<T, E>(\n result: Result<T, E>,\n fn: (result: Result<T, E>) => void,\n ): Result<T, E> {\n fn(result);\n return result;\n },\n\n /**\n * Execute a side-effect on success only.\n * Calls fn with the value only if result is ok, returns the same result.\n *\n * @param result - The Result to tap\n * @param fn - Side-effect function called with the value on success\n * @returns The same Result for chaining\n *\n * @example\n * ```ts\n * Result.tapOk(result, value => console.log('Success:', value.messageId));\n * ```\n */\n tapOk<T, E>(result: Result<T, E>, fn: (value: T) => void): Result<T, E> {\n if (result.isSuccess) {\n fn(result.value);\n }\n return result;\n },\n\n /**\n * Execute a side-effect on failure only.\n * Calls fn with the error only if result is fail, returns the same result.\n *\n * @param result - The Result to tap\n * @param fn - Side-effect function called with the error on failure\n * @returns The same Result for chaining\n *\n * @example\n * ```ts\n * Result.tapErr(result, error => console.error('Failed:', error.message));\n * ```\n */\n tapErr<T, E>(result: Result<T, E>, fn: (error: E) => void): Result<T, E> {\n if (result.isFailure) {\n fn(result.error);\n }\n return result;\n },\n\n /**\n * Return the value on success, or throw with a custom message on failure.\n * Use this when you want to convert a failed Result to an exception.\n *\n * @param result - The Result to expect\n * @param message - Custom error message to use if result is fail\n * @returns The success value\n * @throws Error with the provided message (and original error as cause)\n *\n * @example\n * ```ts\n * const value = Result.expect(result, 'Message send failed');\n * // throws Error('Message send failed') if result is fail\n * ```\n */\n expect<T, E>(result: Result<T, E>, message: string): T {\n if (result.isSuccess) {\n return result.value;\n }\n throw new Error(message, { cause: result.error });\n },\n};\n",
|
|
7
7
|
"import { KMsgError, KMsgErrorCode } from \"@k-msg/core\";\nimport type {\n KakaoChannelAliasEntry,\n KakaoChannelBindingSource,\n KakaoChannelListItem,\n KakaoChannelResolveInput,\n KakaoChannelResolverConfig,\n KakaoProviderConfigEntry,\n ResolvedKakaoChannelBinding,\n} from \"./types\";\n\nfunction readString(value: unknown): string | undefined {\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nfunction normalizeProviderType(value: string | undefined): string | undefined {\n if (!value) return undefined;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed.toLowerCase() : undefined;\n}\n\nfunction extractProviderBindingHint(provider: KakaoProviderConfigEntry): {\n senderKey?: string;\n plusId?: string;\n} {\n const cfg =\n provider.config && typeof provider.config === \"object\"\n ? provider.config\n : {};\n\n const senderKey =\n readString((cfg as Record<string, unknown>).senderKey) ??\n readString((cfg as Record<string, unknown>).kakaoPfId) ??\n readString((cfg as Record<string, unknown>).profileId);\n const plusId = readString((cfg as Record<string, unknown>).plusId);\n\n const providerType = normalizeProviderType(provider.type);\n if (providerType === \"solapi\") {\n return {\n senderKey:\n readString((cfg as Record<string, unknown>).kakaoPfId) ?? senderKey,\n ...(plusId ? { plusId } : {}),\n };\n }\n\n return {\n ...(senderKey ? { senderKey } : {}),\n ...(plusId ? { plusId } : {}),\n };\n}\n\nfunction dedupeKey(item: KakaoChannelListItem): string {\n return [\n item.providerId ?? \"\",\n item.senderKey ?? \"\",\n item.plusId ?? \"\",\n item.source,\n ].join(\"|\");\n}\n\nfunction selectSingleProviderId(\n providers: KakaoProviderConfigEntry[] | undefined,\n): string | undefined {\n if (!Array.isArray(providers) || providers.length !== 1) return undefined;\n return readString(providers[0]?.id);\n}\n\nexport class KakaoChannelBindingResolver {\n constructor(private readonly config: KakaoChannelResolverConfig) {}\n\n list(params?: { providerId?: string }): KakaoChannelListItem[] {\n const requestedProviderId = readString(params?.providerId);\n const aliases = this.config.aliases?.kakaoChannels ?? {};\n const items: KakaoChannelListItem[] = [];\n const seen = new Set<string>();\n\n const pushUnique = (item: KakaoChannelListItem): void => {\n if (requestedProviderId && item.providerId !== requestedProviderId) {\n return;\n }\n const key = dedupeKey(item);\n if (seen.has(key)) {\n return;\n }\n seen.add(key);\n items.push(item);\n };\n\n for (const [alias, entry] of Object.entries(aliases)) {\n const providerId = readString(entry.providerId);\n if (!providerId) continue;\n\n const senderKey = readString(entry.senderKey);\n const plusId = readString(entry.plusId);\n if (!senderKey && !plusId) continue;\n\n pushUnique({\n source: \"config\",\n alias,\n providerId,\n ...(senderKey ? { senderKey } : {}),\n ...(plusId ? { plusId } : {}),\n ...(readString(entry.name) ? { name: readString(entry.name) } : {}),\n });\n }\n\n const defaultsKakao = this.config.defaults?.kakao;\n const defaultsChannelAlias = readString(defaultsKakao?.channel);\n const defaultAliasEntry = defaultsChannelAlias\n ? aliases[defaultsChannelAlias]\n : undefined;\n const defaultProviderId =\n readString(defaultAliasEntry?.providerId) ??\n readString(this.config.routing?.defaultProviderId) ??\n selectSingleProviderId(this.config.providers);\n\n const defaultsSenderKey =\n readString(defaultsKakao?.senderKey) ??\n readString(defaultAliasEntry?.senderKey);\n const defaultsPlusId =\n readString(defaultsKakao?.plusId) ??\n readString(defaultAliasEntry?.plusId);\n\n if (defaultProviderId && (defaultsSenderKey || defaultsPlusId)) {\n pushUnique({\n source: \"config\",\n ...(defaultsChannelAlias ? { alias: defaultsChannelAlias } : {}),\n providerId: defaultProviderId,\n ...(defaultsSenderKey ? { senderKey: defaultsSenderKey } : {}),\n ...(defaultsPlusId ? { plusId: defaultsPlusId } : {}),\n ...(readString(defaultAliasEntry?.name)\n ? { name: readString(defaultAliasEntry?.name) }\n : {}),\n });\n }\n\n for (const provider of this.config.providers ?? []) {\n const providerId = readString(provider.id);\n if (!providerId) continue;\n\n const hint = extractProviderBindingHint(provider);\n if (!hint.senderKey && !hint.plusId) continue;\n\n pushUnique({\n source: \"config\",\n providerId,\n ...(hint.senderKey ? { senderKey: hint.senderKey } : {}),\n ...(hint.plusId ? { plusId: hint.plusId } : {}),\n });\n }\n\n return items;\n }\n\n resolve(input?: KakaoChannelResolveInput): ResolvedKakaoChannelBinding {\n const aliases = this.config.aliases?.kakaoChannels ?? {};\n\n const channelAlias = readString(input?.channelAlias);\n const aliasEntry = channelAlias ? aliases[channelAlias] : undefined;\n\n if (channelAlias && input?.strictAlias === true && !aliasEntry) {\n throw new KMsgError(\n KMsgErrorCode.INVALID_REQUEST,\n `Unknown kakao channel alias: ${channelAlias}`,\n );\n }\n\n const defaultsKakao = this.config.defaults?.kakao;\n const defaultsChannelAlias = readString(defaultsKakao?.channel);\n const defaultAliasEntry = defaultsChannelAlias\n ? aliases[defaultsChannelAlias]\n : undefined;\n\n const explicitProviderId = readString(input?.providerId);\n const aliasProviderId = readString(aliasEntry?.providerId);\n const defaultsProviderId = readString(defaultAliasEntry?.providerId);\n const routingDefaultProviderId = readString(\n this.config.routing?.defaultProviderId,\n );\n const singleProviderId = selectSingleProviderId(this.config.providers);\n\n let providerId: string | undefined;\n let providerIdSource: KakaoChannelBindingSource = \"unknown\";\n\n if (explicitProviderId) {\n providerId = explicitProviderId;\n providerIdSource = \"explicit\";\n } else if (aliasProviderId) {\n providerId = aliasProviderId;\n providerIdSource = \"alias\";\n } else if (defaultsProviderId) {\n providerId = defaultsProviderId;\n providerIdSource = \"defaults\";\n } else if (routingDefaultProviderId) {\n providerId = routingDefaultProviderId;\n providerIdSource = \"routing\";\n } else if (singleProviderId) {\n providerId = singleProviderId;\n providerIdSource = \"single_provider\";\n }\n\n const providerEntry = providerId\n ? (this.config.providers ?? []).find((entry) => entry.id === providerId)\n : undefined;\n const providerHint = providerEntry\n ? extractProviderBindingHint(providerEntry)\n : {};\n\n const explicitSenderKey = readString(input?.senderKey);\n const aliasSenderKey = readString(aliasEntry?.senderKey);\n const defaultsSenderKey = readString(defaultsKakao?.senderKey);\n const defaultAliasSenderKey = readString(defaultAliasEntry?.senderKey);\n const providerHintSenderKey = readString(providerHint.senderKey);\n\n const explicitPlusId = readString(input?.plusId);\n const aliasPlusId = readString(aliasEntry?.plusId);\n const defaultsPlusId = readString(defaultsKakao?.plusId);\n const defaultAliasPlusId = readString(defaultAliasEntry?.plusId);\n const providerHintPlusId = readString(providerHint.plusId);\n\n let senderKey: string | undefined;\n let senderKeySource: KakaoChannelBindingSource | undefined;\n\n if (explicitSenderKey) {\n senderKey = explicitSenderKey;\n senderKeySource = \"explicit\";\n } else if (aliasSenderKey) {\n senderKey = aliasSenderKey;\n senderKeySource = \"alias\";\n } else if (defaultsSenderKey) {\n senderKey = defaultsSenderKey;\n senderKeySource = \"defaults\";\n } else if (defaultAliasSenderKey) {\n senderKey = defaultAliasSenderKey;\n senderKeySource = \"defaults\";\n } else if (providerHintSenderKey) {\n senderKey = providerHintSenderKey;\n senderKeySource = \"provider_config\";\n }\n\n let plusId: string | undefined;\n let plusIdSource: KakaoChannelBindingSource | undefined;\n\n if (explicitPlusId) {\n plusId = explicitPlusId;\n plusIdSource = \"explicit\";\n } else if (aliasPlusId) {\n plusId = aliasPlusId;\n plusIdSource = \"alias\";\n } else if (defaultsPlusId) {\n plusId = defaultsPlusId;\n plusIdSource = \"defaults\";\n } else if (defaultAliasPlusId) {\n plusId = defaultAliasPlusId;\n plusIdSource = \"defaults\";\n } else if (providerHintPlusId) {\n plusId = providerHintPlusId;\n plusIdSource = \"provider_config\";\n }\n\n return {\n ...(channelAlias ? { alias: channelAlias } : {}),\n ...(providerId ? { providerId } : {}),\n ...(normalizeProviderType(providerEntry?.type)\n ? { providerType: normalizeProviderType(providerEntry?.type) }\n : {}),\n ...(senderKey ? { senderKey } : {}),\n ...(plusId ? { plusId } : {}),\n ...(readString(aliasEntry?.name)\n ? { name: readString(aliasEntry?.name) }\n : readString(defaultAliasEntry?.name)\n ? { name: readString(defaultAliasEntry?.name) }\n : {}),\n providerIdSource,\n ...(senderKeySource ? { senderKeySource } : {}),\n ...(plusIdSource ? { plusIdSource } : {}),\n };\n }\n\n getAlias(alias: string): KakaoChannelAliasEntry | undefined {\n const normalized = readString(alias);\n if (!normalized) return undefined;\n return this.config.aliases?.kakaoChannels?.[normalized];\n }\n}\n",
|
|
8
8
|
"import type { ProviderOnboardingSpec } from \"@k-msg/core\";\nimport type {\n KakaoChannelCapability,\n KakaoChannelCapabilityMode,\n KakaoChannelRuntimeProvider,\n} from \"./types\";\n\nfunction hasFunction(value: unknown): value is (...args: unknown[]) => unknown {\n return typeof value === \"function\";\n}\n\nfunction tryGetOnboardingSpec(\n provider: KakaoChannelRuntimeProvider,\n): ProviderOnboardingSpec | undefined {\n if (!hasFunction(provider.getOnboardingSpec)) {\n return undefined;\n }\n\n try {\n return provider.getOnboardingSpec();\n } catch {\n return undefined;\n }\n}\n\nfunction normalizeProviderType(value: string | undefined): string | undefined {\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed.toLowerCase() : undefined;\n}\n\nfunction inferMode(\n spec: ProviderOnboardingSpec | undefined,\n supportsList: boolean,\n): KakaoChannelCapabilityMode {\n if (spec?.channelOnboarding) {\n if (spec.channelOnboarding === \"api\" && !supportsList) {\n return \"none\";\n }\n return spec.channelOnboarding;\n }\n\n return supportsList ? \"api\" : \"none\";\n}\n\nexport class KakaoChannelCapabilityService {\n resolve(provider: KakaoChannelRuntimeProvider): KakaoChannelCapability {\n const spec = tryGetOnboardingSpec(provider);\n\n const supports = {\n list: hasFunction(provider.listKakaoChannels),\n categories: hasFunction(provider.listKakaoChannelCategories),\n auth: hasFunction(provider.requestKakaoChannelAuth),\n add: hasFunction(provider.addKakaoChannel),\n };\n\n const providerType = normalizeProviderType(spec?.providerId);\n const mode = inferMode(spec, supports.list);\n\n return {\n providerId: provider.id,\n ...(providerType ? { providerType } : {}),\n mode,\n supports,\n };\n }\n}\n",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"import type {\n KakaoChannelApiOperation,\n KakaoChannelRuntimeProvider,\n} from \"../types\";\n\nexport class SolapiChannelAdapter {\n readonly mode = \"none\" as const;\n\n constructor(private readonly provider: KakaoChannelRuntimeProvider) {}\n\n unsupportedMessage(operation: KakaoChannelApiOperation): string {\n return `Provider '${this.provider.id}' does not expose Kakao channel onboarding API. Operation '${operation}' is unsupported.`;\n }\n}\n",
|
|
13
13
|
"import {\n fail,\n type KakaoChannel,\n type KakaoChannelCategories,\n KMsgError,\n KMsgErrorCode,\n ok,\n type Result,\n} from \"@k-msg/core\";\nimport { AligoChannelAdapter } from \"./adapters/aligo.adapter\";\nimport { IwinvChannelAdapter } from \"./adapters/iwinv.adapter\";\nimport { MockChannelAdapter } from \"./adapters/mock.adapter\";\nimport { SolapiChannelAdapter } from \"./adapters/solapi.adapter\";\nimport { KakaoChannelCapabilityService } from \"./kakao-channel-capability.service\";\nimport type {\n KakaoChannelAddParams,\n KakaoChannelApiAdapter,\n KakaoChannelApiOperation,\n KakaoChannelAuthParams,\n KakaoChannelCapability,\n KakaoChannelListItem,\n KakaoChannelListParams,\n KakaoChannelRuntimeProvider,\n} from \"./types\";\n\nfunction normalizeProviderType(value: string | undefined): string | undefined {\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed.toLowerCase() : undefined;\n}\n\nfunction createApiAdapter(\n providerType: string | undefined,\n provider: KakaoChannelRuntimeProvider,\n): KakaoChannelApiAdapter | undefined {\n switch (providerType) {\n case \"aligo\":\n return new AligoChannelAdapter(provider);\n case \"mock\":\n return new MockChannelAdapter(provider);\n default:\n return typeof provider.listKakaoChannels === \"function\"\n ? new AligoChannelAdapter(provider)\n : undefined;\n }\n}\n\nexport class KakaoChannelLifecycleService {\n private readonly capability: KakaoChannelCapability;\n private readonly providerType?: string;\n private readonly apiAdapter?: KakaoChannelApiAdapter;\n private readonly iwinvAdapter?: IwinvChannelAdapter;\n private readonly solapiAdapter?: SolapiChannelAdapter;\n\n constructor(\n private readonly provider: KakaoChannelRuntimeProvider,\n capabilityService = new KakaoChannelCapabilityService(),\n ) {\n this.capability = capabilityService.resolve(provider);\n this.providerType = normalizeProviderType(this.capability.providerType);\n\n if (this.capability.mode === \"api\") {\n this.apiAdapter = createApiAdapter(this.providerType, this.provider);\n } else if (this.providerType === \"iwinv\") {\n this.iwinvAdapter = new IwinvChannelAdapter(this.provider);\n } else if (this.providerType === \"solapi\") {\n this.solapiAdapter = new SolapiChannelAdapter(this.provider);\n }\n }\n\n getCapability(): KakaoChannelCapability {\n return this.capability;\n }\n\n private unsupported(\n operation: KakaoChannelApiOperation,\n ): Result<never, KMsgError> {\n const message = (() => {\n if (this.capability.mode === \"manual\") {\n if (this.iwinvAdapter) {\n return this.iwinvAdapter.unsupportedMessage(operation);\n }\n return `Provider '${this.provider.id}' requires manual Kakao channel onboarding. Operation '${operation}' is unavailable via API.`;\n }\n\n if (this.capability.mode === \"none\") {\n if (this.solapiAdapter) {\n return this.solapiAdapter.unsupportedMessage(operation);\n }\n return `Provider '${this.provider.id}' does not support Kakao channel onboarding API operation '${operation}'.`;\n }\n\n return `Provider '${this.provider.id}' does not support Kakao channel onboarding API operation '${operation}'.`;\n })();\n\n return fail(\n new KMsgError(KMsgErrorCode.INVALID_REQUEST, message, {\n providerId: this.provider.id,\n mode: this.capability.mode,\n operation,\n }),\n );\n }\n\n private ensureApi(\n operation: KakaoChannelApiOperation,\n ): Result<void, KMsgError> {\n if (this.capability.mode !== \"api\") {\n return this.unsupported(operation);\n }\n\n if (!this.apiAdapter) {\n return fail(\n new KMsgError(\n KMsgErrorCode.INVALID_REQUEST,\n `Provider '${this.provider.id}' is marked as api mode but does not expose kakao channel operations`,\n {\n providerId: this.provider.id,\n mode: this.capability.mode,\n operation,\n },\n ),\n );\n }\n\n return ok(undefined);\n }\n\n async list(\n params?: KakaoChannelListParams,\n ): Promise<Result<KakaoChannelListItem[], KMsgError>> {\n const ready = this.ensureApi(\"list\");\n if (ready.isFailure) return ready;\n const apiAdapter = this.apiAdapter;\n if (!apiAdapter) return this.unsupported(\"list\");\n\n const result = await apiAdapter.list(params);\n if (result.isFailure) return result;\n\n return ok(\n result.value.map((channel) => ({\n source: \"api\" as const,\n providerId: channel.providerId || this.provider.id,\n senderKey: channel.senderKey,\n ...(channel.plusId ? { plusId: channel.plusId } : {}),\n ...(channel.name ? { name: channel.name } : {}),\n ...(channel.status ? { status: channel.status } : {}),\n })),\n );\n }\n\n async categories(): Promise<Result<KakaoChannelCategories, KMsgError>> {\n const ready = this.ensureApi(\"categories\");\n if (ready.isFailure) return ready;\n const apiAdapter = this.apiAdapter;\n if (!apiAdapter) return this.unsupported(\"categories\");\n\n return apiAdapter.categories();\n }\n\n async auth(params: KakaoChannelAuthParams): Promise<Result<void, KMsgError>> {\n const ready = this.ensureApi(\"auth\");\n if (ready.isFailure) return ready;\n const apiAdapter = this.apiAdapter;\n if (!apiAdapter) return this.unsupported(\"auth\");\n\n return apiAdapter.auth(params);\n }\n\n async add(\n params: KakaoChannelAddParams,\n ): Promise<Result<KakaoChannel, KMsgError>> {\n const ready = this.ensureApi(\"add\");\n if (ready.isFailure) return ready;\n const apiAdapter = this.apiAdapter;\n if (!apiAdapter) return this.unsupported(\"add\");\n\n return apiAdapter.add(params);\n }\n}\n"
|
|
14
14
|
],
|
|
15
|
-
"mappings": "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",
|
|
16
|
-
"debugId": "
|
|
15
|
+
"mappings": "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",
|
|
16
|
+
"debugId": "32A104C9BC685D0564756E2164756E21",
|
|
17
17
|
"names": []
|
|
18
18
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var W=Object.defineProperty;var se=(e,t)=>{for(var r in t)W(e,r,{get:t[r],enumerable:!0,configurable:!0,set:(i)=>t[r]=()=>i})};var L={["INVALID_REQUEST"]:{ko:"잘못된 요청입니다",en:"Invalid request"},["AUTHENTICATION_FAILED"]:{ko:"인증에 실패했습니다",en:"Authentication failed"},["INSUFFICIENT_BALANCE"]:{ko:"잔액이 부족합니다",en:"Insufficient balance"},["TEMPLATE_NOT_FOUND"]:{ko:"템플릿을 찾을 수 없습니다",en:"Template not found"},["RATE_LIMIT_EXCEEDED"]:{ko:"요청 한도를 초과했습니다",en:"Rate limit exceeded"},["NETWORK_ERROR"]:{ko:"네트워크 오류가 발생했습니다",en:"Network error"},["NETWORK_TIMEOUT"]:{ko:"네트워크 요청 시간이 초과되었습니다",en:"Network timeout"},["NETWORK_SERVICE_UNAVAILABLE"]:{ko:"서비스를 일시적으로 사용할 수 없습니다",en:"Service temporarily unavailable"},["PROVIDER_ERROR"]:{ko:"제공자 오류가 발생했습니다",en:"Provider error"},["MESSAGE_SEND_FAILED"]:{ko:"메시지 전송에 실패했습니다",en:"Message send failed"},["CRYPTO_CONFIG_ERROR"]:{ko:"암호화 설정 오류가 발생했습니다",en:"Crypto configuration error"},["CRYPTO_ENCRYPT_FAILED"]:{ko:"암호화에 실패했습니다",en:"Encryption failed"},["CRYPTO_DECRYPT_FAILED"]:{ko:"복호화에 실패했습니다",en:"Decryption failed"},["CRYPTO_HASH_FAILED"]:{ko:"해시 생성에 실패했습니다",en:"Hash generation failed"},["CRYPTO_POLICY_VIOLATION"]:{ko:"암호화 정책 위반이 발생했습니다",en:"Crypto policy violation"},["UNKNOWN_ERROR"]:{ko:"알 수 없는 오류가 발생했습니다",en:"Unknown error"}};var I=(e)=>{if(typeof e!=="number"||Number.isNaN(e)||!Number.isFinite(e))return;return Math.trunc(e)};class c extends Error{code;details;providerErrorCode;providerErrorText;httpStatus;requestId;retryAfterMs;attempt;causeChain;constructor(e,t,r,i={}){super(t);if(this.name="KMsgError",this.code=e,this.details=r,this.providerErrorCode=i.providerErrorCode,this.providerErrorText=i.providerErrorText,this.httpStatus=I(i.httpStatus),this.requestId=typeof i.requestId==="string"?i.requestId:void 0,this.retryAfterMs=I(i.retryAfterMs),this.attempt=I(i.attempt),Array.isArray(i.causeChain))this.causeChain=i.causeChain;else if(i.causeChain!==void 0)this.causeChain=[i.causeChain];if(Error.captureStackTrace)Error.captureStackTrace(this,c)}getLocalizedMessage(e="ko"){let t=L[this.code];if(t?.[e])return t[e];return this.message}toJSON(){return{name:this.name,code:this.code,message:this.message,details:this.details,providerErrorCode:this.providerErrorCode,providerErrorText:this.providerErrorText,httpStatus:this.httpStatus,requestId:this.requestId,retryAfterMs:this.retryAfterMs,attempt:this.attempt,causeChain:this.causeChain}}}var x=(e)=>({isSuccess:!0,isFailure:!1,value:e}),f=(e)=>({isSuccess:!1,isFailure:!0,error:e});function n(e){if(typeof e!=="string")return;let t=e.trim();return t.length>0?t:void 0}function O(e){if(!e)return;let t=e.trim();return t.length>0?t.toLowerCase():void 0}function G(e){let t=e.config&&typeof e.config==="object"?e.config:{},r=n(t.senderKey)??n(t.kakaoPfId)??n(t.profileId),i=n(t.plusId);if(O(e.type)==="solapi")return{senderKey:n(t.kakaoPfId)??r,...i?{plusId:i}:{}};return{...r?{senderKey:r}:{},...i?{plusId:i}:{}}}function z(e){return[e.providerId??"",e.senderKey??"",e.plusId??"",e.source].join("|")}function J(e){if(!Array.isArray(e)||e.length!==1)return;return n(e[0]?.id)}class V{config;constructor(e){this.config=e}list(e){let t=n(e?.providerId),r=this.config.aliases?.kakaoChannels??{},i=[],s=new Set,K=(o)=>{if(t&&o.providerId!==t)return;let a=z(o);if(s.has(a))return;s.add(a),i.push(o)};for(let[o,a]of Object.entries(r)){let d=n(a.providerId);if(!d)continue;let v=n(a.senderKey),P=n(a.plusId);if(!v&&!P)continue;K({source:"config",alias:o,providerId:d,...v?{senderKey:v}:{},...P?{plusId:P}:{},...n(a.name)?{name:n(a.name)}:{}})}let p=this.config.defaults?.kakao,y=n(p?.channel),l=y?r[y]:void 0,A=n(l?.providerId)??n(this.config.routing?.defaultProviderId)??J(this.config.providers),C=n(p?.senderKey)??n(l?.senderKey),k=n(p?.plusId)??n(l?.plusId);if(A&&(C||k))K({source:"config",...y?{alias:y}:{},providerId:A,...C?{senderKey:C}:{},...k?{plusId:k}:{},...n(l?.name)?{name:n(l?.name)}:{}});for(let o of this.config.providers??[]){let a=n(o.id);if(!a)continue;let d=G(o);if(!d.senderKey&&!d.plusId)continue;K({source:"config",providerId:a,...d.senderKey?{senderKey:d.senderKey}:{},...d.plusId?{plusId:d.plusId}:{}})}return i}resolve(e){let t=this.config.aliases?.kakaoChannels??{},r=n(e?.channelAlias),i=r?t[r]:void 0;if(r&&e?.strictAlias===!0&&!i)throw new c("INVALID_REQUEST",`Unknown kakao channel alias: ${r}`);let s=this.config.defaults?.kakao,K=n(s?.channel),p=K?t[K]:void 0,y=n(e?.providerId),l=n(i?.providerId),A=n(p?.providerId),C=n(this.config.routing?.defaultProviderId),k=J(this.config.providers),o,a="unknown";if(y)o=y,a="explicit";else if(l)o=l,a="alias";else if(A)o=A,a="defaults";else if(C)o=C,a="routing";else if(k)o=k,a="single_provider";let d=o?(this.config.providers??[]).find((Q)=>Q.id===o):void 0,v=d?G(d):{},P=n(e?.senderKey),D=n(i?.senderKey),B=n(s?.senderKey),_=n(p?.senderKey),q=n(v.senderKey),N=n(e?.plusId),U=n(i?.plusId),$=n(s?.plusId),H=n(p?.plusId),j=n(v.plusId),u,h;if(P)u=P,h="explicit";else if(D)u=D,h="alias";else if(B)u=B,h="defaults";else if(_)u=_,h="defaults";else if(q)u=q,h="provider_config";let g,m;if(N)g=N,m="explicit";else if(U)g=U,m="alias";else if($)g=$,m="defaults";else if(H)g=H,m="defaults";else if(j)g=j,m="provider_config";return{...r?{alias:r}:{},...o?{providerId:o}:{},...O(d?.type)?{providerType:O(d?.type)}:{},...u?{senderKey:u}:{},...g?{plusId:g}:{},...n(i?.name)?{name:n(i?.name)}:n(p?.name)?{name:n(p?.name)}:{},providerIdSource:a,...h?{senderKeySource:h}:{},...m?{plusIdSource:m}:{}}}getAlias(e){let t=n(e);if(!t)return;return this.config.aliases?.kakaoChannels?.[t]}}function w(e){return typeof e==="function"}function ee(e){if(!w(e.getOnboardingSpec))return;try{return e.getOnboardingSpec()}catch{return}}function te(e){if(typeof e!=="string")return;let t=e.trim();return t.length>0?t.toLowerCase():void 0}function ne(e,t){if(e?.channelOnboarding){if(e.channelOnboarding==="api"&&!t)return"none";return e.channelOnboarding}return t?"api":"none"}class S{resolve(e){let t=ee(e),r={list:w(e.listKakaoChannels),categories:w(e.listKakaoChannelCategories),auth:w(e.requestKakaoChannelAuth),add:w(e.addKakaoChannel)},i=te(t?.providerId),s=ne(t,r.list);return{providerId:e.id,...i?{providerType:i}:{},mode:s,supports:r}}}function R(e,t){return new c("INVALID_REQUEST",`Provider '${e}' does not support kakao channel api operation '${t}'`,{providerId:e,operation:t})}class F{provider;constructor(e){this.provider=e}async list(e){let t=this.provider.listKakaoChannels;if(typeof t!=="function")return f(R(this.provider.id,"list"));return t.call(this.provider,e)}async categories(){let e=this.provider.listKakaoChannelCategories;if(typeof e!=="function")return f(R(this.provider.id,"categories"));return e.call(this.provider)}async auth(e){let t=this.provider.requestKakaoChannelAuth;if(typeof t!=="function")return f(R(this.provider.id,"auth"));return t.call(this.provider,e)}async add(e){let t=this.provider.addKakaoChannel;if(typeof t!=="function")return f(R(this.provider.id,"add"));return t.call(this.provider,e)}}class E{provider;mode="manual";constructor(e){this.provider=e}unsupportedMessage(e){return`Provider '${this.provider.id}' uses manual Kakao channel onboarding. Operation '${e}' is not available via API.`}}class M extends F{constructor(e){super(e)}}class T{provider;mode="none";constructor(e){this.provider=e}unsupportedMessage(e){return`Provider '${this.provider.id}' does not expose Kakao channel onboarding API. Operation '${e}' is unsupported.`}}function ie(e){if(typeof e!=="string")return;let t=e.trim();return t.length>0?t.toLowerCase():void 0}function re(e,t){switch(e){case"aligo":return new F(t);case"mock":return new M(t);default:return typeof t.listKakaoChannels==="function"?new F(t):void 0}}class Y{provider;capability;providerType;apiAdapter;iwinvAdapter;solapiAdapter;constructor(e,t=new S){this.provider=e;if(this.capability=t.resolve(e),this.providerType=ie(this.capability.providerType),this.capability.mode==="api")this.apiAdapter=re(this.providerType,this.provider);else if(this.providerType==="iwinv")this.iwinvAdapter=new E(this.provider);else if(this.providerType==="solapi")this.solapiAdapter=new T(this.provider)}getCapability(){return this.capability}unsupported(e){let t=(()=>{if(this.capability.mode==="manual"){if(this.iwinvAdapter)return this.iwinvAdapter.unsupportedMessage(e);return`Provider '${this.provider.id}' requires manual Kakao channel onboarding. Operation '${e}' is unavailable via API.`}if(this.capability.mode==="none"){if(this.solapiAdapter)return this.solapiAdapter.unsupportedMessage(e);return`Provider '${this.provider.id}' does not support Kakao channel onboarding API operation '${e}'.`}return`Provider '${this.provider.id}' does not support Kakao channel onboarding API operation '${e}'.`})();return f(new c("INVALID_REQUEST",t,{providerId:this.provider.id,mode:this.capability.mode,operation:e}))}ensureApi(e){if(this.capability.mode!=="api")return this.unsupported(e);if(!this.apiAdapter)return f(new c("INVALID_REQUEST",`Provider '${this.provider.id}' is marked as api mode but does not expose kakao channel operations`,{providerId:this.provider.id,mode:this.capability.mode,operation:e}));return x(void 0)}async list(e){let t=this.ensureApi("list");if(t.isFailure)return t;let r=this.apiAdapter;if(!r)return this.unsupported("list");let i=await r.list(e);if(i.isFailure)return i;return x(i.value.map((s)=>({source:"api",providerId:s.providerId||this.provider.id,senderKey:s.senderKey,...s.plusId?{plusId:s.plusId}:{},...s.name?{name:s.name}:{},...s.status?{status:s.status}:{}})))}async categories(){let e=this.ensureApi("categories");if(e.isFailure)return e;let t=this.apiAdapter;if(!t)return this.unsupported("categories");return t.categories()}async auth(e){let t=this.ensureApi("auth");if(t.isFailure)return t;let r=this.apiAdapter;if(!r)return this.unsupported("auth");return r.auth(e)}async add(e){let t=this.ensureApi("add");if(t.isFailure)return t;let r=this.apiAdapter;if(!r)return this.unsupported("add");return r.add(e)}}export{Y as KakaoChannelLifecycleService,S as KakaoChannelCapabilityService,V as KakaoChannelBindingResolver};
|
|
1
|
+
var s=Object.defineProperty;var Kn=(n,f)=>{for(var i in f)s(n,i,{get:f[i],enumerable:!0,configurable:!0,set:(K)=>f[i]=()=>K})};var D;((I)=>{I.INVALID_REQUEST="INVALID_REQUEST";I.AUTHENTICATION_FAILED="AUTHENTICATION_FAILED";I.INSUFFICIENT_BALANCE="INSUFFICIENT_BALANCE";I.TEMPLATE_NOT_FOUND="TEMPLATE_NOT_FOUND";I.RATE_LIMIT_EXCEEDED="RATE_LIMIT_EXCEEDED";I.NETWORK_ERROR="NETWORK_ERROR";I.NETWORK_TIMEOUT="NETWORK_TIMEOUT";I.NETWORK_SERVICE_UNAVAILABLE="NETWORK_SERVICE_UNAVAILABLE";I.PROVIDER_ERROR="PROVIDER_ERROR";I.MESSAGE_SEND_FAILED="MESSAGE_SEND_FAILED";I.CRYPTO_CONFIG_ERROR="CRYPTO_CONFIG_ERROR";I.CRYPTO_ENCRYPT_FAILED="CRYPTO_ENCRYPT_FAILED";I.CRYPTO_DECRYPT_FAILED="CRYPTO_DECRYPT_FAILED";I.CRYPTO_HASH_FAILED="CRYPTO_HASH_FAILED";I.CRYPTO_POLICY_VIOLATION="CRYPTO_POLICY_VIOLATION";I.UNKNOWN_ERROR="UNKNOWN_ERROR"})(D||={});var a={["INVALID_REQUEST"]:{ko:"잘못된 요청입니다",en:"Invalid request"},["AUTHENTICATION_FAILED"]:{ko:"인증에 실패했습니다",en:"Authentication failed"},["INSUFFICIENT_BALANCE"]:{ko:"잔액이 부족합니다",en:"Insufficient balance"},["TEMPLATE_NOT_FOUND"]:{ko:"템플릿을 찾을 수 없습니다",en:"Template not found"},["RATE_LIMIT_EXCEEDED"]:{ko:"요청 한도를 초과했습니다",en:"Rate limit exceeded"},["NETWORK_ERROR"]:{ko:"네트워크 오류가 발생했습니다",en:"Network error"},["NETWORK_TIMEOUT"]:{ko:"네트워크 요청 시간이 초과되었습니다",en:"Network timeout"},["NETWORK_SERVICE_UNAVAILABLE"]:{ko:"서비스를 일시적으로 사용할 수 없습니다",en:"Service temporarily unavailable"},["PROVIDER_ERROR"]:{ko:"제공자 오류가 발생했습니다",en:"Provider error"},["MESSAGE_SEND_FAILED"]:{ko:"메시지 전송에 실패했습니다",en:"Message send failed"},["CRYPTO_CONFIG_ERROR"]:{ko:"암호화 설정 오류가 발생했습니다",en:"Crypto configuration error"},["CRYPTO_ENCRYPT_FAILED"]:{ko:"암호화에 실패했습니다",en:"Encryption failed"},["CRYPTO_DECRYPT_FAILED"]:{ko:"복호화에 실패했습니다",en:"Decryption failed"},["CRYPTO_HASH_FAILED"]:{ko:"해시 생성에 실패했습니다",en:"Hash generation failed"},["CRYPTO_POLICY_VIOLATION"]:{ko:"암호화 정책 위반이 발생했습니다",en:"Crypto policy violation"},["UNKNOWN_ERROR"]:{ko:"알 수 없는 오류가 발생했습니다",en:"Unknown error"}},Pn=new Set(Object.values(D));var L=(n)=>{if(typeof n!=="number"||Number.isNaN(n)||!Number.isFinite(n))return;return Math.trunc(n)};class A extends Error{code;details;providerErrorCode;providerErrorText;httpStatus;requestId;retryAfterMs;attempt;causeChain;constructor(n,f,i,K={}){super(f);if(this.name="KMsgError",this.code=n,this.details=i,this.providerErrorCode=K.providerErrorCode,this.providerErrorText=K.providerErrorText,this.httpStatus=L(K.httpStatus),this.requestId=typeof K.requestId==="string"?K.requestId:void 0,this.retryAfterMs=L(K.retryAfterMs),this.attempt=L(K.attempt),Array.isArray(K.causeChain))this.causeChain=K.causeChain;else if(K.causeChain!==void 0)this.causeChain=[K.causeChain];if(Error.captureStackTrace)Error.captureStackTrace(this,A)}getLocalizedMessage(n="ko"){let f=a[this.code];if(f?.[n])return f[n];return this.message}toJSON(){return{name:this.name,code:this.code,message:this.message,details:this.details,providerErrorCode:this.providerErrorCode,providerErrorText:this.providerErrorText,httpStatus:this.httpStatus,requestId:this.requestId,retryAfterMs:this.retryAfterMs,attempt:this.attempt,causeChain:this.causeChain}}}var R=(n)=>({isSuccess:!0,isFailure:!1,value:n}),w=(n)=>({isSuccess:!1,isFailure:!0,error:n});function k(n){if(typeof n!=="string")return;let f=n.trim();return f.length>0?f:void 0}function F(n){if(!n)return;let f=n.trim();return f.length>0?f.toLowerCase():void 0}function c(n){let f=n.config&&typeof n.config==="object"?n.config:{},i=k(f.senderKey)??k(f.kakaoPfId)??k(f.profileId),K=k(f.plusId);if(F(n.type)==="solapi")return{senderKey:k(f.kakaoPfId)??i,...K?{plusId:K}:{}};return{...i?{senderKey:i}:{},...K?{plusId:K}:{}}}function o(n){return[n.providerId??"",n.senderKey??"",n.plusId??"",n.source].join("|")}function l(n){if(!Array.isArray(n)||n.length!==1)return;return k(n[0]?.id)}class u{config;constructor(n){this.config=n}list(n){let f=k(n?.providerId),i=this.config.aliases?.kakaoChannels??{},K=[],P=new Set,V=(h)=>{if(f&&h.providerId!==f)return;let g=o(h);if(P.has(g))return;P.add(g),K.push(h)};for(let[h,g]of Object.entries(i)){let C=k(g.providerId);if(!C)continue;let O=k(g.senderKey),I=k(g.plusId);if(!O&&!I)continue;V({source:"config",alias:h,providerId:C,...O?{senderKey:O}:{},...I?{plusId:I}:{},...k(g.name)?{name:k(g.name)}:{}})}let y=this.config.defaults?.kakao,B=k(y?.channel),$=B?i[B]:void 0,q=k($?.providerId)??k(this.config.routing?.defaultProviderId)??l(this.config.providers),X=k(y?.senderKey)??k($?.senderKey),Z=k(y?.plusId)??k($?.plusId);if(q&&(X||Z))V({source:"config",...B?{alias:B}:{},providerId:q,...X?{senderKey:X}:{},...Z?{plusId:Z}:{},...k($?.name)?{name:k($?.name)}:{}});for(let h of this.config.providers??[]){let g=k(h.id);if(!g)continue;let C=c(h);if(!C.senderKey&&!C.plusId)continue;V({source:"config",providerId:g,...C.senderKey?{senderKey:C.senderKey}:{},...C.plusId?{plusId:C.plusId}:{}})}return K}resolve(n){let f=this.config.aliases?.kakaoChannels??{},i=k(n?.channelAlias),K=i?f[i]:void 0;if(i&&n?.strictAlias===!0&&!K)throw new A("INVALID_REQUEST",`Unknown kakao channel alias: ${i}`);let P=this.config.defaults?.kakao,V=k(P?.channel),y=V?f[V]:void 0,B=k(n?.providerId),$=k(K?.providerId),q=k(y?.providerId),X=k(this.config.routing?.defaultProviderId),Z=l(this.config.providers),h,g="unknown";if(B)h=B,g="explicit";else if($)h=$,g="alias";else if(q)h=q,g="defaults";else if(X)h=X,g="routing";else if(Z)h=Z,g="single_provider";let C=h?(this.config.providers??[]).find((t)=>t.id===h):void 0,O=C?c(C):{},I=k(n?.senderKey),b=k(K?.senderKey),N=k(P?.senderKey),x=k(y?.senderKey),d=k(O.senderKey),p=k(n?.plusId),v=k(K?.plusId),M=k(P?.plusId),z=k(y?.plusId),E=k(O.plusId),H,Q;if(I)H=I,Q="explicit";else if(b)H=b,Q="alias";else if(N)H=N,Q="defaults";else if(x)H=x,Q="defaults";else if(d)H=d,Q="provider_config";let G,J;if(p)G=p,J="explicit";else if(v)G=v,J="alias";else if(M)G=M,J="defaults";else if(z)G=z,J="defaults";else if(E)G=E,J="provider_config";return{...i?{alias:i}:{},...h?{providerId:h}:{},...F(C?.type)?{providerType:F(C?.type)}:{},...H?{senderKey:H}:{},...G?{plusId:G}:{},...k(K?.name)?{name:k(K?.name)}:k(y?.name)?{name:k(y?.name)}:{},providerIdSource:g,...Q?{senderKeySource:Q}:{},...J?{plusIdSource:J}:{}}}getAlias(n){let f=k(n);if(!f)return;return this.config.aliases?.kakaoChannels?.[f]}}function U(n){return typeof n==="function"}function e(n){if(!U(n.getOnboardingSpec))return;try{return n.getOnboardingSpec()}catch{return}}function r(n){if(typeof n!=="string")return;let f=n.trim();return f.length>0?f.toLowerCase():void 0}function nn(n,f){if(n?.channelOnboarding){if(n.channelOnboarding==="api"&&!f)return"none";return n.channelOnboarding}return f?"api":"none"}class Y{resolve(n){let f=e(n),i={list:U(n.listKakaoChannels),categories:U(n.listKakaoChannelCategories),auth:U(n.requestKakaoChannelAuth),add:U(n.addKakaoChannel)},K=r(f?.providerId),P=nn(f,i.list);return{providerId:n.id,...K?{providerType:K}:{},mode:P,supports:i}}}function S(n,f){return new A("INVALID_REQUEST",`Provider '${n}' does not support kakao channel api operation '${f}'`,{providerId:n,operation:f})}class W{provider;constructor(n){this.provider=n}async list(n){let f=this.provider.listKakaoChannels;if(typeof f!=="function")return w(S(this.provider.id,"list"));return f.call(this.provider,n)}async categories(){let n=this.provider.listKakaoChannelCategories;if(typeof n!=="function")return w(S(this.provider.id,"categories"));return n.call(this.provider)}async auth(n){let f=this.provider.requestKakaoChannelAuth;if(typeof f!=="function")return w(S(this.provider.id,"auth"));return f.call(this.provider,n)}async add(n){let f=this.provider.addKakaoChannel;if(typeof f!=="function")return w(S(this.provider.id,"add"));return f.call(this.provider,n)}}class j{provider;mode="manual";constructor(n){this.provider=n}unsupportedMessage(n){return`Provider '${this.provider.id}' uses manual Kakao channel onboarding. Operation '${n}' is not available via API.`}}class _ extends W{constructor(n){super(n)}}class T{provider;mode="none";constructor(n){this.provider=n}unsupportedMessage(n){return`Provider '${this.provider.id}' does not expose Kakao channel onboarding API. Operation '${n}' is unsupported.`}}function fn(n){if(typeof n!=="string")return;let f=n.trim();return f.length>0?f.toLowerCase():void 0}function kn(n,f){switch(n){case"aligo":return new W(f);case"mock":return new _(f);default:return typeof f.listKakaoChannels==="function"?new W(f):void 0}}class m{provider;capability;providerType;apiAdapter;iwinvAdapter;solapiAdapter;constructor(n,f=new Y){this.provider=n;if(this.capability=f.resolve(n),this.providerType=fn(this.capability.providerType),this.capability.mode==="api")this.apiAdapter=kn(this.providerType,this.provider);else if(this.providerType==="iwinv")this.iwinvAdapter=new j(this.provider);else if(this.providerType==="solapi")this.solapiAdapter=new T(this.provider)}getCapability(){return this.capability}unsupported(n){let f=(()=>{if(this.capability.mode==="manual"){if(this.iwinvAdapter)return this.iwinvAdapter.unsupportedMessage(n);return`Provider '${this.provider.id}' requires manual Kakao channel onboarding. Operation '${n}' is unavailable via API.`}if(this.capability.mode==="none"){if(this.solapiAdapter)return this.solapiAdapter.unsupportedMessage(n);return`Provider '${this.provider.id}' does not support Kakao channel onboarding API operation '${n}'.`}return`Provider '${this.provider.id}' does not support Kakao channel onboarding API operation '${n}'.`})();return w(new A("INVALID_REQUEST",f,{providerId:this.provider.id,mode:this.capability.mode,operation:n}))}ensureApi(n){if(this.capability.mode!=="api")return this.unsupported(n);if(!this.apiAdapter)return w(new A("INVALID_REQUEST",`Provider '${this.provider.id}' is marked as api mode but does not expose kakao channel operations`,{providerId:this.provider.id,mode:this.capability.mode,operation:n}));return R(void 0)}async list(n){let f=this.ensureApi("list");if(f.isFailure)return f;let i=this.apiAdapter;if(!i)return this.unsupported("list");let K=await i.list(n);if(K.isFailure)return K;return R(K.value.map((P)=>({source:"api",providerId:P.providerId||this.provider.id,senderKey:P.senderKey,...P.plusId?{plusId:P.plusId}:{},...P.name?{name:P.name}:{},...P.status?{status:P.status}:{}})))}async categories(){let n=this.ensureApi("categories");if(n.isFailure)return n;let f=this.apiAdapter;if(!f)return this.unsupported("categories");return f.categories()}async auth(n){let f=this.ensureApi("auth");if(f.isFailure)return f;let i=this.apiAdapter;if(!i)return this.unsupported("auth");return i.auth(n)}async add(n){let f=this.ensureApi("add");if(f.isFailure)return f;let i=this.apiAdapter;if(!i)return this.unsupported("add");return i.add(n)}}export{m as KakaoChannelLifecycleService,Y as KakaoChannelCapabilityService,u as KakaoChannelBindingResolver};
|
|
2
2
|
|
|
3
|
-
//# debugId=
|
|
3
|
+
//# debugId=E03E043FEC76F1D764756E2164756E21
|
|
4
4
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../core/src/errors.ts", "../../core/src/result.ts", "../src/runtime/kakao-channel-binding-resolver.ts", "../src/runtime/kakao-channel-capability.service.ts", "../src/runtime/adapters/aligo.adapter.ts", "../src/runtime/adapters/iwinv.adapter.ts", "../src/runtime/adapters/mock.adapter.ts", "../src/runtime/adapters/solapi.adapter.ts", "../src/runtime/kakao-channel-lifecycle.service.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"export type Locale = \"ko\" | \"en\";\n\nexport enum KMsgErrorCode {\n INVALID_REQUEST = \"INVALID_REQUEST\",\n AUTHENTICATION_FAILED = \"AUTHENTICATION_FAILED\",\n INSUFFICIENT_BALANCE = \"INSUFFICIENT_BALANCE\",\n TEMPLATE_NOT_FOUND = \"TEMPLATE_NOT_FOUND\",\n RATE_LIMIT_EXCEEDED = \"RATE_LIMIT_EXCEEDED\",\n NETWORK_ERROR = \"NETWORK_ERROR\",\n NETWORK_TIMEOUT = \"NETWORK_TIMEOUT\",\n NETWORK_SERVICE_UNAVAILABLE = \"NETWORK_SERVICE_UNAVAILABLE\",\n PROVIDER_ERROR = \"PROVIDER_ERROR\",\n MESSAGE_SEND_FAILED = \"MESSAGE_SEND_FAILED\",\n CRYPTO_CONFIG_ERROR = \"CRYPTO_CONFIG_ERROR\",\n CRYPTO_ENCRYPT_FAILED = \"CRYPTO_ENCRYPT_FAILED\",\n CRYPTO_DECRYPT_FAILED = \"CRYPTO_DECRYPT_FAILED\",\n CRYPTO_HASH_FAILED = \"CRYPTO_HASH_FAILED\",\n CRYPTO_POLICY_VIOLATION = \"CRYPTO_POLICY_VIOLATION\",\n UNKNOWN_ERROR = \"UNKNOWN_ERROR\",\n}\n\nconst DEFAULT_LOCALE: Locale = \"ko\";\n\nconst ERROR_MESSAGES: Record<KMsgErrorCode, { ko: string; en: string }> = {\n [KMsgErrorCode.INVALID_REQUEST]: {\n ko: \"잘못된 요청입니다\",\n en: \"Invalid request\",\n },\n [KMsgErrorCode.AUTHENTICATION_FAILED]: {\n ko: \"인증에 실패했습니다\",\n en: \"Authentication failed\",\n },\n [KMsgErrorCode.INSUFFICIENT_BALANCE]: {\n ko: \"잔액이 부족합니다\",\n en: \"Insufficient balance\",\n },\n [KMsgErrorCode.TEMPLATE_NOT_FOUND]: {\n ko: \"템플릿을 찾을 수 없습니다\",\n en: \"Template not found\",\n },\n [KMsgErrorCode.RATE_LIMIT_EXCEEDED]: {\n ko: \"요청 한도를 초과했습니다\",\n en: \"Rate limit exceeded\",\n },\n [KMsgErrorCode.NETWORK_ERROR]: {\n ko: \"네트워크 오류가 발생했습니다\",\n en: \"Network error\",\n },\n [KMsgErrorCode.NETWORK_TIMEOUT]: {\n ko: \"네트워크 요청 시간이 초과되었습니다\",\n en: \"Network timeout\",\n },\n [KMsgErrorCode.NETWORK_SERVICE_UNAVAILABLE]: {\n ko: \"서비스를 일시적으로 사용할 수 없습니다\",\n en: \"Service temporarily unavailable\",\n },\n [KMsgErrorCode.PROVIDER_ERROR]: {\n ko: \"제공자 오류가 발생했습니다\",\n en: \"Provider error\",\n },\n [KMsgErrorCode.MESSAGE_SEND_FAILED]: {\n ko: \"메시지 전송에 실패했습니다\",\n en: \"Message send failed\",\n },\n [KMsgErrorCode.CRYPTO_CONFIG_ERROR]: {\n ko: \"암호화 설정 오류가 발생했습니다\",\n en: \"Crypto configuration error\",\n },\n [KMsgErrorCode.CRYPTO_ENCRYPT_FAILED]: {\n ko: \"암호화에 실패했습니다\",\n en: \"Encryption failed\",\n },\n [KMsgErrorCode.CRYPTO_DECRYPT_FAILED]: {\n ko: \"복호화에 실패했습니다\",\n en: \"Decryption failed\",\n },\n [KMsgErrorCode.CRYPTO_HASH_FAILED]: {\n ko: \"해시 생성에 실패했습니다\",\n en: \"Hash generation failed\",\n },\n [KMsgErrorCode.CRYPTO_POLICY_VIOLATION]: {\n ko: \"암호화 정책 위반이 발생했습니다\",\n en: \"Crypto policy violation\",\n },\n [KMsgErrorCode.UNKNOWN_ERROR]: {\n ko: \"알 수 없는 오류가 발생했습니다\",\n en: \"Unknown error\",\n },\n};\n\nexport type RetryPolicyErrorCode = KMsgErrorCode;\n\nexport type ProviderRetryHint = \"retryable\" | \"non_retryable\";\n\nexport interface KMsgErrorMetadata {\n providerErrorCode?: string;\n providerErrorText?: string;\n httpStatus?: number;\n requestId?: string;\n retryAfterMs?: number;\n attempt?: number;\n causeChain?: unknown[];\n}\n\nexport interface ErrorRetryPolicy {\n retryableCodes?: readonly KMsgErrorCode[];\n nonRetryableCodes?: readonly KMsgErrorCode[];\n classifyByStatusCode?: (status: number) => ProviderRetryHint;\n classifyByMessage?: (message: string) => ProviderRetryHint | undefined;\n /**\n * Optional override for retry hint inference.\n */\n fallback?: ProviderRetryHint;\n /**\n * Optional custom retry delay in milliseconds.\n */\n retryAfterMs?: (error: KMsgError) => number | undefined;\n}\n\nconst DEFAULT_RETRYABLE_ERROR_CODES: ReadonlySet<RetryPolicyErrorCode> =\n new Set([\n KMsgErrorCode.NETWORK_ERROR,\n KMsgErrorCode.RATE_LIMIT_EXCEEDED,\n KMsgErrorCode.NETWORK_TIMEOUT,\n KMsgErrorCode.NETWORK_SERVICE_UNAVAILABLE,\n KMsgErrorCode.PROVIDER_ERROR,\n KMsgErrorCode.UNKNOWN_ERROR,\n ]);\n\nconst DEFAULT_NON_RETRYABLE_ERROR_CODES: ReadonlySet<RetryPolicyErrorCode> =\n new Set([\n KMsgErrorCode.INVALID_REQUEST,\n KMsgErrorCode.AUTHENTICATION_FAILED,\n KMsgErrorCode.INSUFFICIENT_BALANCE,\n KMsgErrorCode.TEMPLATE_NOT_FOUND,\n KMsgErrorCode.MESSAGE_SEND_FAILED,\n KMsgErrorCode.CRYPTO_CONFIG_ERROR,\n KMsgErrorCode.CRYPTO_ENCRYPT_FAILED,\n KMsgErrorCode.CRYPTO_DECRYPT_FAILED,\n KMsgErrorCode.CRYPTO_HASH_FAILED,\n KMsgErrorCode.CRYPTO_POLICY_VIOLATION,\n ]);\n\nconst normalizeNumber = (value: unknown): number | undefined => {\n if (\n typeof value !== \"number\" ||\n Number.isNaN(value) ||\n !Number.isFinite(value)\n ) {\n return undefined;\n }\n\n return Math.trunc(value);\n};\n\nexport const normalizeRetryAfterMs = (value: unknown): number | undefined => {\n const normalized = normalizeNumber(value);\n if (normalized === undefined || normalized < 0) {\n return undefined;\n }\n\n return normalized;\n};\n\nconst toLowerString = (value: unknown): string | undefined => {\n if (typeof value !== \"string\") {\n return undefined;\n }\n\n return value.toLowerCase().trim();\n};\n\nconst classifyByHttpStatus = (status: number): ProviderRetryHint => {\n if (status >= 500) {\n return \"retryable\";\n }\n\n if (status === 408 || status === 425 || status === 429) {\n return \"retryable\";\n }\n\n return \"non_retryable\";\n};\n\nconst classifyByMessage = (message: string): ProviderRetryHint | undefined => {\n const normalized = message.toLowerCase();\n\n if (\n normalized.includes(\"timeout\") ||\n normalized.includes(\"temporar\") ||\n normalized.includes(\"network\") ||\n normalized.includes(\"retry\")\n ) {\n return \"retryable\";\n }\n\n return undefined;\n};\n\nexport class KMsgError extends Error {\n public readonly code: KMsgErrorCode;\n public readonly details?: Record<string, unknown>;\n public readonly providerErrorCode?: string;\n public readonly providerErrorText?: string;\n public readonly httpStatus?: number;\n public readonly requestId?: string;\n public readonly retryAfterMs?: number;\n public readonly attempt?: number;\n public readonly causeChain?: unknown[];\n\n constructor(\n code: KMsgErrorCode,\n message: string,\n details?: Record<string, unknown>,\n metadata: KMsgErrorMetadata = {},\n ) {\n super(message);\n this.name = \"KMsgError\";\n this.code = code;\n this.details = details;\n\n this.providerErrorCode = metadata.providerErrorCode;\n this.providerErrorText = metadata.providerErrorText;\n this.httpStatus = normalizeNumber(metadata.httpStatus);\n this.requestId =\n typeof metadata.requestId === \"string\" ? metadata.requestId : undefined;\n this.retryAfterMs = normalizeNumber(metadata.retryAfterMs);\n this.attempt = normalizeNumber(metadata.attempt);\n\n if (Array.isArray(metadata.causeChain)) {\n this.causeChain = metadata.causeChain;\n } else if (metadata.causeChain !== undefined) {\n this.causeChain = [metadata.causeChain];\n }\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, KMsgError);\n }\n }\n\n /**\n * Returns a localized error message based on the provided locale.\n * Falls back to Korean (default) if locale is not provided.\n * Falls back to the original message if no localized message exists.\n */\n getLocalizedMessage(locale: Locale = DEFAULT_LOCALE): string {\n const messages = ERROR_MESSAGES[this.code];\n if (messages?.[locale]) {\n return messages[locale];\n }\n return this.message;\n }\n\n toJSON() {\n return {\n name: this.name,\n code: this.code,\n message: this.message,\n details: this.details,\n providerErrorCode: this.providerErrorCode,\n providerErrorText: this.providerErrorText,\n httpStatus: this.httpStatus,\n requestId: this.requestId,\n retryAfterMs: this.retryAfterMs,\n attempt: this.attempt,\n causeChain: this.causeChain,\n };\n }\n}\n\nexport const ErrorUtils = {\n isRetryable(error: unknown, policy: ErrorRetryPolicy = {}): boolean {\n return ErrorUtils.classifyForRetry(error, policy) === \"retryable\";\n },\n\n classifyForRetry(\n error: unknown,\n policy: ErrorRetryPolicy = {},\n ): ProviderRetryHint {\n if (error instanceof KMsgError) {\n const retryableCodes = new Set(\n policy.retryableCodes ?? Array.from(DEFAULT_RETRYABLE_ERROR_CODES),\n );\n if (retryableCodes.has(error.code)) {\n return \"retryable\";\n }\n\n const nonRetryableCodes = new Set(\n policy.nonRetryableCodes ??\n Array.from(DEFAULT_NON_RETRYABLE_ERROR_CODES),\n );\n if (nonRetryableCodes.has(error.code)) {\n return \"non_retryable\";\n }\n\n if (error.httpStatus !== undefined) {\n return classifyByHttpStatus(error.httpStatus);\n }\n\n const classifiedByMessage = classifyByMessage(error.message);\n if (classifiedByMessage) {\n return classifiedByMessage;\n }\n\n if (policy.classifyByMessage && error.message) {\n const classified = policy.classifyByMessage(error.message);\n if (classified) {\n return classified;\n }\n }\n\n if (policy.fallback) {\n return policy.fallback;\n }\n\n return \"non_retryable\";\n }\n\n const candidate =\n error && typeof error === \"object\"\n ? (error as {\n status?: unknown;\n statusCode?: unknown;\n httpStatus?: unknown;\n code?: unknown;\n message?: unknown;\n })\n : undefined;\n\n const status =\n toLowerString(candidate?.status) ??\n toLowerString(candidate?.statusCode) ??\n toLowerString(candidate?.code);\n const statusCode =\n normalizeNumber(candidate?.status) ??\n normalizeNumber(candidate?.statusCode) ??\n normalizeNumber(candidate?.httpStatus);\n\n if (typeof status === \"string\" && status.startsWith(\"5\")) {\n return \"retryable\";\n }\n\n if (statusCode !== undefined) {\n if (policy.classifyByStatusCode) {\n return policy.classifyByStatusCode(statusCode);\n }\n\n return classifyByHttpStatus(statusCode);\n }\n\n const classifiedByMessage =\n typeof candidate?.message === \"string\"\n ? classifyByMessage(candidate.message)\n : undefined;\n\n if (classifiedByMessage) {\n return classifiedByMessage;\n }\n\n if (policy.classifyByMessage && typeof candidate?.message === \"string\") {\n const classified = policy.classifyByMessage(candidate.message);\n if (classified) {\n return classified;\n }\n }\n\n return policy.fallback ?? \"non_retryable\";\n },\n\n resolveRetryAfterMs(\n error: KMsgError,\n policy?: ErrorRetryPolicy,\n ): number | undefined {\n if (policy?.retryAfterMs) {\n const override = policy.retryAfterMs(error);\n const normalized = normalizeRetryAfterMs(override);\n if (normalized !== undefined) {\n return normalized;\n }\n }\n\n if (error.retryAfterMs !== undefined) {\n return normalizeRetryAfterMs(error.retryAfterMs);\n }\n\n if (\n error.code === KMsgErrorCode.RATE_LIMIT_EXCEEDED &&\n error.retryAfterMs === undefined\n ) {\n return undefined;\n }\n\n return undefined;\n },\n\n isUnknownStatus: (statusCode: number | undefined): boolean => {\n if (\n statusCode === undefined ||\n Number.isNaN(statusCode) ||\n !Number.isFinite(statusCode)\n ) {\n return false;\n }\n\n return statusCode < 500;\n },\n\n toRetryMetadata(error: KMsgError): KMsgErrorMetadata {\n return {\n providerErrorCode: error.providerErrorCode,\n providerErrorText: error.providerErrorText,\n httpStatus: error.httpStatus,\n requestId: error.requestId,\n retryAfterMs: error.retryAfterMs,\n attempt: error.attempt,\n causeChain: error.causeChain,\n };\n },\n\n withAttempt(error: KMsgError, attempt: number): KMsgError {\n return new KMsgError(error.code, error.message, error.details, {\n ...ErrorUtils.toRetryMetadata(error),\n attempt: normalizeNumber(attempt),\n });\n },\n\n DEFAULT_RETRYABLE_ERROR_CODES,\n DEFAULT_NON_RETRYABLE_ERROR_CODES,\n};\n",
|
|
5
|
+
"export type Locale = \"ko\" | \"en\";\n\nexport enum KMsgErrorCode {\n INVALID_REQUEST = \"INVALID_REQUEST\",\n AUTHENTICATION_FAILED = \"AUTHENTICATION_FAILED\",\n INSUFFICIENT_BALANCE = \"INSUFFICIENT_BALANCE\",\n TEMPLATE_NOT_FOUND = \"TEMPLATE_NOT_FOUND\",\n RATE_LIMIT_EXCEEDED = \"RATE_LIMIT_EXCEEDED\",\n NETWORK_ERROR = \"NETWORK_ERROR\",\n NETWORK_TIMEOUT = \"NETWORK_TIMEOUT\",\n NETWORK_SERVICE_UNAVAILABLE = \"NETWORK_SERVICE_UNAVAILABLE\",\n PROVIDER_ERROR = \"PROVIDER_ERROR\",\n MESSAGE_SEND_FAILED = \"MESSAGE_SEND_FAILED\",\n CRYPTO_CONFIG_ERROR = \"CRYPTO_CONFIG_ERROR\",\n CRYPTO_ENCRYPT_FAILED = \"CRYPTO_ENCRYPT_FAILED\",\n CRYPTO_DECRYPT_FAILED = \"CRYPTO_DECRYPT_FAILED\",\n CRYPTO_HASH_FAILED = \"CRYPTO_HASH_FAILED\",\n CRYPTO_POLICY_VIOLATION = \"CRYPTO_POLICY_VIOLATION\",\n UNKNOWN_ERROR = \"UNKNOWN_ERROR\",\n}\n\nconst DEFAULT_LOCALE: Locale = \"ko\";\n\nconst ERROR_MESSAGES: Record<KMsgErrorCode, { ko: string; en: string }> = {\n [KMsgErrorCode.INVALID_REQUEST]: {\n ko: \"잘못된 요청입니다\",\n en: \"Invalid request\",\n },\n [KMsgErrorCode.AUTHENTICATION_FAILED]: {\n ko: \"인증에 실패했습니다\",\n en: \"Authentication failed\",\n },\n [KMsgErrorCode.INSUFFICIENT_BALANCE]: {\n ko: \"잔액이 부족합니다\",\n en: \"Insufficient balance\",\n },\n [KMsgErrorCode.TEMPLATE_NOT_FOUND]: {\n ko: \"템플릿을 찾을 수 없습니다\",\n en: \"Template not found\",\n },\n [KMsgErrorCode.RATE_LIMIT_EXCEEDED]: {\n ko: \"요청 한도를 초과했습니다\",\n en: \"Rate limit exceeded\",\n },\n [KMsgErrorCode.NETWORK_ERROR]: {\n ko: \"네트워크 오류가 발생했습니다\",\n en: \"Network error\",\n },\n [KMsgErrorCode.NETWORK_TIMEOUT]: {\n ko: \"네트워크 요청 시간이 초과되었습니다\",\n en: \"Network timeout\",\n },\n [KMsgErrorCode.NETWORK_SERVICE_UNAVAILABLE]: {\n ko: \"서비스를 일시적으로 사용할 수 없습니다\",\n en: \"Service temporarily unavailable\",\n },\n [KMsgErrorCode.PROVIDER_ERROR]: {\n ko: \"제공자 오류가 발생했습니다\",\n en: \"Provider error\",\n },\n [KMsgErrorCode.MESSAGE_SEND_FAILED]: {\n ko: \"메시지 전송에 실패했습니다\",\n en: \"Message send failed\",\n },\n [KMsgErrorCode.CRYPTO_CONFIG_ERROR]: {\n ko: \"암호화 설정 오류가 발생했습니다\",\n en: \"Crypto configuration error\",\n },\n [KMsgErrorCode.CRYPTO_ENCRYPT_FAILED]: {\n ko: \"암호화에 실패했습니다\",\n en: \"Encryption failed\",\n },\n [KMsgErrorCode.CRYPTO_DECRYPT_FAILED]: {\n ko: \"복호화에 실패했습니다\",\n en: \"Decryption failed\",\n },\n [KMsgErrorCode.CRYPTO_HASH_FAILED]: {\n ko: \"해시 생성에 실패했습니다\",\n en: \"Hash generation failed\",\n },\n [KMsgErrorCode.CRYPTO_POLICY_VIOLATION]: {\n ko: \"암호화 정책 위반이 발생했습니다\",\n en: \"Crypto policy violation\",\n },\n [KMsgErrorCode.UNKNOWN_ERROR]: {\n ko: \"알 수 없는 오류가 발생했습니다\",\n en: \"Unknown error\",\n },\n};\n\nexport type RetryPolicyErrorCode = KMsgErrorCode;\n\nexport type ProviderRetryHint = \"retryable\" | \"non_retryable\";\n\nexport interface KMsgErrorMetadata {\n providerErrorCode?: string;\n providerErrorText?: string;\n httpStatus?: number;\n requestId?: string;\n retryAfterMs?: number;\n attempt?: number;\n causeChain?: unknown[];\n}\n\nexport interface ErrorRetryPolicy {\n retryableCodes?: readonly KMsgErrorCode[];\n nonRetryableCodes?: readonly KMsgErrorCode[];\n classifyByStatusCode?: (status: number) => ProviderRetryHint;\n classifyByMessage?: (message: string) => ProviderRetryHint | undefined;\n /**\n * Optional override for retry hint inference.\n */\n fallback?: ProviderRetryHint;\n /**\n * Optional custom retry delay in milliseconds.\n */\n retryAfterMs?: (error: KMsgError) => number | undefined;\n}\n\nexport type ErrorRetryPolicyMode = \"safe\" | \"compat\";\n\nexport interface ErrorRetryPolicyIssue {\n code: string;\n message: string;\n path: string;\n}\n\nexport interface ErrorRetryPolicyValidationResult {\n policy: ErrorRetryPolicy | null;\n issues: ErrorRetryPolicyIssue[];\n}\n\nexport interface ErrorRetryPolicyNormalizeOptions {\n mode?: ErrorRetryPolicyMode;\n}\n\nexport type ProviderErrorSource =\n | \"metadata\"\n | \"details\"\n | \"http\"\n | \"fallback\"\n | \"policy\"\n | \"input\";\n\nexport interface NormalizedProviderErrorSources {\n code: ProviderErrorSource;\n classification: ProviderErrorSource;\n providerErrorCode?: ProviderErrorSource;\n providerErrorText?: ProviderErrorSource;\n httpStatus?: ProviderErrorSource;\n requestId?: ProviderErrorSource;\n retryAfterMs?: ProviderErrorSource;\n causeChain?: ProviderErrorSource;\n attempt?: ProviderErrorSource;\n}\n\nexport interface NormalizedProviderError {\n code: KMsgErrorCode;\n classification: ProviderRetryHint;\n providerErrorCode?: string;\n providerErrorText?: string;\n httpStatus?: number;\n requestId?: string;\n retryAfterMs?: number;\n causeChain?: unknown[];\n attempt?: number;\n sources: NormalizedProviderErrorSources;\n}\n\nexport interface NormalizeProviderErrorOptions {\n mode?: ErrorRetryPolicyMode;\n policy?: ErrorRetryPolicy;\n attempt?: number;\n defaultCode?: KMsgErrorCode;\n}\n\nconst KNOWN_KMSG_ERROR_CODES: ReadonlySet<string> = new Set(\n Object.values(KMsgErrorCode),\n);\n\nconst DEFAULT_RETRYABLE_ERROR_CODES: ReadonlySet<RetryPolicyErrorCode> =\n new Set([\n KMsgErrorCode.NETWORK_ERROR,\n KMsgErrorCode.RATE_LIMIT_EXCEEDED,\n KMsgErrorCode.NETWORK_TIMEOUT,\n KMsgErrorCode.NETWORK_SERVICE_UNAVAILABLE,\n KMsgErrorCode.PROVIDER_ERROR,\n KMsgErrorCode.UNKNOWN_ERROR,\n ]);\n\nconst DEFAULT_NON_RETRYABLE_ERROR_CODES: ReadonlySet<RetryPolicyErrorCode> =\n new Set([\n KMsgErrorCode.INVALID_REQUEST,\n KMsgErrorCode.AUTHENTICATION_FAILED,\n KMsgErrorCode.INSUFFICIENT_BALANCE,\n KMsgErrorCode.TEMPLATE_NOT_FOUND,\n KMsgErrorCode.MESSAGE_SEND_FAILED,\n KMsgErrorCode.CRYPTO_CONFIG_ERROR,\n KMsgErrorCode.CRYPTO_ENCRYPT_FAILED,\n KMsgErrorCode.CRYPTO_DECRYPT_FAILED,\n KMsgErrorCode.CRYPTO_HASH_FAILED,\n KMsgErrorCode.CRYPTO_POLICY_VIOLATION,\n ]);\n\nconst normalizeNumber = (value: unknown): number | undefined => {\n if (\n typeof value !== \"number\" ||\n Number.isNaN(value) ||\n !Number.isFinite(value)\n ) {\n return undefined;\n }\n\n return Math.trunc(value);\n};\n\nexport const normalizeRetryAfterMs = (value: unknown): number | undefined => {\n const normalized = normalizeNumber(value);\n if (normalized === undefined || normalized < 0) {\n return undefined;\n }\n\n return normalized;\n};\n\nconst toLowerString = (value: unknown): string | undefined => {\n if (typeof value !== \"string\") {\n return undefined;\n }\n\n return value.toLowerCase().trim();\n};\n\nconst toTrimmedString = (value: unknown): string | undefined => {\n if (typeof value !== \"string\") {\n return undefined;\n }\n\n const normalized = value.trim();\n return normalized.length > 0 ? normalized : undefined;\n};\n\nconst isObjectRecord = (value: unknown): value is Record<string, unknown> => {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n};\n\nconst pickByKey = (\n value: Record<string, unknown>,\n keys: readonly string[],\n): unknown => {\n for (const key of keys) {\n if (key in value) {\n return value[key];\n }\n }\n return undefined;\n};\n\nconst ensureIssuePath = (path: string): string => {\n return path.length > 0 ? path : \"$\";\n};\n\nconst normalizePolicyMode = (\n mode: ErrorRetryPolicyMode | undefined,\n): ErrorRetryPolicyMode => {\n return mode === \"compat\" ? \"compat\" : \"safe\";\n};\n\nconst classifyByHttpStatus = (status: number): ProviderRetryHint => {\n if (status >= 500) {\n return \"retryable\";\n }\n\n if (status === 408 || status === 425 || status === 429) {\n return \"retryable\";\n }\n\n return \"non_retryable\";\n};\n\nconst classifyByMessage = (message: string): ProviderRetryHint | undefined => {\n const normalized = message.toLowerCase();\n\n if (\n normalized.includes(\"timeout\") ||\n normalized.includes(\"temporar\") ||\n normalized.includes(\"network\") ||\n normalized.includes(\"retry\")\n ) {\n return \"retryable\";\n }\n\n return undefined;\n};\n\nexport class KMsgError extends Error {\n public readonly code: KMsgErrorCode;\n public readonly details?: Record<string, unknown>;\n public readonly providerErrorCode?: string;\n public readonly providerErrorText?: string;\n public readonly httpStatus?: number;\n public readonly requestId?: string;\n public readonly retryAfterMs?: number;\n public readonly attempt?: number;\n public readonly causeChain?: unknown[];\n\n constructor(\n code: KMsgErrorCode,\n message: string,\n details?: Record<string, unknown>,\n metadata: KMsgErrorMetadata = {},\n ) {\n super(message);\n this.name = \"KMsgError\";\n this.code = code;\n this.details = details;\n\n this.providerErrorCode = metadata.providerErrorCode;\n this.providerErrorText = metadata.providerErrorText;\n this.httpStatus = normalizeNumber(metadata.httpStatus);\n this.requestId =\n typeof metadata.requestId === \"string\" ? metadata.requestId : undefined;\n this.retryAfterMs = normalizeNumber(metadata.retryAfterMs);\n this.attempt = normalizeNumber(metadata.attempt);\n\n if (Array.isArray(metadata.causeChain)) {\n this.causeChain = metadata.causeChain;\n } else if (metadata.causeChain !== undefined) {\n this.causeChain = [metadata.causeChain];\n }\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, KMsgError);\n }\n }\n\n /**\n * Returns a localized error message based on the provided locale.\n * Falls back to Korean (default) if locale is not provided.\n * Falls back to the original message if no localized message exists.\n */\n getLocalizedMessage(locale: Locale = DEFAULT_LOCALE): string {\n const messages = ERROR_MESSAGES[this.code];\n if (messages?.[locale]) {\n return messages[locale];\n }\n return this.message;\n }\n\n toJSON() {\n return {\n name: this.name,\n code: this.code,\n message: this.message,\n details: this.details,\n providerErrorCode: this.providerErrorCode,\n providerErrorText: this.providerErrorText,\n httpStatus: this.httpStatus,\n requestId: this.requestId,\n retryAfterMs: this.retryAfterMs,\n attempt: this.attempt,\n causeChain: this.causeChain,\n };\n }\n}\n\nconst normalizeIntegerLike = (\n value: unknown,\n mode: ErrorRetryPolicyMode,\n): number | undefined => {\n const normalized = normalizeNumber(value);\n if (normalized !== undefined) return normalized;\n\n if (mode === \"compat\" && typeof value === \"string\") {\n const parsed = Number(value.trim());\n if (Number.isFinite(parsed)) {\n return Math.trunc(parsed);\n }\n }\n\n return undefined;\n};\n\nconst normalizeStringLike = (\n value: unknown,\n mode: ErrorRetryPolicyMode,\n): string | undefined => {\n const fromString = toTrimmedString(value);\n if (fromString) return fromString;\n\n if (\n mode === \"compat\" &&\n (typeof value === \"number\" || typeof value === \"boolean\")\n ) {\n return String(value);\n }\n\n return undefined;\n};\n\nconst normalizeKMsgErrorCode = (value: unknown): KMsgErrorCode | undefined => {\n if (typeof value !== \"string\") {\n return undefined;\n }\n\n const normalized = value.trim().toUpperCase();\n if (!KNOWN_KMSG_ERROR_CODES.has(normalized)) {\n return undefined;\n }\n\n return normalized as KMsgErrorCode;\n};\n\nconst pushPolicyIssue = (\n issues: ErrorRetryPolicyIssue[],\n issue: ErrorRetryPolicyIssue,\n) => {\n issues.push({\n ...issue,\n path: ensureIssuePath(issue.path),\n });\n};\n\nconst normalizePolicyCodeList = (\n value: unknown,\n path: string,\n mode: ErrorRetryPolicyMode,\n issues: ErrorRetryPolicyIssue[],\n): KMsgErrorCode[] => {\n if (value === undefined) return [];\n\n const items: unknown[] = (() => {\n if (Array.isArray(value)) return value;\n if (mode === \"compat\" && typeof value === \"string\") {\n return value\n .split(\",\")\n .map((item) => item.trim())\n .filter((item) => item.length > 0);\n }\n\n pushPolicyIssue(issues, {\n code: \"invalid_type\",\n message: \"expected array of KMsgErrorCode values\",\n path,\n });\n return [];\n })();\n\n const out: KMsgErrorCode[] = [];\n const seen = new Set<KMsgErrorCode>();\n\n for (let index = 0; index < items.length; index += 1) {\n const item = items[index];\n const code = normalizeKMsgErrorCode(\n typeof item === \"string\" ? item : mode === \"compat\" ? String(item) : item,\n );\n\n if (!code) {\n pushPolicyIssue(issues, {\n code: \"unknown_code\",\n message: `unknown retry policy code: ${String(item)}`,\n path: `${path}[${index}]`,\n });\n continue;\n }\n\n if (seen.has(code)) {\n pushPolicyIssue(issues, {\n code: \"duplicate_code\",\n message: `duplicate retry policy code: ${code}`,\n path: `${path}[${index}]`,\n });\n continue;\n }\n\n seen.add(code);\n out.push(code);\n }\n\n return out;\n};\n\nconst normalizeRetryFallback = (\n value: unknown,\n mode: ErrorRetryPolicyMode,\n issues: ErrorRetryPolicyIssue[],\n): ProviderRetryHint | undefined => {\n if (value === undefined) return undefined;\n\n if (typeof value === \"string\") {\n const normalized = value.trim().toLowerCase();\n if (normalized === \"retryable\") return \"retryable\";\n if (normalized === \"non_retryable\" || normalized === \"non-retryable\") {\n return \"non_retryable\";\n }\n }\n\n if (mode === \"compat\" && typeof value === \"boolean\") {\n return value ? \"retryable\" : \"non_retryable\";\n }\n\n pushPolicyIssue(issues, {\n code: \"invalid_fallback\",\n message: `invalid fallback value: ${String(value)}`,\n path: \"fallback\",\n });\n return undefined;\n};\n\nexport function validateErrorRetryPolicy(\n input: unknown,\n options: ErrorRetryPolicyNormalizeOptions = {},\n): ErrorRetryPolicyValidationResult {\n const mode = normalizePolicyMode(options.mode);\n const issues: ErrorRetryPolicyIssue[] = [];\n\n if (!isObjectRecord(input)) {\n pushPolicyIssue(issues, {\n code: \"invalid_root\",\n message: \"retry policy must be an object\",\n path: \"$\",\n });\n return { policy: null, issues };\n }\n\n const knownKeys = new Set([\n \"retryableCodes\",\n \"nonRetryableCodes\",\n \"fallback\",\n ]);\n for (const key of Object.keys(input)) {\n if (knownKeys.has(key)) continue;\n pushPolicyIssue(issues, {\n code: \"unknown_field\",\n message: `unknown retry policy field: ${key}`,\n path: key,\n });\n }\n\n const retryableCodes = normalizePolicyCodeList(\n input.retryableCodes,\n \"retryableCodes\",\n mode,\n issues,\n );\n const nonRetryableCodes = normalizePolicyCodeList(\n input.nonRetryableCodes,\n \"nonRetryableCodes\",\n mode,\n issues,\n );\n const fallback = normalizeRetryFallback(input.fallback, mode, issues);\n\n const retryableSet = new Set(retryableCodes);\n const nonRetryableSet = new Set(nonRetryableCodes);\n\n for (const code of retryableSet) {\n if (!nonRetryableSet.has(code)) continue;\n retryableSet.delete(code);\n pushPolicyIssue(issues, {\n code: \"conflicting_code\",\n message: `code '${code}' is both retryable and nonRetryable; nonRetryable wins`,\n path: \"retryableCodes\",\n });\n }\n\n const policy: ErrorRetryPolicy = {\n ...(retryableSet.size > 0\n ? { retryableCodes: Array.from(retryableSet) }\n : {}),\n ...(nonRetryableSet.size > 0\n ? { nonRetryableCodes: Array.from(nonRetryableSet) }\n : {}),\n ...(fallback ? { fallback } : {}),\n };\n\n const hasConfig =\n policy.retryableCodes !== undefined ||\n policy.nonRetryableCodes !== undefined ||\n policy.fallback !== undefined;\n\n return {\n policy: hasConfig ? policy : null,\n issues,\n };\n}\n\nexport function normalizeErrorRetryPolicy(\n input: unknown,\n options: ErrorRetryPolicyNormalizeOptions = {},\n): ErrorRetryPolicy | null {\n return validateErrorRetryPolicy(input, options).policy;\n}\n\nexport function parseErrorRetryPolicyFromJson(\n raw: string,\n options: ErrorRetryPolicyNormalizeOptions = {},\n): ErrorRetryPolicy | null {\n if (typeof raw !== \"string\" || raw.trim().length === 0) {\n return null;\n }\n\n try {\n const parsed = JSON.parse(raw);\n return normalizeErrorRetryPolicy(parsed, options);\n } catch {\n return null;\n }\n}\n\nconst resolveNestedHttpStatus = (\n record: Record<string, unknown>,\n mode: ErrorRetryPolicyMode,\n): number | undefined => {\n const response = record.response;\n if (!isObjectRecord(response)) {\n return undefined;\n }\n\n return normalizeIntegerLike(\n pickByKey(response, [\"status\", \"statusCode\", \"httpStatus\"]),\n mode,\n );\n};\n\nconst resolveCauseChain = (\n error: unknown,\n mode: ErrorRetryPolicyMode,\n): unknown[] | undefined => {\n if (error instanceof KMsgError && Array.isArray(error.causeChain)) {\n return error.causeChain.slice();\n }\n\n if (isObjectRecord(error)) {\n const fromChain = error.causeChain;\n if (Array.isArray(fromChain)) {\n return fromChain.slice();\n }\n\n const details = error.details;\n if (mode === \"compat\" && isObjectRecord(details)) {\n const detailChain = details.causeChain;\n if (Array.isArray(detailChain)) {\n return detailChain.slice();\n }\n if (detailChain !== undefined) {\n return [detailChain];\n }\n }\n }\n\n const chain: unknown[] = [];\n const seen = new Set<unknown>();\n let cursor: unknown = error;\n\n for (let depth = 0; depth < 8; depth += 1) {\n if (!isObjectRecord(cursor)) break;\n const cause = cursor.cause;\n if (cause === undefined || seen.has(cause)) break;\n seen.add(cause);\n chain.push(cause);\n cursor = cause;\n }\n\n return chain.length > 0 ? chain : undefined;\n};\n\nconst resolveErrorMessage = (error: unknown): string => {\n if (error instanceof Error && typeof error.message === \"string\") {\n return error.message;\n }\n\n if (isObjectRecord(error) && typeof error.message === \"string\") {\n return error.message;\n }\n\n return typeof error === \"string\" ? error : \"Unknown error\";\n};\n\nexport function normalizeProviderError(\n error: unknown,\n options: NormalizeProviderErrorOptions = {},\n): NormalizedProviderError {\n const mode = normalizePolicyMode(options.mode);\n const defaultCode = options.defaultCode ?? KMsgErrorCode.UNKNOWN_ERROR;\n\n let code = defaultCode;\n const sources: NormalizedProviderErrorSources = {\n code: \"fallback\",\n classification: options.policy ? \"policy\" : \"fallback\",\n };\n\n let providerErrorCode: string | undefined;\n let providerErrorText: string | undefined;\n let httpStatus: number | undefined;\n let requestId: string | undefined;\n let retryAfterMs: number | undefined;\n let attempt: number | undefined;\n let causeChain: unknown[] | undefined;\n\n const assignFromMetadata = (candidate: KMsgError) => {\n if (candidate.providerErrorCode !== undefined) {\n providerErrorCode = candidate.providerErrorCode;\n sources.providerErrorCode = \"metadata\";\n }\n if (candidate.providerErrorText !== undefined) {\n providerErrorText = candidate.providerErrorText;\n sources.providerErrorText = \"metadata\";\n }\n if (candidate.httpStatus !== undefined) {\n httpStatus = candidate.httpStatus;\n sources.httpStatus = \"metadata\";\n }\n if (candidate.requestId !== undefined) {\n requestId = candidate.requestId;\n sources.requestId = \"metadata\";\n }\n if (candidate.retryAfterMs !== undefined) {\n retryAfterMs = normalizeRetryAfterMs(candidate.retryAfterMs);\n sources.retryAfterMs = \"metadata\";\n }\n if (candidate.attempt !== undefined) {\n attempt = normalizeIntegerLike(candidate.attempt, mode);\n sources.attempt = \"metadata\";\n }\n if (Array.isArray(candidate.causeChain)) {\n causeChain = candidate.causeChain.slice();\n sources.causeChain = \"metadata\";\n }\n };\n\n const assignFromRecord = (\n record: Record<string, unknown>,\n source: ProviderErrorSource,\n ) => {\n if (providerErrorCode === undefined) {\n const next = normalizeStringLike(\n pickByKey(record, [\"providerErrorCode\", \"errorCode\", \"resultCode\"]),\n mode,\n );\n if (next !== undefined) {\n providerErrorCode = next;\n sources.providerErrorCode = source;\n }\n }\n\n if (providerErrorText === undefined) {\n const next = normalizeStringLike(\n pickByKey(record, [\n \"providerErrorText\",\n \"errorMessage\",\n \"msg\",\n \"message\",\n ]),\n mode,\n );\n if (next !== undefined) {\n providerErrorText = next;\n sources.providerErrorText = source;\n }\n }\n\n if (httpStatus === undefined) {\n const next =\n normalizeIntegerLike(\n pickByKey(record, [\"httpStatus\", \"statusCode\", \"status\"]),\n mode,\n ) ?? resolveNestedHttpStatus(record, mode);\n if (next !== undefined) {\n httpStatus = next;\n sources.httpStatus = source === \"details\" ? \"details\" : \"http\";\n }\n }\n\n if (requestId === undefined) {\n const next = normalizeStringLike(\n pickByKey(record, [\"requestId\", \"request_id\", \"reqId\", \"traceId\"]),\n mode,\n );\n if (next !== undefined) {\n requestId = next;\n sources.requestId = source;\n }\n }\n\n if (retryAfterMs === undefined) {\n const next = normalizeRetryAfterMs(\n normalizeIntegerLike(\n pickByKey(record, [\"retryAfterMs\", \"retry_after_ms\", \"retryAfter\"]),\n mode,\n ),\n );\n if (next !== undefined) {\n retryAfterMs = next;\n sources.retryAfterMs = source;\n }\n }\n\n if (attempt === undefined) {\n const next = normalizeIntegerLike(record.attempt, mode);\n if (next !== undefined && next > 0) {\n attempt = next;\n sources.attempt = source;\n }\n }\n };\n\n if (error instanceof KMsgError) {\n code = error.code;\n sources.code = \"input\";\n assignFromMetadata(error);\n\n if (mode === \"compat\" && isObjectRecord(error.details)) {\n assignFromRecord(error.details, \"details\");\n }\n } else if (isObjectRecord(error)) {\n const candidateCode = normalizeKMsgErrorCode(\n pickByKey(error, [\"code\", \"errorCode\", \"resultCode\"]),\n );\n if (candidateCode !== undefined) {\n code = candidateCode;\n sources.code = \"input\";\n } else if (httpStatus === undefined) {\n const nextStatus =\n normalizeIntegerLike(\n pickByKey(error, [\"httpStatus\", \"statusCode\", \"status\"]),\n mode,\n ) ?? resolveNestedHttpStatus(error, mode);\n if (nextStatus !== undefined && nextStatus >= 500) {\n code = KMsgErrorCode.PROVIDER_ERROR;\n sources.code = \"http\";\n }\n }\n\n assignFromRecord(error, \"input\");\n if (mode === \"compat\" && isObjectRecord(error.details)) {\n assignFromRecord(error.details, \"details\");\n }\n }\n\n if (causeChain === undefined) {\n const nextCauseChain = resolveCauseChain(error, mode);\n if (nextCauseChain !== undefined) {\n causeChain = nextCauseChain;\n sources.causeChain = \"input\";\n }\n }\n\n if (\n options.attempt !== undefined &&\n normalizeIntegerLike(options.attempt, mode) !== undefined\n ) {\n const normalizedAttempt = normalizeIntegerLike(options.attempt, mode);\n if (normalizedAttempt !== undefined && normalizedAttempt > 0) {\n attempt = normalizedAttempt;\n sources.attempt = \"input\";\n }\n }\n\n const classificationProbe = new KMsgError(\n code,\n resolveErrorMessage(error),\n undefined,\n {\n providerErrorCode,\n providerErrorText,\n httpStatus,\n requestId,\n retryAfterMs,\n attempt,\n causeChain,\n },\n );\n const classification = ErrorUtils.classifyForRetry(\n classificationProbe,\n options.policy,\n );\n\n return {\n code,\n classification,\n ...(providerErrorCode !== undefined ? { providerErrorCode } : {}),\n ...(providerErrorText !== undefined ? { providerErrorText } : {}),\n ...(httpStatus !== undefined ? { httpStatus } : {}),\n ...(requestId !== undefined ? { requestId } : {}),\n ...(retryAfterMs !== undefined ? { retryAfterMs } : {}),\n ...(attempt !== undefined ? { attempt } : {}),\n ...(causeChain !== undefined ? { causeChain } : {}),\n sources,\n };\n}\n\nexport const ErrorUtils = {\n isRetryable(error: unknown, policy: ErrorRetryPolicy = {}): boolean {\n return ErrorUtils.classifyForRetry(error, policy) === \"retryable\";\n },\n\n classifyForRetry(\n error: unknown,\n policy: ErrorRetryPolicy = {},\n ): ProviderRetryHint {\n if (error instanceof KMsgError) {\n const retryableCodes = new Set(\n policy.retryableCodes ?? Array.from(DEFAULT_RETRYABLE_ERROR_CODES),\n );\n if (retryableCodes.has(error.code)) {\n return \"retryable\";\n }\n\n const nonRetryableCodes = new Set(\n policy.nonRetryableCodes ??\n Array.from(DEFAULT_NON_RETRYABLE_ERROR_CODES),\n );\n if (nonRetryableCodes.has(error.code)) {\n return \"non_retryable\";\n }\n\n if (error.httpStatus !== undefined) {\n return classifyByHttpStatus(error.httpStatus);\n }\n\n const classifiedByMessage = classifyByMessage(error.message);\n if (classifiedByMessage) {\n return classifiedByMessage;\n }\n\n if (policy.classifyByMessage && error.message) {\n const classified = policy.classifyByMessage(error.message);\n if (classified) {\n return classified;\n }\n }\n\n if (policy.fallback) {\n return policy.fallback;\n }\n\n return \"non_retryable\";\n }\n\n const candidate =\n error && typeof error === \"object\"\n ? (error as {\n status?: unknown;\n statusCode?: unknown;\n httpStatus?: unknown;\n code?: unknown;\n message?: unknown;\n })\n : undefined;\n\n const status =\n toLowerString(candidate?.status) ??\n toLowerString(candidate?.statusCode) ??\n toLowerString(candidate?.code);\n const statusCode =\n normalizeNumber(candidate?.status) ??\n normalizeNumber(candidate?.statusCode) ??\n normalizeNumber(candidate?.httpStatus);\n\n if (typeof status === \"string\" && status.startsWith(\"5\")) {\n return \"retryable\";\n }\n\n if (statusCode !== undefined) {\n if (policy.classifyByStatusCode) {\n return policy.classifyByStatusCode(statusCode);\n }\n\n return classifyByHttpStatus(statusCode);\n }\n\n const classifiedByMessage =\n typeof candidate?.message === \"string\"\n ? classifyByMessage(candidate.message)\n : undefined;\n\n if (classifiedByMessage) {\n return classifiedByMessage;\n }\n\n if (policy.classifyByMessage && typeof candidate?.message === \"string\") {\n const classified = policy.classifyByMessage(candidate.message);\n if (classified) {\n return classified;\n }\n }\n\n return policy.fallback ?? \"non_retryable\";\n },\n\n resolveRetryAfterMs(\n error: KMsgError,\n policy?: ErrorRetryPolicy,\n ): number | undefined {\n if (policy?.retryAfterMs) {\n const override = policy.retryAfterMs(error);\n const normalized = normalizeRetryAfterMs(override);\n if (normalized !== undefined) {\n return normalized;\n }\n }\n\n if (error.retryAfterMs !== undefined) {\n return normalizeRetryAfterMs(error.retryAfterMs);\n }\n\n if (\n error.code === KMsgErrorCode.RATE_LIMIT_EXCEEDED &&\n error.retryAfterMs === undefined\n ) {\n return undefined;\n }\n\n return undefined;\n },\n\n isUnknownStatus: (statusCode: number | undefined): boolean => {\n if (\n statusCode === undefined ||\n Number.isNaN(statusCode) ||\n !Number.isFinite(statusCode)\n ) {\n return false;\n }\n\n return statusCode < 500;\n },\n\n toRetryMetadata(error: KMsgError): KMsgErrorMetadata {\n return {\n providerErrorCode: error.providerErrorCode,\n providerErrorText: error.providerErrorText,\n httpStatus: error.httpStatus,\n requestId: error.requestId,\n retryAfterMs: error.retryAfterMs,\n attempt: error.attempt,\n causeChain: error.causeChain,\n };\n },\n\n withAttempt(error: KMsgError, attempt: number): KMsgError {\n return new KMsgError(error.code, error.message, error.details, {\n ...ErrorUtils.toRetryMetadata(error),\n attempt: normalizeNumber(attempt),\n });\n },\n\n DEFAULT_RETRYABLE_ERROR_CODES,\n DEFAULT_NON_RETRYABLE_ERROR_CODES,\n};\n",
|
|
6
6
|
"/**\n * Represents a successful result containing a value.\n */\nexport type Ok<T> = {\n /** Always true for successful results. */\n readonly isSuccess: true;\n /** Always false for successful results. */\n readonly isFailure: false;\n /** The contained success value. */\n readonly value: T;\n};\n\n/**\n * Represents a failed result containing an error.\n */\nexport type Fail<E> = {\n /** Always false for failed results. */\n readonly isSuccess: false;\n /** Always true for failed results. */\n readonly isFailure: true;\n /** The contained error. */\n readonly error: E;\n};\n\n/**\n * A result type that represents either success (Ok) or failure (Fail).\n * Used throughout k-msg for explicit error handling without exceptions.\n *\n * @template T - The type of the success value\n * @template E - The type of the error (defaults to Error)\n *\n * @example\n * ```ts\n * function divide(a: number, b: number): Result<number, string> {\n * if (b === 0) return fail(\"division by zero\");\n * return ok(a / b);\n * }\n *\n * const result = divide(10, 2);\n * if (result.isSuccess) {\n * console.log(result.value); // 5\n * } else {\n * console.error(result.error);\n * }\n * ```\n */\nexport type Result<T, E = Error> = Ok<T> | Fail<E>;\n\n/**\n * Create a successful result containing the given value.\n * @param value - The success value to wrap\n * @returns An Ok result containing the value\n */\nexport const ok = <T>(value: T): Ok<T> => ({\n isSuccess: true,\n isFailure: false,\n value,\n});\n\n/**\n * Create a failed result containing the given error.\n * @param error - The error to wrap\n * @returns A Fail result containing the error\n */\nexport const fail = <E>(error: E): Fail<E> => ({\n isSuccess: false,\n isFailure: true,\n error,\n});\n\n/**\n * Result utility functions for chaining and transformation\n */\nexport const Result = {\n /**\n * Transform the success value of a Result\n */\n map<T, U, E>(result: Result<T, E>, fn: (value: T) => U): Result<U, E> {\n if (result.isSuccess) {\n return ok(fn(result.value));\n }\n return result;\n },\n\n /**\n * Chain Result-returning operations\n */\n flatMap<T, U, E>(\n result: Result<T, E>,\n fn: (value: T) => Result<U, E>,\n ): Result<U, E> {\n if (result.isSuccess) {\n return fn(result.value);\n }\n return result;\n },\n\n /**\n * Transform the error of a Result\n */\n mapError<T, E, F>(result: Result<T, E>, fn: (error: E) => F): Result<T, F> {\n if (result.isFailure) {\n return fail(fn(result.error));\n }\n return result;\n },\n\n /**\n * Extract the value or throw the error\n */\n unwrap<T, E>(result: Result<T, E>): T {\n if (result.isSuccess) {\n return result.value;\n }\n throw result.error;\n },\n\n /**\n * Extract the value or return a default\n */\n unwrapOr<T, E>(result: Result<T, E>, defaultValue: T): T {\n if (result.isSuccess) {\n return result.value;\n }\n return defaultValue;\n },\n\n /**\n * Extract the value or compute a default from the error\n */\n unwrapOrElse<T, E>(result: Result<T, E>, fn: (error: E) => T): T {\n if (result.isSuccess) {\n return result.value;\n }\n return fn(result.error);\n },\n\n /**\n * Pattern match on a Result\n */\n match<T, E, U>(\n result: Result<T, E>,\n handlers: { ok: (value: T) => U; fail: (error: E) => U },\n ): U {\n if (result.isSuccess) {\n return handlers.ok(result.value);\n }\n return handlers.fail(result.error);\n },\n\n /**\n * Convert a Promise to a Result\n */\n async fromPromise<T, E = Error>(promise: Promise<T>): Promise<Result<T, E>> {\n try {\n const value = await promise;\n return ok(value);\n } catch (error) {\n return fail(error as E);\n }\n },\n\n /**\n * Check if a Result is Ok\n */\n isOk<T, E>(result: Result<T, E>): result is Ok<T> {\n return result.isSuccess;\n },\n\n /**\n * Check if a Result is Fail\n */\n isFail<T, E>(result: Result<T, E>): result is Fail<E> {\n return result.isFailure;\n },\n\n /**\n * Execute a side-effect without breaking the chain.\n * Calls fn with the result (ok or fail) and returns the same result.\n *\n * @param result - The Result to tap\n * @param fn - Side-effect function called with the result\n * @returns The same Result for chaining\n *\n * @example\n * ```ts\n * const result = await provider.send(options);\n * Result.tap(result, r => console.log('Completed:', r));\n * ```\n */\n tap<T, E>(\n result: Result<T, E>,\n fn: (result: Result<T, E>) => void,\n ): Result<T, E> {\n fn(result);\n return result;\n },\n\n /**\n * Execute a side-effect on success only.\n * Calls fn with the value only if result is ok, returns the same result.\n *\n * @param result - The Result to tap\n * @param fn - Side-effect function called with the value on success\n * @returns The same Result for chaining\n *\n * @example\n * ```ts\n * Result.tapOk(result, value => console.log('Success:', value.messageId));\n * ```\n */\n tapOk<T, E>(result: Result<T, E>, fn: (value: T) => void): Result<T, E> {\n if (result.isSuccess) {\n fn(result.value);\n }\n return result;\n },\n\n /**\n * Execute a side-effect on failure only.\n * Calls fn with the error only if result is fail, returns the same result.\n *\n * @param result - The Result to tap\n * @param fn - Side-effect function called with the error on failure\n * @returns The same Result for chaining\n *\n * @example\n * ```ts\n * Result.tapErr(result, error => console.error('Failed:', error.message));\n * ```\n */\n tapErr<T, E>(result: Result<T, E>, fn: (error: E) => void): Result<T, E> {\n if (result.isFailure) {\n fn(result.error);\n }\n return result;\n },\n\n /**\n * Return the value on success, or throw with a custom message on failure.\n * Use this when you want to convert a failed Result to an exception.\n *\n * @param result - The Result to expect\n * @param message - Custom error message to use if result is fail\n * @returns The success value\n * @throws Error with the provided message (and original error as cause)\n *\n * @example\n * ```ts\n * const value = Result.expect(result, 'Message send failed');\n * // throws Error('Message send failed') if result is fail\n * ```\n */\n expect<T, E>(result: Result<T, E>, message: string): T {\n if (result.isSuccess) {\n return result.value;\n }\n throw new Error(message, { cause: result.error });\n },\n};\n",
|
|
7
7
|
"import { KMsgError, KMsgErrorCode } from \"@k-msg/core\";\nimport type {\n KakaoChannelAliasEntry,\n KakaoChannelBindingSource,\n KakaoChannelListItem,\n KakaoChannelResolveInput,\n KakaoChannelResolverConfig,\n KakaoProviderConfigEntry,\n ResolvedKakaoChannelBinding,\n} from \"./types\";\n\nfunction readString(value: unknown): string | undefined {\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nfunction normalizeProviderType(value: string | undefined): string | undefined {\n if (!value) return undefined;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed.toLowerCase() : undefined;\n}\n\nfunction extractProviderBindingHint(provider: KakaoProviderConfigEntry): {\n senderKey?: string;\n plusId?: string;\n} {\n const cfg =\n provider.config && typeof provider.config === \"object\"\n ? provider.config\n : {};\n\n const senderKey =\n readString((cfg as Record<string, unknown>).senderKey) ??\n readString((cfg as Record<string, unknown>).kakaoPfId) ??\n readString((cfg as Record<string, unknown>).profileId);\n const plusId = readString((cfg as Record<string, unknown>).plusId);\n\n const providerType = normalizeProviderType(provider.type);\n if (providerType === \"solapi\") {\n return {\n senderKey:\n readString((cfg as Record<string, unknown>).kakaoPfId) ?? senderKey,\n ...(plusId ? { plusId } : {}),\n };\n }\n\n return {\n ...(senderKey ? { senderKey } : {}),\n ...(plusId ? { plusId } : {}),\n };\n}\n\nfunction dedupeKey(item: KakaoChannelListItem): string {\n return [\n item.providerId ?? \"\",\n item.senderKey ?? \"\",\n item.plusId ?? \"\",\n item.source,\n ].join(\"|\");\n}\n\nfunction selectSingleProviderId(\n providers: KakaoProviderConfigEntry[] | undefined,\n): string | undefined {\n if (!Array.isArray(providers) || providers.length !== 1) return undefined;\n return readString(providers[0]?.id);\n}\n\nexport class KakaoChannelBindingResolver {\n constructor(private readonly config: KakaoChannelResolverConfig) {}\n\n list(params?: { providerId?: string }): KakaoChannelListItem[] {\n const requestedProviderId = readString(params?.providerId);\n const aliases = this.config.aliases?.kakaoChannels ?? {};\n const items: KakaoChannelListItem[] = [];\n const seen = new Set<string>();\n\n const pushUnique = (item: KakaoChannelListItem): void => {\n if (requestedProviderId && item.providerId !== requestedProviderId) {\n return;\n }\n const key = dedupeKey(item);\n if (seen.has(key)) {\n return;\n }\n seen.add(key);\n items.push(item);\n };\n\n for (const [alias, entry] of Object.entries(aliases)) {\n const providerId = readString(entry.providerId);\n if (!providerId) continue;\n\n const senderKey = readString(entry.senderKey);\n const plusId = readString(entry.plusId);\n if (!senderKey && !plusId) continue;\n\n pushUnique({\n source: \"config\",\n alias,\n providerId,\n ...(senderKey ? { senderKey } : {}),\n ...(plusId ? { plusId } : {}),\n ...(readString(entry.name) ? { name: readString(entry.name) } : {}),\n });\n }\n\n const defaultsKakao = this.config.defaults?.kakao;\n const defaultsChannelAlias = readString(defaultsKakao?.channel);\n const defaultAliasEntry = defaultsChannelAlias\n ? aliases[defaultsChannelAlias]\n : undefined;\n const defaultProviderId =\n readString(defaultAliasEntry?.providerId) ??\n readString(this.config.routing?.defaultProviderId) ??\n selectSingleProviderId(this.config.providers);\n\n const defaultsSenderKey =\n readString(defaultsKakao?.senderKey) ??\n readString(defaultAliasEntry?.senderKey);\n const defaultsPlusId =\n readString(defaultsKakao?.plusId) ??\n readString(defaultAliasEntry?.plusId);\n\n if (defaultProviderId && (defaultsSenderKey || defaultsPlusId)) {\n pushUnique({\n source: \"config\",\n ...(defaultsChannelAlias ? { alias: defaultsChannelAlias } : {}),\n providerId: defaultProviderId,\n ...(defaultsSenderKey ? { senderKey: defaultsSenderKey } : {}),\n ...(defaultsPlusId ? { plusId: defaultsPlusId } : {}),\n ...(readString(defaultAliasEntry?.name)\n ? { name: readString(defaultAliasEntry?.name) }\n : {}),\n });\n }\n\n for (const provider of this.config.providers ?? []) {\n const providerId = readString(provider.id);\n if (!providerId) continue;\n\n const hint = extractProviderBindingHint(provider);\n if (!hint.senderKey && !hint.plusId) continue;\n\n pushUnique({\n source: \"config\",\n providerId,\n ...(hint.senderKey ? { senderKey: hint.senderKey } : {}),\n ...(hint.plusId ? { plusId: hint.plusId } : {}),\n });\n }\n\n return items;\n }\n\n resolve(input?: KakaoChannelResolveInput): ResolvedKakaoChannelBinding {\n const aliases = this.config.aliases?.kakaoChannels ?? {};\n\n const channelAlias = readString(input?.channelAlias);\n const aliasEntry = channelAlias ? aliases[channelAlias] : undefined;\n\n if (channelAlias && input?.strictAlias === true && !aliasEntry) {\n throw new KMsgError(\n KMsgErrorCode.INVALID_REQUEST,\n `Unknown kakao channel alias: ${channelAlias}`,\n );\n }\n\n const defaultsKakao = this.config.defaults?.kakao;\n const defaultsChannelAlias = readString(defaultsKakao?.channel);\n const defaultAliasEntry = defaultsChannelAlias\n ? aliases[defaultsChannelAlias]\n : undefined;\n\n const explicitProviderId = readString(input?.providerId);\n const aliasProviderId = readString(aliasEntry?.providerId);\n const defaultsProviderId = readString(defaultAliasEntry?.providerId);\n const routingDefaultProviderId = readString(\n this.config.routing?.defaultProviderId,\n );\n const singleProviderId = selectSingleProviderId(this.config.providers);\n\n let providerId: string | undefined;\n let providerIdSource: KakaoChannelBindingSource = \"unknown\";\n\n if (explicitProviderId) {\n providerId = explicitProviderId;\n providerIdSource = \"explicit\";\n } else if (aliasProviderId) {\n providerId = aliasProviderId;\n providerIdSource = \"alias\";\n } else if (defaultsProviderId) {\n providerId = defaultsProviderId;\n providerIdSource = \"defaults\";\n } else if (routingDefaultProviderId) {\n providerId = routingDefaultProviderId;\n providerIdSource = \"routing\";\n } else if (singleProviderId) {\n providerId = singleProviderId;\n providerIdSource = \"single_provider\";\n }\n\n const providerEntry = providerId\n ? (this.config.providers ?? []).find((entry) => entry.id === providerId)\n : undefined;\n const providerHint = providerEntry\n ? extractProviderBindingHint(providerEntry)\n : {};\n\n const explicitSenderKey = readString(input?.senderKey);\n const aliasSenderKey = readString(aliasEntry?.senderKey);\n const defaultsSenderKey = readString(defaultsKakao?.senderKey);\n const defaultAliasSenderKey = readString(defaultAliasEntry?.senderKey);\n const providerHintSenderKey = readString(providerHint.senderKey);\n\n const explicitPlusId = readString(input?.plusId);\n const aliasPlusId = readString(aliasEntry?.plusId);\n const defaultsPlusId = readString(defaultsKakao?.plusId);\n const defaultAliasPlusId = readString(defaultAliasEntry?.plusId);\n const providerHintPlusId = readString(providerHint.plusId);\n\n let senderKey: string | undefined;\n let senderKeySource: KakaoChannelBindingSource | undefined;\n\n if (explicitSenderKey) {\n senderKey = explicitSenderKey;\n senderKeySource = \"explicit\";\n } else if (aliasSenderKey) {\n senderKey = aliasSenderKey;\n senderKeySource = \"alias\";\n } else if (defaultsSenderKey) {\n senderKey = defaultsSenderKey;\n senderKeySource = \"defaults\";\n } else if (defaultAliasSenderKey) {\n senderKey = defaultAliasSenderKey;\n senderKeySource = \"defaults\";\n } else if (providerHintSenderKey) {\n senderKey = providerHintSenderKey;\n senderKeySource = \"provider_config\";\n }\n\n let plusId: string | undefined;\n let plusIdSource: KakaoChannelBindingSource | undefined;\n\n if (explicitPlusId) {\n plusId = explicitPlusId;\n plusIdSource = \"explicit\";\n } else if (aliasPlusId) {\n plusId = aliasPlusId;\n plusIdSource = \"alias\";\n } else if (defaultsPlusId) {\n plusId = defaultsPlusId;\n plusIdSource = \"defaults\";\n } else if (defaultAliasPlusId) {\n plusId = defaultAliasPlusId;\n plusIdSource = \"defaults\";\n } else if (providerHintPlusId) {\n plusId = providerHintPlusId;\n plusIdSource = \"provider_config\";\n }\n\n return {\n ...(channelAlias ? { alias: channelAlias } : {}),\n ...(providerId ? { providerId } : {}),\n ...(normalizeProviderType(providerEntry?.type)\n ? { providerType: normalizeProviderType(providerEntry?.type) }\n : {}),\n ...(senderKey ? { senderKey } : {}),\n ...(plusId ? { plusId } : {}),\n ...(readString(aliasEntry?.name)\n ? { name: readString(aliasEntry?.name) }\n : readString(defaultAliasEntry?.name)\n ? { name: readString(defaultAliasEntry?.name) }\n : {}),\n providerIdSource,\n ...(senderKeySource ? { senderKeySource } : {}),\n ...(plusIdSource ? { plusIdSource } : {}),\n };\n }\n\n getAlias(alias: string): KakaoChannelAliasEntry | undefined {\n const normalized = readString(alias);\n if (!normalized) return undefined;\n return this.config.aliases?.kakaoChannels?.[normalized];\n }\n}\n",
|
|
8
8
|
"import type { ProviderOnboardingSpec } from \"@k-msg/core\";\nimport type {\n KakaoChannelCapability,\n KakaoChannelCapabilityMode,\n KakaoChannelRuntimeProvider,\n} from \"./types\";\n\nfunction hasFunction(value: unknown): value is (...args: unknown[]) => unknown {\n return typeof value === \"function\";\n}\n\nfunction tryGetOnboardingSpec(\n provider: KakaoChannelRuntimeProvider,\n): ProviderOnboardingSpec | undefined {\n if (!hasFunction(provider.getOnboardingSpec)) {\n return undefined;\n }\n\n try {\n return provider.getOnboardingSpec();\n } catch {\n return undefined;\n }\n}\n\nfunction normalizeProviderType(value: string | undefined): string | undefined {\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed.toLowerCase() : undefined;\n}\n\nfunction inferMode(\n spec: ProviderOnboardingSpec | undefined,\n supportsList: boolean,\n): KakaoChannelCapabilityMode {\n if (spec?.channelOnboarding) {\n if (spec.channelOnboarding === \"api\" && !supportsList) {\n return \"none\";\n }\n return spec.channelOnboarding;\n }\n\n return supportsList ? \"api\" : \"none\";\n}\n\nexport class KakaoChannelCapabilityService {\n resolve(provider: KakaoChannelRuntimeProvider): KakaoChannelCapability {\n const spec = tryGetOnboardingSpec(provider);\n\n const supports = {\n list: hasFunction(provider.listKakaoChannels),\n categories: hasFunction(provider.listKakaoChannelCategories),\n auth: hasFunction(provider.requestKakaoChannelAuth),\n add: hasFunction(provider.addKakaoChannel),\n };\n\n const providerType = normalizeProviderType(spec?.providerId);\n const mode = inferMode(spec, supports.list);\n\n return {\n providerId: provider.id,\n ...(providerType ? { providerType } : {}),\n mode,\n supports,\n };\n }\n}\n",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"import type {\n KakaoChannelApiOperation,\n KakaoChannelRuntimeProvider,\n} from \"../types\";\n\nexport class SolapiChannelAdapter {\n readonly mode = \"none\" as const;\n\n constructor(private readonly provider: KakaoChannelRuntimeProvider) {}\n\n unsupportedMessage(operation: KakaoChannelApiOperation): string {\n return `Provider '${this.provider.id}' does not expose Kakao channel onboarding API. Operation '${operation}' is unsupported.`;\n }\n}\n",
|
|
13
13
|
"import {\n fail,\n type KakaoChannel,\n type KakaoChannelCategories,\n KMsgError,\n KMsgErrorCode,\n ok,\n type Result,\n} from \"@k-msg/core\";\nimport { AligoChannelAdapter } from \"./adapters/aligo.adapter\";\nimport { IwinvChannelAdapter } from \"./adapters/iwinv.adapter\";\nimport { MockChannelAdapter } from \"./adapters/mock.adapter\";\nimport { SolapiChannelAdapter } from \"./adapters/solapi.adapter\";\nimport { KakaoChannelCapabilityService } from \"./kakao-channel-capability.service\";\nimport type {\n KakaoChannelAddParams,\n KakaoChannelApiAdapter,\n KakaoChannelApiOperation,\n KakaoChannelAuthParams,\n KakaoChannelCapability,\n KakaoChannelListItem,\n KakaoChannelListParams,\n KakaoChannelRuntimeProvider,\n} from \"./types\";\n\nfunction normalizeProviderType(value: string | undefined): string | undefined {\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed.toLowerCase() : undefined;\n}\n\nfunction createApiAdapter(\n providerType: string | undefined,\n provider: KakaoChannelRuntimeProvider,\n): KakaoChannelApiAdapter | undefined {\n switch (providerType) {\n case \"aligo\":\n return new AligoChannelAdapter(provider);\n case \"mock\":\n return new MockChannelAdapter(provider);\n default:\n return typeof provider.listKakaoChannels === \"function\"\n ? new AligoChannelAdapter(provider)\n : undefined;\n }\n}\n\nexport class KakaoChannelLifecycleService {\n private readonly capability: KakaoChannelCapability;\n private readonly providerType?: string;\n private readonly apiAdapter?: KakaoChannelApiAdapter;\n private readonly iwinvAdapter?: IwinvChannelAdapter;\n private readonly solapiAdapter?: SolapiChannelAdapter;\n\n constructor(\n private readonly provider: KakaoChannelRuntimeProvider,\n capabilityService = new KakaoChannelCapabilityService(),\n ) {\n this.capability = capabilityService.resolve(provider);\n this.providerType = normalizeProviderType(this.capability.providerType);\n\n if (this.capability.mode === \"api\") {\n this.apiAdapter = createApiAdapter(this.providerType, this.provider);\n } else if (this.providerType === \"iwinv\") {\n this.iwinvAdapter = new IwinvChannelAdapter(this.provider);\n } else if (this.providerType === \"solapi\") {\n this.solapiAdapter = new SolapiChannelAdapter(this.provider);\n }\n }\n\n getCapability(): KakaoChannelCapability {\n return this.capability;\n }\n\n private unsupported(\n operation: KakaoChannelApiOperation,\n ): Result<never, KMsgError> {\n const message = (() => {\n if (this.capability.mode === \"manual\") {\n if (this.iwinvAdapter) {\n return this.iwinvAdapter.unsupportedMessage(operation);\n }\n return `Provider '${this.provider.id}' requires manual Kakao channel onboarding. Operation '${operation}' is unavailable via API.`;\n }\n\n if (this.capability.mode === \"none\") {\n if (this.solapiAdapter) {\n return this.solapiAdapter.unsupportedMessage(operation);\n }\n return `Provider '${this.provider.id}' does not support Kakao channel onboarding API operation '${operation}'.`;\n }\n\n return `Provider '${this.provider.id}' does not support Kakao channel onboarding API operation '${operation}'.`;\n })();\n\n return fail(\n new KMsgError(KMsgErrorCode.INVALID_REQUEST, message, {\n providerId: this.provider.id,\n mode: this.capability.mode,\n operation,\n }),\n );\n }\n\n private ensureApi(\n operation: KakaoChannelApiOperation,\n ): Result<void, KMsgError> {\n if (this.capability.mode !== \"api\") {\n return this.unsupported(operation);\n }\n\n if (!this.apiAdapter) {\n return fail(\n new KMsgError(\n KMsgErrorCode.INVALID_REQUEST,\n `Provider '${this.provider.id}' is marked as api mode but does not expose kakao channel operations`,\n {\n providerId: this.provider.id,\n mode: this.capability.mode,\n operation,\n },\n ),\n );\n }\n\n return ok(undefined);\n }\n\n async list(\n params?: KakaoChannelListParams,\n ): Promise<Result<KakaoChannelListItem[], KMsgError>> {\n const ready = this.ensureApi(\"list\");\n if (ready.isFailure) return ready;\n const apiAdapter = this.apiAdapter;\n if (!apiAdapter) return this.unsupported(\"list\");\n\n const result = await apiAdapter.list(params);\n if (result.isFailure) return result;\n\n return ok(\n result.value.map((channel) => ({\n source: \"api\" as const,\n providerId: channel.providerId || this.provider.id,\n senderKey: channel.senderKey,\n ...(channel.plusId ? { plusId: channel.plusId } : {}),\n ...(channel.name ? { name: channel.name } : {}),\n ...(channel.status ? { status: channel.status } : {}),\n })),\n );\n }\n\n async categories(): Promise<Result<KakaoChannelCategories, KMsgError>> {\n const ready = this.ensureApi(\"categories\");\n if (ready.isFailure) return ready;\n const apiAdapter = this.apiAdapter;\n if (!apiAdapter) return this.unsupported(\"categories\");\n\n return apiAdapter.categories();\n }\n\n async auth(params: KakaoChannelAuthParams): Promise<Result<void, KMsgError>> {\n const ready = this.ensureApi(\"auth\");\n if (ready.isFailure) return ready;\n const apiAdapter = this.apiAdapter;\n if (!apiAdapter) return this.unsupported(\"auth\");\n\n return apiAdapter.auth(params);\n }\n\n async add(\n params: KakaoChannelAddParams,\n ): Promise<Result<KakaoChannel, KMsgError>> {\n const ready = this.ensureApi(\"add\");\n if (ready.isFailure) return ready;\n const apiAdapter = this.apiAdapter;\n if (!apiAdapter) return this.unsupported(\"add\");\n\n return apiAdapter.add(params);\n }\n}\n"
|
|
14
14
|
],
|
|
15
|
-
"mappings": "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",
|
|
16
|
-
"debugId": "
|
|
15
|
+
"mappings": "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",
|
|
16
|
+
"debugId": "E03E043FEC76F1D764756E2164756E21",
|
|
17
17
|
"names": []
|
|
18
18
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@k-msg/channel",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.27.0",
|
|
4
4
|
"packageManager": "bun@1.3.8",
|
|
5
5
|
"description": "AlimTalk channel and sender number management",
|
|
6
6
|
"type": "module",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"publish": "bun publish --access public"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@k-msg/core": "0.
|
|
37
|
+
"@k-msg/core": "0.27.0",
|
|
38
38
|
"zod": "^4.0.14"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|