@k-msg/provider 0.27.1 → 0.27.2
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/aligo/aligo.helpers.d.ts +9 -24
- package/dist/aligo/aligo.shared.helpers.d.ts +22 -0
- package/dist/aligo/aligo.template.helpers.d.ts +2 -0
- package/dist/aligo/index.js +3 -3
- package/dist/aligo/index.mjs +3 -3
- package/dist/aligo/provider.d.ts +3 -28
- package/dist/aligo/provider.send.d.ts +38 -0
- package/dist/aligo/provider.template.d.ts +26 -0
- package/dist/aligo/send.d.ts +5 -0
- package/dist/aligo/send.js +5 -0
- package/dist/aligo/send.mjs +5 -0
- package/dist/aligo/template.d.ts +6 -0
- package/dist/aligo/template.js +5 -0
- package/dist/aligo/template.mjs +5 -0
- package/dist/index.js +3 -3
- package/dist/index.mjs +3 -3
- package/dist/iwinv/index.js +2 -2
- package/dist/iwinv/index.mjs +2 -2
- package/dist/iwinv/provider.d.ts +3 -14
- package/dist/iwinv/provider.send.d.ts +24 -0
- package/dist/iwinv/send.d.ts +5 -0
- package/dist/iwinv/send.js +4 -0
- package/dist/iwinv/send.mjs +4 -0
- package/dist/iwinv/template.d.ts +24 -0
- package/dist/iwinv/template.js +4 -0
- package/dist/iwinv/template.mjs +4 -0
- package/package.json +25 -5
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{
|
|
2
|
-
`);return Gt(t,e)}import{fail as Xt,KMsgError as at,KMsgErrorCode as Be,ok as Zt}from"@k-msg/core";async function O(e){let t=new FormData;for(let[n,i]of Object.entries(e.data))if(i!==void 0&&i!==null)t.append(n,String(i));let r=await fetch(`${e.host}${e.endpoint}`,{method:"POST",body:t});if(!r.ok)throw new at(Be.NETWORK_ERROR,`HTTP error! status: ${r.status}`,{providerId:e.providerId});return await r.json()}function U(e){let{providerId:t,response:r,fallbackMessage:n}=e,i=r.code,o=ot(i);if(o===0)return Zt(void 0);let l=typeof r.message==="string"&&r.message.length>0?r.message:n,d=o===509||o===-99?Be.INVALID_REQUEST:Be.PROVIDER_ERROR;return Xt(new at(d,l,{providerId:t,originalCode:i,raw:r}))}async function dt(e,t){try{let r={apikey:e.config.apiKey,userid:e.config.userId,...typeof t?.plusId==="string"&&t.plusId.trim().length>0?{plusid:t.plusId.trim()}:{},...typeof t?.senderKey==="string"&&t.senderKey.trim().length>0?{senderkey:t.senderKey.trim()}:{}},n=await O({host:e.alimtalkHost,endpoint:"/akv10/profile/list/",data:r,providerId:e.providerId}),i=U({providerId:e.providerId,response:n,fallbackMessage:"channel list failed"});if(i.isFailure)return i;let o=n.list,d=(Array.isArray(o)?o:[]).filter(v).map((a)=>({providerId:e.providerId,senderKey:String(a.senderKey??""),plusId:typeof a.uuid==="string"?a.uuid:void 0,name:typeof a.name==="string"?a.name:void 0,status:typeof a.status==="string"?a.status:void 0,createdAt:M(a.cdate),updatedAt:M(a.udate),raw:a})).filter((a)=>a.senderKey.length>0);return Ve(d)}catch(r){return oe(F(r,e.providerId))}}async function lt(e){try{let t=await O({host:e.alimtalkHost,endpoint:"/akv10/category/",data:{apikey:e.config.apiKey,userid:e.config.userId},providerId:e.providerId}),r=U({providerId:e.providerId,response:t,fallbackMessage:"category list failed"});if(r.isFailure)return r;let n=v(t.data)?t.data:{},i=(o)=>{return(Array.isArray(o)?o:[]).filter(v).map((d)=>({code:String(d.code??""),name:String(d.name??""),parentCode:typeof d.parentCode==="string"&&d.parentCode.length>0?d.parentCode:void 0})).filter((d)=>d.code.length>0)};return Ve({first:i(n.firstBusinessType),second:i(n.secondBusinessType),third:i(n.thirdBusinessType)})}catch(t){return oe(F(t,e.providerId))}}async function pt(e,t){try{let r=t.plusId.trim(),n=t.phoneNumber.trim();if(!r||!n)return oe(new Le(Ke.INVALID_REQUEST,"plusId and phoneNumber are required",{providerId:e.providerId}));let i=await O({host:e.alimtalkHost,endpoint:"/akv10/profile/auth/",data:{apikey:e.config.apiKey,userid:e.config.userId,plusid:r,phonenumber:n},providerId:e.providerId}),o=U({providerId:e.providerId,response:i,fallbackMessage:"channel auth failed"});if(o.isFailure)return o;return Ve(void 0)}catch(r){return oe(F(r,e.providerId))}}async function ut(e,t){try{let r=t.plusId.trim(),n=t.authNum.trim(),i=t.phoneNumber.trim(),o=t.categoryCode.trim();if(!r||!n||!i||!o)return oe(new Le(Ke.INVALID_REQUEST,"plusId, authNum, phoneNumber, categoryCode are required",{providerId:e.providerId}));let l=await O({host:e.alimtalkHost,endpoint:"/akv10/profile/add/",data:{apikey:e.config.apiKey,userid:e.config.userId,plusid:r,authnum:n,phonenumber:i,categorycode:o},providerId:e.providerId}),d=U({providerId:e.providerId,response:l,fallbackMessage:"channel add failed"});if(d.isFailure)return d;let a=l.data,s=Array.isArray(a)?a.find(v):v(a)?a:void 0;if(!s)return oe(new Le(Ke.PROVIDER_ERROR,"channel add returned empty data",{providerId:e.providerId,raw:l}));let p=String(s.senderKey??"");if(!p)return oe(new Le(Ke.PROVIDER_ERROR,"channel add did not return senderKey",{providerId:e.providerId,raw:s}));return Ve({providerId:e.providerId,senderKey:p,plusId:typeof s.uuid==="string"?s.uuid:r,name:typeof s.name==="string"?s.name:void 0,status:typeof s.status==="string"?s.status:void 0,createdAt:M(s.cdate),updatedAt:M(s.udate),raw:s})}catch(r){return oe(F(r,e.providerId))}}import{fail as q,KMsgError as se,KMsgErrorCode as ae,ok as Qe}from"@k-msg/core";function er(e,t){if(e.type!=="ALIMTALK")return;if(e.failover?.enabled!==!0)return;return[{code:"FAILOVER_PARTIAL_PROVIDER",message:"Aligo failover mapping is partial. API-level fallback may be attempted for non-Kakao-user failures.",details:{providerId:t,mappedFields:["failover","fmessage_1","fsubject_1"],unsupportedFields:["fallbackChannel"]}}]}async function tr(e,t){let r=t.from||e.config.sender||"";if(!r)return q(new se(ae.INVALID_REQUEST,"from is required for SMS/LMS/MMS (options.from or config.sender)",{providerId:e.providerId}));let n={key:e.config.apiKey,user_id:e.config.userId,sender:r,receiver:t.to,msg:t.text,msg_type:t.type,title:t.subject,testmode_yn:e.config.testMode?"Y":"N"},i=t.options?.scheduledAt;if(i instanceof Date&&!Number.isNaN(i.getTime())){let{date:l,time:d}=Me(i);n.rdate=l,n.rtime=d}if(t.type==="MMS"){let l=We({imageUrl:t.imageUrl,media:t.media,providerId:e.providerId});if(!l)return q(new se(ae.INVALID_REQUEST,"image is required for MMS (options.imageUrl or options.media.image.ref)",{providerId:e.providerId}));n.image=l}let o=await O({host:e.smsHost,endpoint:Oe("sendSMS",e.config),data:n,providerId:e.providerId});if(o.result_code!=="1")return q(Ne(o,e.providerId));return Qe({messageId:t.messageId||crypto.randomUUID(),providerId:e.providerId,providerMessageId:o.msg_id,status:"PENDING",type:t.type,to:t.to,raw:o})}async function rr(e,t){let r=er(t,e.providerId),n=(typeof t.kakao?.profileId==="string"?t.kakao.profileId:e.config.senderKey)||"";if(!n)return q(new se(ae.INVALID_REQUEST,"kakao profileId is required (options.kakao.profileId or config.senderKey)",{providerId:e.providerId}));let i=t.from||e.config.sender||"";if(!i)return q(new se(ae.INVALID_REQUEST,"from is required for ALIMTALK (options.from or config.sender)",{providerId:e.providerId}));let{variables:o,templateId:l}=t;if(!l||l.length===0)return q(new se(ae.INVALID_REQUEST,"templateId is required for ALIMTALK",{providerId:e.providerId}));let d=typeof t.providerOptions?.templateContent==="string"?t.providerOptions.templateContent:void 0,a={apikey:e.config.apiKey,userid:e.config.userId,senderkey:n,tpl_code:l,sender:i,receiver_1:t.to,subject_1:"알림톡",message_1:st(o,d),testMode:e.config.testMode?"Y":"N"},s=typeof t.providerOptions?.failover==="string"?t.providerOptions.failover.trim().toUpperCase():"",p=s==="Y"||s==="N"?s:void 0,m=t.failover?.enabled===!0?"Y":t.failover?.enabled===!1?"N":void 0,u=p??m,g=typeof t.providerOptions?.fsubject_1==="string"&&t.providerOptions.fsubject_1.trim().length>0?t.providerOptions.fsubject_1.trim():typeof t.failover?.fallbackTitle==="string"&&t.failover.fallbackTitle.trim().length>0?t.failover.fallbackTitle.trim():void 0,S=typeof t.providerOptions?.fmessage_1==="string"&&t.providerOptions.fmessage_1.trim().length>0?t.providerOptions.fmessage_1.trim():typeof t.failover?.fallbackContent==="string"&&t.failover.fallbackContent.trim().length>0?t.failover.fallbackContent.trim():void 0;if(u)a.failover=u;if(g)a.fsubject_1=g;if(S)a.fmessage_1=S;let f=t.options?.scheduledAt;if(f instanceof Date&&!Number.isNaN(f.getTime())){let{date:b,time:c}=Me(f);a.reserve="Y",a.reserve_date=b,a.reserve_time=c}let y=await O({host:e.alimtalkHost,endpoint:Oe("sendAlimTalk",e.config),data:a,providerId:e.providerId});if(y.result_code!=="0")return q(Ne(y,e.providerId));return Qe({messageId:t.messageId||crypto.randomUUID(),providerId:e.providerId,providerMessageId:y.msg_id,status:"PENDING",type:t.type,to:t.to,...Array.isArray(r)&&r.length>0?{warnings:r}:{},raw:y})}async function nr(e,t){let r=(typeof t.kakao?.profileId==="string"?t.kakao.profileId:e.config.senderKey)||"";if(!r)return q(new se(ae.INVALID_REQUEST,"kakao profileId is required (options.kakao.profileId or config.senderKey)",{providerId:e.providerId}));let n=t.from||e.config.sender||"";if(!n)return q(new se(ae.INVALID_REQUEST,"from is required for FRIENDTALK (options.from or config.sender)",{providerId:e.providerId}));let i={apikey:e.config.apiKey,userid:e.config.userId,senderkey:r,sender:n,receiver_1:t.to,subject_1:"친구톡",message_1:t.text,testMode:e.config.testMode?"Y":"N"},o=We({imageUrl:t.imageUrl,media:t.media,providerId:e.providerId});if(o)i.image_1=o;let l=Array.isArray(t.kakao?.buttons)?t.kakao.buttons:t.buttons;if(l)i.button_1=JSON.stringify(l);let d=t.options?.scheduledAt;if(d instanceof Date&&!Number.isNaN(d.getTime())){let{date:s,time:p}=Me(d);i.reserve="Y",i.reserve_date=s,i.reserve_time=p}let a=await O({host:e.alimtalkHost,endpoint:Oe("sendFriendTalk",e.config),data:i,providerId:e.providerId});if(a.result_code!=="0")return q(Ne(a,e.providerId));return Qe({messageId:t.messageId||crypto.randomUUID(),providerId:e.providerId,providerMessageId:a.msg_id,status:"PENDING",type:t.type,to:t.to,raw:a})}async function ft(e,t){try{switch(t.type){case"ALIMTALK":return await rr(e,t);case"FRIENDTALK":return await nr(e,t);case"SMS":case"LMS":case"MMS":return await tr(e,t);default:return q(new se(ae.INVALID_REQUEST,`AligoProvider does not support type ${t.type}`,{providerId:e.providerId,type:t.type}))}}catch(r){return q(Ne(r,e.providerId))}}import{fail as L,KMsgError as me,KMsgErrorCode as Ae,ok as ye}from"@k-msg/core";import{validateTemplatePayload as ct}from"@k-msg/template";function gt(e,t){return new me(e.code,e.message,{providerId:t,...e.details??{}})}async function mt(e,t,r){try{let n=ge(e,r),i=ct(t,{requireName:!0,requireContent:!0});if(i.isFailure)return L(gt(i.error,e.providerId));let o={apikey:e.config.apiKey,userid:e.config.userId,senderkey:n,tpl_name:i.value.name??t.name,tpl_content:i.value.content??t.content},l=xe(i.value.buttons);if(l)o.tpl_button=l;let d=await O({host:e.alimtalkHost,endpoint:"/akv10/template/add/",data:o,providerId:e.providerId}),a=U({providerId:e.providerId,response:d,fallbackMessage:"template create failed"});if(a.isFailure)return a;let s=v(d.data)?d.data:{},p=String(s.templtCode??"");if(!p)return L(new me(Ae.PROVIDER_ERROR,"template create did not return templtCode",{providerId:e.providerId,raw:d}));let m=M(s.cdate)??new Date,u=M(s.udate)??M(s.cdate)??m;return ye({id:p,code:p,name:String(s.templtName??i.value.name??t.name),content:String(s.templtContent??i.value.content??t.content),category:t.category,status:Pe(s),buttons:Array.isArray(s.buttons)?s.buttons:i.value.buttons,variables:t.variables,createdAt:m,updatedAt:u})}catch(n){return L(F(n,e.providerId))}}async function Fe(e,t,r){try{let n=ge(e,r),i=t.trim();if(!i)return L(new me(Ae.INVALID_REQUEST,"code is required",{providerId:e.providerId}));let o=await O({host:e.alimtalkHost,endpoint:"/akv10/template/list/",data:{apikey:e.config.apiKey,userid:e.config.userId,senderkey:n,tpl_code:i},providerId:e.providerId}),l=U({providerId:e.providerId,response:o,fallbackMessage:"template get failed"});if(l.isFailure)return l;let d=o.list,s=(Array.isArray(d)?d:[]).find(v);if(!s)return L(new me(Ae.TEMPLATE_NOT_FOUND,"Template not found",{providerId:e.providerId,templateCode:i}));let p=String(s.templtCode??i),m=M(s.cdate)??new Date,u=M(s.udate)??M(s.cdate)??m;return ye({id:p,code:p,name:String(s.templtName??""),content:String(s.templtContent??""),status:Pe(s),buttons:Array.isArray(s.buttons)?s.buttons:void 0,createdAt:m,updatedAt:u})}catch(n){return L(F(n,e.providerId))}}async function yt(e,t,r,n){try{let i=ge(e,n),o=t.trim();if(!o)return L(new me(Ae.INVALID_REQUEST,"code is required",{providerId:e.providerId}));let l=await Fe(e,o,{kakaoChannelSenderKey:i});if(l.isFailure)return l;let d=l.value,a=typeof r.name==="string"&&r.name.trim().length>0?r.name.trim():d.name,s=typeof r.content==="string"&&r.content.trim().length>0?r.content:d.content,p=ct({name:a,content:s,buttons:r.buttons!==void 0?r.buttons:d.buttons},{requireName:!0,requireContent:!0});if(p.isFailure)return L(gt(p.error,e.providerId));let m={apikey:e.config.apiKey,userid:e.config.userId,senderkey:i,tpl_code:o,tpl_name:p.value.name??a,tpl_content:p.value.content??s},u=xe(p.value.buttons);if(u)m.tpl_button=u;let g=await O({host:e.alimtalkHost,endpoint:"/akv10/template/modify/",data:m,providerId:e.providerId}),S=U({providerId:e.providerId,response:g,fallbackMessage:"template update failed"});if(S.isFailure)return S;let f=await Fe(e,o,{kakaoChannelSenderKey:i});if(f.isSuccess)return f;return ye({...d,name:p.value.name??a,content:p.value.content??s,...r.category!==void 0?{category:r.category}:{},...r.variables!==void 0?{variables:r.variables}:{},...r.buttons!==void 0?{buttons:p.value.buttons}:{},updatedAt:new Date})}catch(i){return L(F(i,e.providerId))}}async function It(e,t,r){try{let n=ge(e,r),i=t.trim();if(!i)return L(new me(Ae.INVALID_REQUEST,"code is required",{providerId:e.providerId}));let o=await O({host:e.alimtalkHost,endpoint:"/akv10/template/del/",data:{apikey:e.config.apiKey,userid:e.config.userId,senderkey:n,tpl_code:i},providerId:e.providerId}),l=U({providerId:e.providerId,response:o,fallbackMessage:"template delete failed"});if(l.isFailure)return l;return ye(void 0)}catch(n){return L(F(n,e.providerId))}}async function St(e,t,r){try{let n=ge(e,r),i=await O({host:e.alimtalkHost,endpoint:"/akv10/template/list/",data:{apikey:e.config.apiKey,userid:e.config.userId,senderkey:n},providerId:e.providerId}),o=U({providerId:e.providerId,response:i,fallbackMessage:"template list failed"});if(o.isFailure)return o;let l=i.list,a=(Array.isArray(l)?l:[]).filter(v).map((s)=>{let p=String(s.templtCode??""),m=M(s.cdate)??new Date,u=M(s.udate)??M(s.cdate)??m;return{id:p,code:p,name:String(s.templtName??""),content:String(s.templtContent??""),status:Pe(s),buttons:Array.isArray(s.buttons)?s.buttons:void 0,createdAt:m,updatedAt:u}}).filter((s)=>s.code.length>0);if(t?.status){let s=t.status.trim().toUpperCase();return ye(a.filter((p)=>p.status===s))}return ye(a)}catch(n){return L(F(n,e.providerId))}}async function vt(e,t,r){try{let n=ge(e,r),i=t.trim();if(!i)return L(new me(Ae.INVALID_REQUEST,"code is required",{providerId:e.providerId}));let o=await O({host:e.alimtalkHost,endpoint:"/akv10/template/request/",data:{apikey:e.config.apiKey,userid:e.config.userId,senderkey:n,tpl_code:i},providerId:e.providerId}),l=U({providerId:e.providerId,response:o,fallbackMessage:"template inspection request failed"});if(l.isFailure)return l;return ye(void 0)}catch(n){return L(F(n,e.providerId))}}class Te{config;id="aligo";name="Aligo Smart SMS";supportedTypes=["ALIMTALK","FRIENDTALK","SMS","LMS","MMS"];smsHost;alimtalkHost;getOnboardingSpec(){let e=fe(this.id);if(!e)throw Error(`Onboarding spec missing for provider: ${this.id}`);return e}constructor(e){this.config=e;if(!e||typeof e!=="object")throw Error("AligoProvider requires a config object");if(!e.apiKey||e.apiKey.length===0)throw Error("AligoProvider requires `apiKey`");if(!e.userId||e.userId.length===0)throw Error("AligoProvider requires `userId`");this.smsHost=e.smsBaseUrl||"https://apis.aligo.in",this.alimtalkHost=e.alimtalkBaseUrl||"https://kakaoapi.aligo.in"}getRuntimeContext(){return{providerId:this.id,config:this.config,smsHost:this.smsHost,alimtalkHost:this.alimtalkHost}}async healthCheck(){let e=Date.now(),t=[];try{if(!this.config.apiKey)t.push("Missing apiKey");if(!this.config.userId)t.push("Missing userId");if(!this.config.sender)t.push("Missing sender (default from)");try{new URL(this.smsHost)}catch{t.push("Invalid smsBaseUrl")}try{new URL(this.alimtalkHost)}catch{t.push("Invalid alimtalkBaseUrl")}return{healthy:t.length===0,issues:t,latencyMs:Date.now()-e,data:{provider:this.id,smsBaseUrl:this.smsHost,alimtalkBaseUrl:this.alimtalkHost}}}catch(r){return t.push(r instanceof Error?r.message:String(r)),{healthy:!1,issues:t,latencyMs:Date.now()-e}}}async send(e){let t=e.messageId||crypto.randomUUID(),r={...e,messageId:t};return ft(this.getRuntimeContext(),r)}async listKakaoChannels(e){return dt(this.getRuntimeContext(),e)}async listKakaoChannelCategories(){return lt(this.getRuntimeContext())}async requestKakaoChannelAuth(e){return pt(this.getRuntimeContext(),e)}async addKakaoChannel(e){return ut(this.getRuntimeContext(),e)}async createTemplate(e,t){return mt(this.getRuntimeContext(),e,t)}async updateTemplate(e,t,r){return yt(this.getRuntimeContext(),e,t,r)}async deleteTemplate(e,t){return It(this.getRuntimeContext(),e,t)}async getTemplate(e,t){return Fe(this.getRuntimeContext(),e,t)}async listTemplates(e,t){return St(this.getRuntimeContext(),e,t)}async requestTemplateInspection(e,t){return vt(this.getRuntimeContext(),e,t)}}var ir=(e)=>new Te(e),bt=()=>{let e={apiKey:Ie("ALIGO_API_KEY")||"",userId:Ie("ALIGO_USER_ID")||"",senderKey:Ie("ALIGO_SENDER_KEY")||"",sender:Ie("ALIGO_SENDER")||"",friendtalkEndpoint:Ie("ALIGO_FRIENDTALK_ENDPOINT"),testMode:Ie("NODE_ENV")!=="production",debug:Ie("NODE_ENV")==="development"};if(!e.apiKey||!e.userId)throw Error("ALIGO_API_KEY and ALIGO_USER_ID are required");return new Te(e)};class At{static create(e){return new Te(e)}static createDefault(){return bt()}}function or(){}var sr={mock:{},aligo:{apiKey:{type:"string",required:!0,description:"Aligo API key",defaultValue:"env:ALIGO_API_KEY"},userId:{type:"string",required:!0,description:"Aligo user id",defaultValue:"env:ALIGO_USER_ID"},senderKey:{type:"string",description:"Default Kakao sender key",defaultValue:"env:ALIGO_SENDER_KEY"},sender:{type:"string",description:"Default SMS/LMS sender number",defaultValue:"env:ALIGO_SENDER"},testMode:{type:"boolean",description:"Enable Aligo test mode"},debug:{type:"boolean",description:"Enable debug logging"},smsBaseUrl:{type:"string",description:"Override SMS API base URL"},alimtalkBaseUrl:{type:"string",description:"Override AlimTalk API base URL"},friendtalkEndpoint:{type:"string",description:"Override FriendTalk endpoint path"}},iwinv:{apiKey:{type:"string",required:!0,description:"IWINV AlimTalk API key (AUTH header)",defaultValue:"env:IWINV_API_KEY"},smsApiKey:{type:"string",description:"IWINV SMS API key",defaultValue:"env:IWINV_SMS_API_KEY"},smsAuthKey:{type:"string",description:"IWINV SMS auth key",defaultValue:"env:IWINV_SMS_AUTH_KEY"},smsCompanyId:{type:"string",description:"IWINV SMS company id",defaultValue:"env:IWINV_SMS_COMPANY_ID"},senderNumber:{type:"string",description:"Default sender number",defaultValue:"env:IWINV_SENDER_NUMBER"},smsSenderNumber:{type:"string",description:"SMS/LMS sender number override"},sendEndpoint:{type:"string",description:"Override IWINV send endpoint path"},xForwardedFor:{type:"string",description:"X-Forwarded-For header override"},extraHeaders:{type:"stringRecord",description:"Additional HTTP headers"},ipRetryCount:{type:"number",description:"IP-restriction retry count"},ipRetryDelayMs:{type:"number",description:"IP-restriction retry delay in ms"},ipAlertWebhookUrl:{type:"string",description:"Webhook URL for IP restriction alerts"},debug:{type:"boolean",description:"Enable debug logging"}},solapi:{apiKey:{type:"string",required:!0,description:"SOLAPI API key",defaultValue:"env:SOLAPI_API_KEY"},apiSecret:{type:"string",required:!0,description:"SOLAPI API secret",defaultValue:"env:SOLAPI_API_SECRET"},defaultFrom:{type:"string",description:"Default sender number",defaultValue:"env:SOLAPI_DEFAULT_FROM"},kakaoPfId:{type:"string",description:"Default Kakao PF ID",defaultValue:"env:SOLAPI_KAKAO_PF_ID"},rcsBrandId:{type:"string",description:"Default RCS brand id"},naverTalkId:{type:"string",description:"Default Naver Talk id"},appId:{type:"string",description:"SOLAPI app id"},defaultCountry:{type:"string",description:"Default country code"},baseUrl:{type:"string",description:"Override SOLAPI API base URL"},debug:{type:"boolean",description:"Enable debug logging"}}};import{fail as X,KMsgError as K,KMsgErrorCode as V,ok as Bt,readRuntimeEnv as Z}from"@k-msg/core";function H(e){if(!e)return{};try{return JSON.parse(e)}catch{return e}}function de(e,t){return v(e)?e:t}import{KMsgErrorCode as le}from"@k-msg/core";function ar(e){let t="",r=0;while(r<e.length){let n=e[r++]??0,i=e[r++]??0,o=e[r++]??0,l=n<<16|i<<8|o;t+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[l>>18&63],t+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[l>>12&63],t+=r-2<e.length?"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[l>>6&63]:"=",t+=r-1<e.length?"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[l&63]:"="}return t}function Ee(e){return ar(new TextEncoder().encode(e))}function Rt(e){let t=e.sendEndpoint||"/api/v2/send/";return t.startsWith("/")?t:`/${t}`}function W(e){let r={AUTH:Ee(e.apiKey),"Content-Type":"application/json;charset=UTF-8"};if(typeof e.xForwardedFor==="string"&&e.xForwardedFor.length>0)r["X-Forwarded-For"]=e.xForwardedFor;if(e.extraHeaders&&typeof e.extraHeaders==="object")return{...r,...e.extraHeaders};return r}function x(e){switch(e){case 201:case 206:case 401:case 403:return le.AUTHENTICATION_FAILED;case 429:return le.RATE_LIMIT_EXCEEDED;case 519:return le.INSUFFICIENT_BALANCE;case 404:case 501:return le.TEMPLATE_NOT_FOUND;case 502:case 503:case 504:case 505:case 506:case 507:case 508:case 509:case 510:case 511:case 512:case 513:case 514:case 515:case 516:case 517:case 540:return le.INVALID_REQUEST;case 518:return le.PROVIDER_ERROR;default:if(e>=500)return le.PROVIDER_ERROR;return le.INVALID_REQUEST}}function Q(e){if(typeof e==="number"&&Number.isFinite(e))return e;if(typeof e==="string"){let t=e.trim();if(t.length===0)return;let r=Number(t);if(Number.isFinite(r))return r}return}function Nt(e){if(typeof e!=="string")return;let t=e.trim().toUpperCase();if(!t)return;switch(t){case"Y":case"APPROVED":return"Y";case"I":case"INSPECTION":return"I";case"R":case"REJECTED":return"R";case"PENDING":return"I";default:return}}function ze(e){switch(typeof e==="string"?e.trim().toUpperCase():""){case"Y":return"APPROVED";case"I":return"INSPECTION";case"R":return"REJECTED";default:return"PENDING"}}var Tt="https://alimtalk.bizservice.iwinv.kr",Et="https://sms.bizservice.iwinv.kr";import{fail as z,KMsgError as $,KMsgErrorCode as G,ok as Re}from"@k-msg/core";import{KMsgErrorCode as we}from"@k-msg/core";function ee(e){return e.replace(/[^0-9]/g,"")}function te(){return Et}function pe(e){if(e.smsApiKey&&e.smsAuthKey)return Ee(`${e.smsApiKey}&${e.smsAuthKey}`);let t=e.smsAuthKey||e.smsApiKey;if(!t)return"";return Ee(`${e.apiKey}&${t}`)}function Se(e){return pe(e).length>0}function $e(e){if(typeof e==="number"&&Number.isFinite(e))return e.toString();if(typeof e==="string")return e.trim();return""}function je(e,t){return{"0":"전송 성공","1":"메시지가 전송되지 않았습니다.","11":"운영 중인 서비스가 아닙니다.","12":"요금제 충전 중입니다. 잠시 후 다시 시도해 보시기 바랍니다.","13":"등록되지 않은 발신번호입니다.","14":"인증 요청이 올바르지 않습니다.","15":"등록하지 않은 IP에서는 발송되지 않습니다.","21":"장문 메시지는 2000 Bytes까지만 입력이 가능합니다.","22":"제목 입력 가능 문자가 올바르지 않습니다.","23":"제목은 40 Byte까지만 입력이 가능합니다.","31":"파일 업로드는 100KB까지 가능합니다.","32":"허용되지 않는 파일 확장자입니다.","33":"이미지 업로드에 실패했습니다.","41":"수신 번호를 입력하여 주세요.","42":"예약 전송 가능 시간이 아닙니다.","43":"날짜와 시간 표현 형식에 맞춰 입력하여 주십시오.","44":"최대 1000건 전송 가능합니다.","50":"SMS 자동 충전 한도를 초과하였습니다.","202":"SMS API 인증 실패 또는 SMS 서비스 권한이 없습니다.","206":"등록하지 않은 IP에서는 발송되지 않습니다."}[e]||t}function Ye(e,t){if(e==="14"||e==="15"||e==="202"||e==="206")return we.AUTHENTICATION_FAILED;if(e==="50")return we.INSUFFICIENT_BALANCE;if(e==="13"||e==="21"||e==="22"||e==="23"||e==="31"||e==="32"||e==="33"||e==="41"||e==="42"||e==="43"||e==="44")return we.INVALID_REQUEST;if(!t)return we.NETWORK_ERROR;return we.PROVIDER_ERROR}function Je(e,t){if(t&&t.trim().length>0)return t.trim();return e.slice(0,20)}function wt(e,t){if(e==="06")return"DELIVERED";if(e==="1000")return"DELIVERED";if(typeof t==="string"){if(t.includes("전송 성공"))return"DELIVERED";if(t.includes("대기")||t.includes("처리중"))return"PENDING"}if(e==="00"||e==="01")return"PENDING";if(!e&&!t)return"UNKNOWN";return"FAILED"}function Ge(e,t){return new Date(e.getTime()+t*24*60*60*1000)}function Xe(e){let t=(r)=>r.toString().padStart(2,"0");return`${e.getFullYear()}-${t(e.getMonth()+1)}-${t(e.getDate())}`}function ve(e){if(typeof e!=="string")return;let t=e.trim();if(!t)return;let r=/^(\d{4})-(\d{2})-(\d{2})\s+(\d{2}):(\d{2}):(\d{2})$/.exec(t);if(!r)return;let n=Number(r[1]),i=Number(r[2]),o=Number(r[3]),l=Number(r[4]),d=Number(r[5]),a=Number(r[6]);if(!Number.isFinite(n)||!Number.isFinite(i)||!Number.isFinite(o)||!Number.isFinite(l)||!Number.isFinite(d)||!Number.isFinite(a))return;let s=new Date(n,i-1,o,l,d,a);if(Number.isNaN(s.getTime()))return;return s}function ke(e){let t=(r)=>r.toString().padStart(2,"0");return`${e.getFullYear()}-${t(e.getMonth()+1)}-${t(e.getDate())} ${t(e.getHours())}:${t(e.getMinutes())}:${t(e.getSeconds())}`}function Ze(e){let t=(r)=>r.toString().padStart(2,"0");return`${e.getFullYear()}-${t(e.getMonth()+1)}-${t(e.getDate())} ${t(e.getHours())}:${t(e.getMinutes())}:${t(e.getSeconds())}`}async function kt(e){let{providerId:t,config:r,query:n}=e,i=n.providerMessageId.trim();if(!i)return z(new $(G.INVALID_REQUEST,"providerMessageId is required",{providerId:t}));let o=ee(n.to);if(!o)return z(new $(G.INVALID_REQUEST,"to is required",{providerId:t}));let l=Number(i),d=Number.isFinite(l)?l:void 0,a=ke(Ge(n.requestedAt,-1)),s=ke(new Date),p={pageNum:1,pageSize:15,phone:o,startDate:a,endDate:s,...d!==void 0?{seqNo:d}:{},...n.scheduledAt instanceof Date&&!Number.isNaN(n.scheduledAt.getTime())?{reserve:"Y"}:{}},m=`${r.baseUrl}/api/history/`;try{let u=await fetch(m,{method:"POST",headers:W(r),body:JSON.stringify(p)}),g=await u.text(),S=H(g),f=de(S,{}),y=f.code,b=typeof y==="number"?y:void 0,c=typeof f.message==="string"&&f.message.length>0?f.message:"IWINV history query failed";if(!u.ok||b!==200)return z(new $(x(b??Q(S)??u.status),c,{providerId:t,originalCode:y??u.status}));let A=f.list,T=Array.isArray(A)?A:[];if(T.length===0)return Re(null);let I=(()=>{if(d===void 0)return T[0];return T.find((R)=>v(R)&&R.seqNo===d)??T[0]})();if(!v(I))return Re(null);let _=typeof I.statusCode==="string"?I.statusCode:void 0,D=typeof I.statusCodeName==="string"?I.statusCodeName:void 0,E=ve(I.sendDate),ie=ve(I.receiveDate),J=_==="OK"||typeof D==="string"&&D.includes("성공");return Re({providerId:t,providerMessageId:i,status:J?"DELIVERED":E?"FAILED":"PENDING",statusCode:_,statusMessage:D,sentAt:E,deliveredAt:J?ie||E:void 0,failedAt:!J&&E?E:void 0,raw:I})}catch(u){return z(new $(G.NETWORK_ERROR,u instanceof Error?u.message:String(u),{providerId:t}))}}async function ht(e){let{providerId:t,config:r,query:n}=e;if(!Se(r))return z(new $(G.INVALID_REQUEST,"SMS v2 configuration missing (smsApiKey/smsAuthKey)",{providerId:t}));if(!r.smsCompanyId||r.smsCompanyId.length===0)return z(new $(G.INVALID_REQUEST,"smsCompanyId required for history (config.smsCompanyId)",{providerId:t}));let i=n.providerMessageId.trim();if(!i)return z(new $(G.INVALID_REQUEST,"providerMessageId is required",{providerId:t}));let o=ee(n.to);if(!o)return z(new $(G.INVALID_REQUEST,"to is required",{providerId:t}));let l=Ge(n.requestedAt,-1),d=new Date;if(d.getTime()-l.getTime()>7776000000)return z(new $(G.INVALID_REQUEST,"SMS history date range must be within 90 days",{providerId:t}));let p={version:"1.0",companyid:r.smsCompanyId,startDate:Xe(l),endDate:Xe(d),requestNo:i,pageNum:1,pageSize:15,phone:o},u={"Content-Type":"application/json;charset=UTF-8",secret:pe(r)};if(typeof r.xForwardedFor==="string"&&r.xForwardedFor.length>0)u["X-Forwarded-For"]=r.xForwardedFor;let g=r.extraHeaders&&typeof r.extraHeaders==="object"?{...u,...r.extraHeaders}:u,S=`${te()}/api/history/`;try{let f=await fetch(S,{method:"POST",headers:g,body:JSON.stringify(p)}),y=await f.text(),b=H(y),c=de(b,{}),A=c.resultCode,T=typeof A==="number"?A:typeof A==="string"?Number(A):NaN,I=typeof c.message==="string"&&c.message.length>0?c.message:"IWINV SMS history query failed";if(!f.ok||T!==0)return z(new $(G.PROVIDER_ERROR,I,{providerId:t,originalCode:A??f.status}));let _=c.list,D=Array.isArray(_)?_:[];if(D.length===0)return Re(null);let E=(()=>{return D.find((ue)=>{if(!v(ue))return!1;let B=ue.requestNo;return B!==void 0&&B!==null?String(B)===i:!1})??D[0]})();if(!v(E))return Re(null);let ie=typeof E.sendStatusCode==="string"?E.sendStatusCode:void 0,J=typeof E.sendStatusMsg==="string"?E.sendStatusMsg:typeof E.sendStatus==="string"?E.sendStatus:void 0,be=ve(E.sendDate),R=wt(ie,J);return Re({providerId:t,providerMessageId:i,status:R,statusCode:ie,statusMessage:J,sentAt:be,deliveredAt:R==="DELIVERED"?be:void 0,failedAt:R==="FAILED"?be:void 0,raw:E})}catch(f){return z(new $(G.NETWORK_ERROR,f instanceof Error?f.message:String(f),{providerId:t}))}}import{fail as k,KMsgError as w,KMsgErrorCode as P,ok as rt}from"@k-msg/core";import{fail as Ct,KMsgError as _t,KMsgErrorCode as Dt,ok as et}from"@k-msg/core";function Ot(e){let t=e.split(/[?#]/,1)[0]??e,r=t.lastIndexOf(".");if(r<=0||r===t.length-1)return"";return t.slice(r).toLowerCase()}function tt(e){switch(Ot(e)){case".jpg":case".jpeg":return"image/jpeg";case".png":return"image/png";case".gif":return"image/gif";case".webp":return"image/webp";default:return}}function Mt(e,t){let r=e&&typeof e==="object"?e:{},i=(r.media&&typeof r.media==="object"?r.media:void 0)?.image;if(i&&typeof i==="object"){if(i.bytes instanceof Uint8Array)return et({bytes:i.bytes,filename:typeof i.filename==="string"?i.filename:void 0,contentType:typeof i.contentType==="string"?i.contentType:void 0});if(i.blob instanceof Blob)return et({blob:i.blob,filename:typeof i.filename==="string"?i.filename:void 0,contentType:typeof i.contentType==="string"?i.contentType:void 0});if(typeof i.ref==="string"&&i.ref.trim().length>0)return Ct(new _t(Dt.INVALID_REQUEST,"IWINV MMS caller must provide blob/bytes in options.media.image",{providerId:t,field:"media.image.ref"}))}let o=r.imageUrl;if(typeof o==="string"&&o.trim().length>0)return Ct(new _t(Dt.INVALID_REQUEST,"IWINV MMS caller must provide blob/bytes in options.media.image",{providerId:t,field:"imageUrl"}));return et(void 0)}async function Pt(e){if("blob"in e){let o=e.contentType||e.blob.type||"application/octet-stream",l=e.filename||"image",d=e.contentType&&e.contentType!==e.blob.type?new Blob([await e.blob.arrayBuffer()],{type:o}):e.blob;return{blob:d,filename:l,contentType:o,size:d.size}}let t=e.contentType||"application/octet-stream",r=new Uint8Array(e.bytes.byteLength);r.set(e.bytes);let n=new Blob([r],{type:t}),i=e.filename||"image";return{blob:n,filename:i,contentType:t,size:n.size}}function Lt(e){if(Ot(e.filename).length>0)return e.filename;let r=tt(e.filename)==="image/png"?".png":tt(e.filename)==="image/gif"?".gif":tt(e.filename)==="image/webp"?".webp":e.contentType==="image/png"?".png":e.contentType==="image/gif"?".gif":e.contentType==="image/webp"?".webp":".jpg";return`${e.filename}${r}`}async function Kt(e){let{providerId:t,config:r,options:n}=e,i=n.templateId;if(!i||i.length===0)return k(new w(P.INVALID_REQUEST,"templateId is required for ALIMTALK",{providerId:t}));let o=n.options?.scheduledAt,l=o instanceof Date&&!Number.isNaN(o.getTime()),d=l?"Y":"N",a=l?ke(o):void 0,s=ee(n.to);if(!s)return k(new w(P.INVALID_REQUEST,"to is required",{providerId:t}));let p=n.providerOptions?.templateParam,m=Array.isArray(p)?p.map((R)=>R===null||R===void 0?"":String(R)):Object.values(n.variables||{}).map((R)=>R===null||R===void 0?"":String(R)),u=n.failover,g=(typeof n.from==="string"&&n.from.length>0?n.from:r.senderNumber||r.smsSenderNumber)||"",S=g?ee(g):"",f=typeof n.providerOptions?.reSend==="string"?n.providerOptions.reSend.trim().toUpperCase():"",y=f==="Y"||f==="N"?f:void 0,b=u?.enabled===!0?"Y":u?.enabled===!1?"N":void 0,c=y??b??(S?"Y":"N"),T=(typeof n.providerOptions?.resendCallback==="string"?ee(n.providerOptions.resendCallback):"")||S;if(c==="Y"&&!T)return k(new w(P.INVALID_REQUEST,"resendCallback is required when reSend is 'Y' (options.from or providerOptions.resendCallback)",{providerId:t}));let I=typeof n.providerOptions?.resendType==="string"?n.providerOptions.resendType.trim().toUpperCase():"",_=I==="Y"||I==="N"?I:void 0;if(typeof n.providerOptions?.resendType==="string"&&n.providerOptions.resendType.length>0&&!_)return k(new w(P.INVALID_REQUEST,"resendType must be 'Y' or 'N'",{providerId:t}));let D=u?.fallbackChannel==="lms"?"Y":u?.fallbackChannel==="sms"?"N":void 0,E=typeof n.providerOptions?.resendTitle==="string"&&n.providerOptions.resendTitle.trim().length>0?n.providerOptions.resendTitle.trim():typeof u?.fallbackTitle==="string"&&u.fallbackTitle.trim().length>0?u.fallbackTitle.trim():void 0,ie=typeof n.providerOptions?.resendContent==="string"&&n.providerOptions.resendContent.trim().length>0?n.providerOptions.resendContent.trim():typeof u?.fallbackContent==="string"&&u.fallbackContent.trim().length>0?u.fallbackContent.trim():void 0,J={templateCode:i,reserve:d,...a?{sendDate:a}:{},list:[{phone:s,templateParam:m.length>0?m:void 0}],reSend:c,...T?{resendCallback:T}:{},..._??D?{resendType:_??D}:{},...E?{resendTitle:E}:{},...ie?{resendContent:ie}:{}},be=`${r.baseUrl}${Rt(r)}`;try{let R=await fetch(be,{method:"POST",headers:W(r),body:JSON.stringify(J)}),qe=await R.text(),ue=H(qe),B=v(ue)?ue:{code:Q(ue)??R.status,message:qe||String(ue||"")};if(!R.ok||B.code!==200)return k(new w(x(B.code),B.message||"IWINV send failed",{providerId:t,originalCode:B.code}));return rt({messageId:n.messageId||crypto.randomUUID(),providerId:t,providerMessageId:typeof B.seqNo==="number"?String(B.seqNo):void 0,status:l?"PENDING":"SENT",type:n.type,to:n.to,raw:B})}catch(R){return k(new w(P.NETWORK_ERROR,R instanceof Error?R.message:String(R),{providerId:t}))}}async function dr(e){let{providerId:t,config:r,options:n,to:i,from:o,text:l,scheduledAtValid:d,scheduledAt:a}=e;if(n.type!=="MMS")return k(new w(P.INVALID_REQUEST,"IWINVProvider: MMS handler called with non-MMS options",{providerId:t,type:n.type}));let s=Je(l,n.subject),p=Mt(n,t);if(p.isFailure)return p;let m=p.value;if(!m)return k(new w(P.INVALID_REQUEST,"image is required for MMS; caller must provide options.media.image.blob or bytes",{providerId:t}));let u;try{u=await Pt(m)}catch(c){return k(c instanceof w?c:new w(P.NETWORK_ERROR,c instanceof Error?c.message:String(c),{providerId:t}))}if(u.size>102400)return k(new w(P.INVALID_REQUEST,"MMS image must be <= 100KB",{providerId:t,bytes:u.size}));let g=new FormData;if(g.append("version","1.0"),g.append("from",o),g.append("to",i),g.append("title",s),g.append("text",l),d&&a)g.append("date",Ze(a));g.append("image",u.blob,Lt(u));let f={secret:pe(r)};if(typeof r.xForwardedFor==="string"&&r.xForwardedFor.length>0)f["X-Forwarded-For"]=r.xForwardedFor;let y={...f};if(r.extraHeaders&&typeof r.extraHeaders==="object")for(let[c,A]of Object.entries(r.extraHeaders)){if(c.toLowerCase()==="content-type")continue;y[c]=A}let b=`${te()}/api/v2/send/`;try{let c=await fetch(b,{method:"POST",headers:y,body:g}),A=await c.text(),T=H(A),I=v(T)?T:{resultCode:T},_=I.resultCode??I.code,D=$e(_),E=typeof I.message==="string"&&I.message.length>0?I.message:je(D,"MMS send failed");if(!(c.ok&&D==="0"))return k(new w(Ye(D,c.ok),E,{providerId:t,originalCode:_}));let J=typeof I.requestNo==="string"&&I.requestNo.length>0?I.requestNo:typeof I.msgid==="string"&&I.msgid.length>0?I.msgid:void 0;return rt({messageId:n.messageId||crypto.randomUUID(),providerId:t,providerMessageId:J,status:d?"PENDING":"SENT",type:n.type,to:n.to,raw:I})}catch(c){return k(new w(P.NETWORK_ERROR,c instanceof Error?c.message:String(c),{providerId:t}))}}async function Vt(e){let{providerId:t,config:r,options:n}=e;if(!Se(r))return k(new w(P.INVALID_REQUEST,"SMS v2 configuration missing (smsApiKey/smsAuthKey)",{providerId:t}));let i=ee(n.to);if(!i)return k(new w(P.INVALID_REQUEST,"to is required",{providerId:t}));let o=n.text;if(!o||o.trim().length===0)return k(new w(P.INVALID_REQUEST,"text is required for SMS/LMS/MMS",{providerId:t}));let l=(typeof n.from==="string"&&n.from.length>0?n.from:r.smsSenderNumber||r.senderNumber)||"",d=l?ee(l):"";if(!d)return k(new w(P.INVALID_REQUEST,"from is required for SMS/LMS/MMS (options.from or config.smsSenderNumber)",{providerId:t}));let a=n.options?.scheduledAt,s=a instanceof Date&&!Number.isNaN(a.getTime());if(n.type==="MMS")return await dr({providerId:t,config:r,options:n,to:i,from:d,text:o,scheduledAtValid:s,scheduledAt:s?a:void 0});let p={version:"1.0",from:d,to:[i],text:o};if(n.type==="LMS")p.title=Je(o,n.subject);else{let f=typeof n.providerOptions?.msgType==="string"&&n.providerOptions.msgType.trim().length>0?n.providerOptions.msgType.trim():void 0;p.msgType=f||n.type}if(s)p.date=Ze(a);let u={"Content-Type":"application/json;charset=UTF-8",secret:pe(r)};if(typeof r.xForwardedFor==="string"&&r.xForwardedFor.length>0)u["X-Forwarded-For"]=r.xForwardedFor;let g=r.extraHeaders&&typeof r.extraHeaders==="object"?{...u,...r.extraHeaders}:u,S=`${te()}/api/v2/send/`;try{let f=await fetch(S,{method:"POST",headers:g,body:JSON.stringify(p)}),y=await f.text(),b=H(y),c=v(b)?b:{resultCode:b},A=c.resultCode??c.code,T=$e(A),I=typeof c.message==="string"&&c.message.length>0?c.message:je(T,"SMS send failed");if(!(f.ok&&T==="0"))return k(new w(Ye(T,f.ok),I,{providerId:t,originalCode:A}));let D=typeof c.requestNo==="string"&&c.requestNo.length>0?c.requestNo:typeof c.msgid==="string"&&c.msgid.length>0?c.msgid:void 0;return rt({messageId:n.messageId||crypto.randomUUID(),providerId:t,providerMessageId:D,status:s?"PENDING":"SENT",type:n.type,to:n.to,raw:c})}catch(f){return k(new w(P.NETWORK_ERROR,f instanceof Error?f.message:String(f),{providerId:t}))}}import{fail as h,KMsgError as C,KMsgErrorCode as j,ok as he}from"@k-msg/core";import{validateTemplatePayload as Ft}from"@k-msg/template";async function Ce(e){let t=await e.text(),r=H(t);return de(r,{code:Q(r)??e.status,message:t||String(r||"")})}function Ut(e,t){return new C(e.code,e.message,{providerId:t,...e.details??{}})}async function qt(e){let{providerId:t,config:r,input:n}=e;if(!n||typeof n!=="object")return h(new C(j.INVALID_REQUEST,"Template input is required",{providerId:t}));let i=Ft(n,{requireName:!0,requireContent:!0});if(i.isFailure)return h(Ut(i.error,t));let o=`${r.baseUrl}/api/template/add/`,l={templateName:i.value.name??n.name,templateContent:i.value.content??n.content,...i.value.buttons?{buttons:i.value.buttons}:{}};try{let d=await fetch(o,{method:"POST",headers:W(r),body:JSON.stringify(l)}),a=await Ce(d),s=Q(a.code)??d.status,p=typeof a.message==="string"&&a.message.length>0?a.message:"IWINV template create failed";if(!d.ok||s!==200)return h(new C(x(s),p,{providerId:t,originalCode:s}));let m=a.templateCode,u=typeof m==="string"&&m.trim().length>0?m.trim():"";if(!u)return h(new C(j.PROVIDER_ERROR,"IWINV template create did not return templateCode",{providerId:t,raw:a}));let g=new Date;return he({id:u,code:u,name:i.value.name??n.name,content:i.value.content??n.content,category:n.category,status:"INSPECTION",buttons:i.value.buttons,variables:n.variables,createdAt:g,updatedAt:g})}catch(d){return h(new C(j.NETWORK_ERROR,d instanceof Error?d.message:String(d),{providerId:t}))}}async function Ht(e){let{providerId:t,config:r,code:n,patch:i,ctx:o}=e,l=typeof n==="string"?n.trim():"";if(!l)return h(new C(j.INVALID_REQUEST,"code is required",{providerId:t}));let d=await Ue({providerId:t,config:r,code:l,ctx:o});if(d.isFailure)return d;let a=d.value,s=typeof i.name==="string"&&i.name.trim().length>0?i.name.trim():a.name,p=typeof i.content==="string"&&i.content.trim().length>0?i.content:a.content,m=i.buttons!==void 0?i.buttons:a.buttons,u=Ft({name:s,content:p,buttons:m},{requireName:!0,requireContent:!0});if(u.isFailure)return h(Ut(u.error,t));let g=`${r.baseUrl}/api/template/modify/`,S={templateCode:l,templateName:u.value.name??s,templateContent:u.value.content??p,...u.value.buttons?{buttons:u.value.buttons}:{}};try{let f=await fetch(g,{method:"POST",headers:W(r),body:JSON.stringify(S)}),y=await Ce(f),b=Q(y.code)??f.status,c=typeof y.message==="string"&&y.message.length>0?y.message:"IWINV template update failed";if(!f.ok||b!==200)return h(new C(x(b),c,{providerId:t,originalCode:b}));let A=await Ue({providerId:t,config:r,code:l,ctx:o});if(A.isSuccess)return A;return he({...a,name:u.value.name??s,content:u.value.content??p,...i.category!==void 0?{category:i.category}:{},...i.variables!==void 0?{variables:i.variables}:{},...i.buttons!==void 0?{buttons:u.value.buttons}:{},updatedAt:new Date})}catch(f){return h(new C(j.NETWORK_ERROR,f instanceof Error?f.message:String(f),{providerId:t}))}}async function Wt(e){let{providerId:t,config:r,code:n}=e,i=typeof n==="string"?n.trim():"";if(!i)return h(new C(j.INVALID_REQUEST,"code is required",{providerId:t}));let o=`${r.baseUrl}/api/template/delete/`,l={templateCode:i};try{let d=await fetch(o,{method:"POST",headers:W(r),body:JSON.stringify(l)}),a=await Ce(d),s=Q(a.code)??d.status,p=typeof a.message==="string"&&a.message.length>0?a.message:typeof a.messgae==="string"&&a.messgae.length>0?a.messgae:"IWINV template delete failed";if(!d.ok||s!==200)return h(new C(x(s),p,{providerId:t,originalCode:s}));return he(void 0)}catch(d){return h(new C(j.NETWORK_ERROR,d instanceof Error?d.message:String(d),{providerId:t}))}}async function Ue(e){let{providerId:t,config:r,code:n}=e,i=typeof n==="string"?n.trim():"";if(!i)return h(new C(j.INVALID_REQUEST,"code is required",{providerId:t}));let o={pageNum:"1",pageSize:"15",templateCode:i},l=`${r.baseUrl}/api/template/`;try{let d=await fetch(l,{method:"POST",headers:W(r),body:JSON.stringify(o)}),a=await Ce(d),s=Q(a.code)??d.status,p=typeof a.message==="string"&&a.message.length>0?a.message:"IWINV template get failed";if(!d.ok||s!==200)return h(new C(x(s),p,{providerId:t,originalCode:s}));let m=a.list,g=(Array.isArray(m)?m:[]).find(v);if(!g)return h(new C(j.TEMPLATE_NOT_FOUND,"Template not found",{providerId:t,templateCode:i}));let S=g.templateCode,f=typeof S==="string"?S:String(S??""),y=typeof g.templateName==="string"?g.templateName:"",b=typeof g.templateContent==="string"?g.templateContent:"",c=ze(g.status),A=ve(g.createDate)??new Date;return he({id:f,code:f,name:y,content:b,status:c,buttons:Array.isArray(g.buttons)?g.buttons:void 0,createdAt:A,updatedAt:A})}catch(d){return h(new C(j.NETWORK_ERROR,d instanceof Error?d.message:String(d),{providerId:t}))}}async function xt(e){let{providerId:t,config:r,query:n}=e,i=typeof n?.page==="number"&&n.page>0?Math.floor(n.page):1,o=typeof n?.limit==="number"&&n.limit>0?Math.floor(n.limit):15,l=Nt(n?.status),d={pageNum:String(i),pageSize:String(o),...l?{templateStatus:l}:{}},a=`${r.baseUrl}/api/template/`;try{let s=await fetch(a,{method:"POST",headers:W(r),body:JSON.stringify(d)}),p=await Ce(s),m=Q(p.code)??s.status,u=typeof p.message==="string"&&p.message.length>0?p.message:"IWINV template list failed";if(!s.ok||m!==200)return h(new C(x(m),u,{providerId:t,originalCode:m}));let g=p.list,f=(Array.isArray(g)?g:[]).filter(v).map((y)=>{let b=y.templateCode,c=typeof b==="string"?b:String(b??""),A=typeof y.templateName==="string"?y.templateName:"",T=typeof y.templateContent==="string"?y.templateContent:"",I=ze(y.status),_=ve(y.createDate)??new Date;return{id:c,code:c,name:A,content:T,status:I,buttons:Array.isArray(y.buttons)?y.buttons:void 0,createdAt:_,updatedAt:_}}).filter((y)=>y.code.length>0);return he(f)}catch(s){return h(new C(j.NETWORK_ERROR,s instanceof Error?s.message:String(s),{providerId:t}))}}class _e{id="iwinv";name="IWINV Messaging Provider";supportedTypes;config;getOnboardingSpec(){let e=fe(this.id);if(!e)throw new K(V.INVALID_REQUEST,`Onboarding spec missing for provider: ${this.id}`,{providerId:this.id});return e}constructor(e){if(!e||typeof e!=="object")throw new K(V.INVALID_REQUEST,"IWINVProvider requires a config object",{providerId:this.id});if(!e.apiKey||e.apiKey.length===0)throw new K(V.INVALID_REQUEST,"IWINVProvider requires `apiKey` configuration",{providerId:this.id});this.config={...e,baseUrl:Tt,sendEndpoint:e.sendEndpoint||"/api/v2/send/"};let t=["ALIMTALK"];if(Se(this.config))t.push("SMS","LMS","MMS");this.supportedTypes=t}async healthCheck(){let e=Date.now(),t=[];try{try{new URL(this.config.baseUrl)}catch{t.push("Invalid baseUrl")}if(Se(this.config))try{new URL(te())}catch{t.push("Invalid smsBaseUrl")}return{healthy:t.length===0,issues:t,latencyMs:Date.now()-e,data:{provider:this.id,baseUrl:this.config.baseUrl,smsBaseUrl:te()}}}catch(r){return t.push(r instanceof Error?r.message:String(r)),{healthy:!1,issues:t,latencyMs:Date.now()-e}}}async send(e){let t=e.messageId||crypto.randomUUID(),r={...e,messageId:t};switch(r.type){case"ALIMTALK":return Kt({providerId:this.id,config:this.config,options:r});case"SMS":case"LMS":case"MMS":return Vt({providerId:this.id,config:this.config,options:r});default:return X(new K(V.INVALID_REQUEST,`IWINVProvider does not support type ${r.type}`,{providerId:this.id,type:r.type}))}}async getDeliveryStatus(e){switch(e.type){case"ALIMTALK":return kt({providerId:this.id,config:this.config,query:e});case"SMS":case"LMS":case"MMS":return ht({providerId:this.id,config:this.config,query:e});default:return X(new K(V.INVALID_REQUEST,`IWINVProvider does not support type ${e.type}`,{providerId:this.id,type:e.type}))}}async getBalance(e){let t=e?.channel??"ALIMTALK";switch(t){case"ALIMTALK":return this.getAlimTalkBalance(t);case"SMS":case"LMS":case"MMS":return this.getSmsBalance(t);default:return X(new K(V.INVALID_REQUEST,`IWINVProvider does not support balance query for type ${t}`,{providerId:this.id,type:t}))}}async getAlimTalkBalance(e){let t=`${this.config.baseUrl}/api/charge/`;try{let r=await fetch(t,{method:"POST",headers:W(this.config),body:JSON.stringify({})}),n=await r.text(),i=H(n),o=de(i,{}),l=o.code,d=typeof l==="string"?Number(l):void 0,a=typeof l==="number"?l:typeof d==="number"&&Number.isFinite(d)?d:void 0,s=typeof o.message==="string"&&o.message.length>0?o.message:"IWINV AlimTalk charge query failed";if(!r.ok||a!==200)return X(new K(x(a??r.status),s,{providerId:this.id,originalCode:l??r.status}));let p=o.charge,m=typeof p==="number"?p:typeof p==="string"?Number(p):NaN;if(!Number.isFinite(m))return X(new K(V.PROVIDER_ERROR,"Invalid charge value from IWINV AlimTalk charge API",{providerId:this.id,raw:o}));return Bt({providerId:this.id,channel:e,amount:m,currency:"KRW",raw:o})}catch(r){return X(new K(V.NETWORK_ERROR,r instanceof Error?r.message:String(r),{providerId:this.id}))}}async getSmsBalance(e){if(!this.config.smsApiKey||!this.config.smsAuthKey)return X(new K(V.INVALID_REQUEST,"smsApiKey and smsAuthKey are required for SMS/LMS/MMS balance query",{providerId:this.id}));let r={"Content-Type":"application/json;charset=UTF-8",secret:pe(this.config)};if(typeof this.config.xForwardedFor==="string"&&this.config.xForwardedFor.length>0)r["X-Forwarded-For"]=this.config.xForwardedFor;let n=this.config.extraHeaders&&typeof this.config.extraHeaders==="object"?{...r,...this.config.extraHeaders}:r,i=`${te()}/api/charge/`;try{let o=await fetch(i,{method:"POST",headers:n,body:JSON.stringify({version:"1.0"})}),l=await o.text(),d=H(l),a=de(d,{}),s=a.code??a.resultCode,p=typeof s==="string"?Number(s):void 0,m=typeof s==="number"?s:typeof p==="number"&&Number.isFinite(p)?p:NaN,u=typeof a.message==="string"&&a.message.length>0?a.message:"IWINV SMS charge query failed";if(!o.ok||m!==0)return X(new K(V.PROVIDER_ERROR,u,{providerId:this.id,originalCode:s??o.status}));let g=a.charge,S=typeof g==="number"?g:typeof g==="string"?Number(g):NaN;if(!Number.isFinite(S))return X(new K(V.PROVIDER_ERROR,"Invalid charge value from IWINV SMS charge API",{providerId:this.id,raw:a}));return Bt({providerId:this.id,channel:e,amount:S,currency:"KRW",raw:a})}catch(o){return X(new K(V.NETWORK_ERROR,o instanceof Error?o.message:String(o),{providerId:this.id}))}}async createTemplate(e,t){return qt({providerId:this.id,config:this.config,input:e})}async updateTemplate(e,t,r){return Ht({providerId:this.id,config:this.config,code:e,patch:t,ctx:r})}async deleteTemplate(e,t){return Wt({providerId:this.id,config:this.config,code:e})}async getTemplate(e,t){return Ue({providerId:this.id,config:this.config,code:e,ctx:t})}async listTemplates(e,t){return xt({providerId:this.id,config:this.config,query:e,ctx:t})}}var lr=(e)=>new _e(e),Qt=()=>{let e={apiKey:Z("IWINV_API_KEY")||"",smsApiKey:Z("IWINV_SMS_API_KEY"),smsAuthKey:Z("IWINV_SMS_AUTH_KEY"),smsCompanyId:Z("IWINV_SMS_COMPANY_ID"),senderNumber:Z("IWINV_SENDER_NUMBER")||Z("IWINV_SMS_SENDER_NUMBER"),smsSenderNumber:Z("IWINV_SMS_SENDER_NUMBER"),sendEndpoint:Z("IWINV_SEND_ENDPOINT")||"/api/v2/send/",xForwardedFor:Z("IWINV_X_FORWARDED_FOR"),debug:Z("NODE_ENV")==="development"};if(!e.apiKey)throw new K(V.INVALID_REQUEST,"IWINV_API_KEY environment variable is required",{providerId:"iwinv"});return new _e(e)};class zt{static create(e){return new _e(e)}static createDefault(){return Qt()}}function pr(){}var ur={mock:{label:"Mock (local test)",routingSeedTypes:["ALIMTALK","FRIENDTALK","SMS","LMS","MMS","NSA","VOICE","FAX","RCS_SMS","RCS_LMS","RCS_MMS","RCS_TPL","RCS_ITPL","RCS_LTPL"],defaultKakaoSenderKey:"env:MOCK_SENDER_KEY"},aligo:{label:"Aligo",routingSeedTypes:["ALIMTALK","FRIENDTALK","SMS","LMS","MMS"],defaultKakaoSenderKey:"env:ALIGO_SENDER_KEY"},iwinv:{label:"IWINV",routingSeedTypes:["ALIMTALK","SMS","LMS","MMS"]},solapi:{label:"SOLAPI",routingSeedTypes:["ALIMTALK","FRIENDTALK","SMS","LMS","MMS","NSA","VOICE","FAX","RCS_SMS","RCS_LMS","RCS_MMS","RCS_TPL","RCS_ITPL","RCS_LTPL"],defaultKakaoSenderKey:"env:SOLAPI_KAKAO_PF_ID"}};import{fail as re,KMsgError as ne,KMsgErrorCode as N,ok as Y}from"@k-msg/core";var $t=(e)=>new Promise((t)=>{setTimeout(t,Math.max(0,Math.floor(e)))}),fr=(e)=>{if(e===N.INVALID_REQUEST||e===N.AUTHENTICATION_FAILED||e===N.INSUFFICIENT_BALANCE||e===N.TEMPLATE_NOT_FOUND||e===N.RATE_LIMIT_EXCEEDED||e===N.NETWORK_ERROR||e===N.NETWORK_TIMEOUT||e===N.NETWORK_SERVICE_UNAVAILABLE||e===N.PROVIDER_ERROR||e===N.MESSAGE_SEND_FAILED||e===N.UNKNOWN_ERROR)return e;return N.PROVIDER_ERROR};class jt{id="mock";name="Mock Provider";supportedTypes=["ALIMTALK","FRIENDTALK","SMS","LMS","MMS","NSA","VOICE","FAX","RCS_SMS","RCS_LMS","RCS_MMS","RCS_TPL","RCS_ITPL","RCS_LTPL"];calls=[];failureCount=0;scenario=[];scenarioCursor=0;templates=new Map;templateSeq=0;channelSeq=0;kakaoChannels=new Map;getOnboardingSpec(){let e=fe(this.id);if(!e)throw Error(`Onboarding spec missing for provider: ${this.id}`);return e}constructor(){let e=new Date,t={id:"MOCK_TPL_SEED",code:"MOCK_TPL_SEED",name:"Mock Seed Template",content:"Hello #{name}",status:"APPROVED",createdAt:e,updatedAt:e};this.templates.set(t.code,t);let r={providerId:this.id,senderKey:"mock-sender-seed",plusId:"@mock",name:"Mock Seed Channel",status:"A",createdAt:e,updatedAt:e};this.kakaoChannels.set(r.senderKey,r)}async healthCheck(){return{healthy:!0,issues:[]}}async send(e){this.calls.push(e);let t=this.nextScenarioOutcome();while(t.outcome==="delay")await $t(t.durationMs??0),t=this.nextScenarioOutcome();if(t.outcome==="timeout")return await $t(t.durationMs??0),re(new ne(N.NETWORK_TIMEOUT,t.message??"Mock provider simulated timeout",{provider:this.id},{providerErrorCode:t.providerErrorCode??"TIMEOUT",providerErrorText:t.providerErrorText,httpStatus:t.httpStatus,retryAfterMs:t.retryAfterMs}));if(t.outcome==="failure"){let n=fr(t.code);return re(new ne(n,t.message??"Mock provider simulated failure",{provider:this.id},{providerErrorCode:t.providerErrorCode,providerErrorText:t.providerErrorText,httpStatus:t.httpStatus,retryAfterMs:t.retryAfterMs,causeChain:t.causeChain}))}if(t.outcome!=="success")return re(new ne(N.UNKNOWN_ERROR,`Unsupported mock outcome: ${String(t.outcome)}`,{provider:this.id}));let r={messageId:e.messageId||crypto.randomUUID(),status:"SENT",providerId:this.id,providerMessageId:`mock-${Date.now()}-${Math.random().toString(36).substring(2,11)}`,type:e.type,to:e.to,...e.type==="ALIMTALK"&&e.failover?.enabled===!0?{warnings:[{code:"FAILOVER_UNSUPPORTED_PROVIDER",message:"Mock provider does not support native ALIMTALK failover.",details:{providerId:this.id}}]}:{}};return Y(r)}mockSuccess(){this.failureCount=0,this.clearScenario()}mockFailure(e){this.failureCount=e,this.clearScenario()}mockScenario(e){this.scenario=Array.isArray(e)?e.slice():[],this.scenarioCursor=0}clearScenario(){this.scenario=[],this.scenarioCursor=0}nextScenarioOutcome(){if(this.scenarioCursor<this.scenario.length){let e=this.scenario[this.scenarioCursor];return this.scenarioCursor+=1,e}if(this.failureCount>0)return this.failureCount-=1,{outcome:"failure",code:N.PROVIDER_ERROR,message:"Mock provider simulated failure"};return{outcome:"success"}}getHistory(){return this.calls}clearHistory(){this.calls=[]}async createTemplate(e,t){this.templateSeq+=1;let r=`MOCK_TPL_${this.templateSeq}`,n={id:r,code:r,name:e.name,content:e.content,category:e.category,buttons:e.buttons,variables:e.variables,status:"APPROVED",createdAt:new Date,updatedAt:new Date};return this.templates.set(n.code,n),Y(n)}async updateTemplate(e,t,r){let n=this.templates.get(e);if(!n)return re(new ne(N.TEMPLATE_NOT_FOUND,`Template not found: ${e}`));let i={...n,...typeof t.name==="string"?{name:t.name}:{},...typeof t.content==="string"?{content:t.content}:{},...t.category!==void 0?{category:t.category}:{},...t.buttons!==void 0?{buttons:t.buttons}:{},...t.variables!==void 0?{variables:t.variables}:{},updatedAt:new Date};return this.templates.set(e,i),Y(i)}async deleteTemplate(e,t){if(!this.templates.has(e))return re(new ne(N.TEMPLATE_NOT_FOUND,`Template not found: ${e}`));return this.templates.delete(e),Y(void 0)}async getTemplate(e,t){let r=this.templates.get(e);if(!r)return re(new ne(N.TEMPLATE_NOT_FOUND,`Template not found: ${e}`));return Y(r)}async listTemplates(e,t){let r=Array.from(this.templates.values());if(e?.status)r=r.filter((d)=>d.status===e.status);let n=e?.page||1,i=e?.limit||10,o=(n-1)*i,l=o+i;return Y(r.slice(o,l))}async requestTemplateInspection(e,t){if(!this.templates.has(e))return re(new ne(N.TEMPLATE_NOT_FOUND,`Template not found: ${e}`));return Y(void 0)}async listKakaoChannels(e){let t=Array.from(this.kakaoChannels.values());if(e?.plusId)t=t.filter((r)=>r.plusId===e.plusId);if(e?.senderKey)t=t.filter((r)=>r.senderKey===e.senderKey);return Y(t)}async listKakaoChannelCategories(){return Y({first:[{code:"001",name:"Mock First"}],second:[{code:"001001",name:"Mock Second",parentCode:"001"}],third:[{code:"001001001",name:"Mock Third",parentCode:"001001"}]})}async requestKakaoChannelAuth(e){if(!e.plusId||!e.phoneNumber)return re(new ne(N.INVALID_REQUEST,"plusId and phoneNumber are required",{providerId:this.id}));return Y(void 0)}async addKakaoChannel(e){if(!e.plusId||!e.authNum||!e.phoneNumber||!e.categoryCode)return re(new ne(N.INVALID_REQUEST,"plusId, authNum, phoneNumber, categoryCode are required",{providerId:this.id}));this.channelSeq+=1;let t=`mock-sender-${this.channelSeq}`,r={providerId:this.id,senderKey:t,plusId:e.plusId,name:"Mock Channel",status:"A",createdAt:new Date,updatedAt:new Date};return this.kakaoChannels.set(t,r),Y(r)}}export{He as providerOnboardingSpecs,sr as providerConfigFieldSpecs,ur as providerCliMetadata,Yt as listProviderOnboardingSpecs,pr as initializeIWINV,or as initializeAligo,fe as getProviderOnboardingSpec,lr as createIWINVProvider,Qt as createDefaultIWINVProvider,bt as createDefaultAligoProvider,ir as createAligoProvider,jt as MockProvider,zt as IWINVProviderFactory,_e as IWINVProvider,At as AligoProviderFactory,Te as AligoProvider};
|
|
1
|
+
import{fail as L,KMsgError as ce,KMsgErrorCode as Re,ok as ge}from"@k-msg/core";import{validateTemplatePayload as ft}from"@k-msg/template/send";function v(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}import{KMsgError as Me,KMsgErrorCode as fe}from"@k-msg/core";function V(e,t){if(e instanceof Me)return e;return new Me(fe.PROVIDER_ERROR,e instanceof Error?e.message:String(e),{providerId:t})}function Ee(e,t){if(e instanceof Me)return e;let r=v(e)?e:{},n=r.result_code,i=n!==void 0&&n!==null?String(n):"UNKNOWN",o=typeof r.message==="string"&&r.message.length>0?r.message:typeof r.msg==="string"&&r.msg.length>0?r.msg:e instanceof Error?e.message:"Unknown Aligo error",l=fe.PROVIDER_ERROR;switch(i){case"-100":case"-101":l=fe.AUTHENTICATION_FAILED;break;case"-102":case"-201":l=fe.INSUFFICIENT_BALANCE;break;case"-103":case"-105":l=fe.INVALID_REQUEST;break;case"-501":l=fe.TEMPLATE_NOT_FOUND;break;default:l=fe.PROVIDER_ERROR}return new Me(l,`${o} (code: ${i})`,{providerId:t,resultCode:i})}import{fail as er,KMsgError as ut,KMsgErrorCode as Qe,ok as tr}from"@k-msg/core";import{KMsgError as at,KMsgErrorCode as dt}from"@k-msg/core";function Zt(e,t){if(!e)return"";return e.replace(/#\{([^}]+)\}/g,(r,n)=>{let i=t[n];return i===void 0||i===null?r:String(i)})}function Be(e){let t=typeof e.imageUrl==="string"&&e.imageUrl.trim().length>0?e.imageUrl.trim():void 0;if(t)return t;let r=e.media?.image;if(!r)return;if("ref"in r){let n=r.ref.trim();return n.length>0?n:void 0}throw new at(dt.INVALID_REQUEST,"Aligo MMS/FriendTalk image requires `options.imageUrl` or `options.media.image.ref` (url/path).",{providerId:e.providerId})}function Pe(e,t){switch(e){case"sendSMS":return"/send/";case"sendAlimTalk":return"/akv10/alimtalk/send/";case"sendFriendTalk":return t.friendtalkEndpoint||"/akv10/friendtalk/send/";default:return"/"}}function Le(e){let t=e.getFullYear(),r=String(e.getMonth()+1).padStart(2,"0"),n=String(e.getDate()).padStart(2,"0"),i=String(e.getHours()).padStart(2,"0"),o=String(e.getMinutes()).padStart(2,"0");return{date:`${t}${r}${n}`,time:`${i}${o}`}}function lt(e){if(typeof e==="number"&&Number.isFinite(e))return e;if(typeof e==="string"){let t=e.trim();if(!t)return;let r=Number(t);if(Number.isFinite(r))return r}return}function me(e,t){let r=(typeof t?.kakaoChannelSenderKey==="string"&&t.kakaoChannelSenderKey.trim().length>0?t.kakaoChannelSenderKey.trim():e.config.senderKey)||"";if(!r)throw new at(dt.INVALID_REQUEST,"kakao channel senderKey is required (ctx.kakaoChannelSenderKey or config.senderKey)",{providerId:e.providerId});return r}function Ke(e){switch(typeof e.inspStatus==="string"?e.inspStatus.trim().toUpperCase():""){case"APR":return"APPROVED";case"REJ":return"REJECTED";case"REQ":case"REG":return"INSPECTION";default:return"PENDING"}}function M(e){if(typeof e!=="string")return;let t=e.trim();if(!t)return;let r=/^(\d{4})-(\d{2})-(\d{2})\s+(\d{2}):(\d{2}):(\d{2})$/.exec(t);if(!r)return;let n=Number(r[1]),i=Number(r[2]),o=Number(r[3]),l=Number(r[4]),d=Number(r[5]),a=Number(r[6]),s=new Date(n,i-1,o,l,d,a);return Number.isNaN(s.getTime())?void 0:s}function pt(e,t){if(!e)return"";let r=e._full_text;if(r!==void 0&&r!==null)return String(r);if(!t)return Object.values(e).map(String).join(`
|
|
2
|
+
`);return Zt(t,e)}async function D(e){let t=new FormData;for(let[n,i]of Object.entries(e.data))if(i!==void 0&&i!==null)t.append(n,String(i));let r=await fetch(`${e.host}${e.endpoint}`,{method:"POST",body:t});if(!r.ok)throw new ut(Qe.NETWORK_ERROR,`HTTP error! status: ${r.status}`,{providerId:e.providerId});return await r.json()}function U(e){let{providerId:t,response:r,fallbackMessage:n}=e,i=r.code,o=lt(i);if(o===0)return tr(void 0);let l=typeof r.message==="string"&&r.message.length>0?r.message:n,d=o===509||o===-99?Qe.INVALID_REQUEST:Qe.PROVIDER_ERROR;return er(new ut(d,l,{providerId:t,originalCode:i,raw:r}))}import{ButtonParser as rr}from"@k-msg/template/send";function We(e){if(!Array.isArray(e)||e.length===0)return;let t=JSON.parse(rr.serializeButtons(e));return JSON.stringify({button:t})}function mt(e,t){return new ce(e.code,e.message,{providerId:t,...e.details??{}})}async function ct(e,t,r){try{let n=me(e,r),i=ft(t,{requireName:!0,requireContent:!0});if(i.isFailure)return L(mt(i.error,e.providerId));let o={apikey:e.config.apiKey,userid:e.config.userId,senderkey:n,tpl_name:i.value.name??t.name,tpl_content:i.value.content??t.content},l=We(i.value.buttons);if(l)o.tpl_button=l;let d=await D({host:e.alimtalkHost,endpoint:"/akv10/template/add/",data:o,providerId:e.providerId}),a=U({providerId:e.providerId,response:d,fallbackMessage:"template create failed"});if(a.isFailure)return a;let s=v(d.data)?d.data:{},p=String(s.templtCode??"");if(!p)return L(new ce(Re.PROVIDER_ERROR,"template create did not return templtCode",{providerId:e.providerId,raw:d}));let g=M(s.cdate)??new Date,u=M(s.udate)??M(s.cdate)??g;return ge({id:p,code:p,name:String(s.templtName??i.value.name??t.name),content:String(s.templtContent??i.value.content??t.content),category:t.category,status:Ke(s),buttons:Array.isArray(s.buttons)?s.buttons:i.value.buttons,variables:t.variables,createdAt:g,updatedAt:u})}catch(n){return L(V(n,e.providerId))}}async function Fe(e,t,r){try{let n=me(e,r),i=t.trim();if(!i)return L(new ce(Re.INVALID_REQUEST,"code is required",{providerId:e.providerId}));let o=await D({host:e.alimtalkHost,endpoint:"/akv10/template/list/",data:{apikey:e.config.apiKey,userid:e.config.userId,senderkey:n,tpl_code:i},providerId:e.providerId}),l=U({providerId:e.providerId,response:o,fallbackMessage:"template get failed"});if(l.isFailure)return l;let d=o.list,s=(Array.isArray(d)?d:[]).find(v);if(!s)return L(new ce(Re.TEMPLATE_NOT_FOUND,"Template not found",{providerId:e.providerId,templateCode:i}));let p=String(s.templtCode??i),g=M(s.cdate)??new Date,u=M(s.udate)??M(s.cdate)??g;return ge({id:p,code:p,name:String(s.templtName??""),content:String(s.templtContent??""),status:Ke(s),buttons:Array.isArray(s.buttons)?s.buttons:void 0,createdAt:g,updatedAt:u})}catch(n){return L(V(n,e.providerId))}}async function gt(e,t,r,n){try{let i=me(e,n),o=t.trim();if(!o)return L(new ce(Re.INVALID_REQUEST,"code is required",{providerId:e.providerId}));let l=await Fe(e,o,{kakaoChannelSenderKey:i});if(l.isFailure)return l;let d=l.value,a=typeof r.name==="string"&&r.name.trim().length>0?r.name.trim():d.name,s=typeof r.content==="string"&&r.content.trim().length>0?r.content:d.content,p=ft({name:a,content:s,buttons:r.buttons!==void 0?r.buttons:d.buttons},{requireName:!0,requireContent:!0});if(p.isFailure)return L(mt(p.error,e.providerId));let g={apikey:e.config.apiKey,userid:e.config.userId,senderkey:i,tpl_code:o,tpl_name:p.value.name??a,tpl_content:p.value.content??s},u=We(p.value.buttons);if(u)g.tpl_button=u;let c=await D({host:e.alimtalkHost,endpoint:"/akv10/template/modify/",data:g,providerId:e.providerId}),S=U({providerId:e.providerId,response:c,fallbackMessage:"template update failed"});if(S.isFailure)return S;let f=await Fe(e,o,{kakaoChannelSenderKey:i});if(f.isSuccess)return f;return ge({...d,name:p.value.name??a,content:p.value.content??s,...r.category!==void 0?{category:r.category}:{},...r.variables!==void 0?{variables:r.variables}:{},...r.buttons!==void 0?{buttons:p.value.buttons}:{},updatedAt:new Date})}catch(i){return L(V(i,e.providerId))}}async function yt(e,t,r){try{let n=me(e,r),i=t.trim();if(!i)return L(new ce(Re.INVALID_REQUEST,"code is required",{providerId:e.providerId}));let o=await D({host:e.alimtalkHost,endpoint:"/akv10/template/del/",data:{apikey:e.config.apiKey,userid:e.config.userId,senderkey:n,tpl_code:i},providerId:e.providerId}),l=U({providerId:e.providerId,response:o,fallbackMessage:"template delete failed"});if(l.isFailure)return l;return ge(void 0)}catch(n){return L(V(n,e.providerId))}}async function It(e,t,r){try{let n=me(e,r),i=await D({host:e.alimtalkHost,endpoint:"/akv10/template/list/",data:{apikey:e.config.apiKey,userid:e.config.userId,senderkey:n},providerId:e.providerId}),o=U({providerId:e.providerId,response:i,fallbackMessage:"template list failed"});if(o.isFailure)return o;let l=i.list,a=(Array.isArray(l)?l:[]).filter(v).map((s)=>{let p=String(s.templtCode??""),g=M(s.cdate)??new Date,u=M(s.udate)??M(s.cdate)??g;return{id:p,code:p,name:String(s.templtName??""),content:String(s.templtContent??""),status:Ke(s),buttons:Array.isArray(s.buttons)?s.buttons:void 0,createdAt:g,updatedAt:u}}).filter((s)=>s.code.length>0);if(t?.status){let s=t.status.trim().toUpperCase();return ge(a.filter((p)=>p.status===s))}return ge(a)}catch(n){return L(V(n,e.providerId))}}async function St(e,t,r){try{let n=me(e,r),i=t.trim();if(!i)return L(new ce(Re.INVALID_REQUEST,"code is required",{providerId:e.providerId}));let o=await D({host:e.alimtalkHost,endpoint:"/akv10/template/request/",data:{apikey:e.config.apiKey,userid:e.config.userId,senderkey:n,tpl_code:i},providerId:e.providerId}),l=U({providerId:e.providerId,response:o,fallbackMessage:"template inspection request failed"});if(l.isFailure)return l;return ge(void 0)}catch(n){return L(V(n,e.providerId))}}import{readRuntimeEnv as Ie}from"@k-msg/core";var ze={iwinv:{providerId:"iwinv",providerName:"IWINV Messaging Provider",channelOnboarding:"manual",templateLifecycleApi:"available",plusIdPolicy:"optional",plusIdInference:"unsupported",liveTestSupport:"supported",checks:[{id:"channel_registered_in_console",title:"Kakao channel is registered in IWINV console",description:"IWINV channel onboarding is manual. Confirm channel registration and approval in console.",kind:"manual",severity:"blocker",scopes:["doctor","preflight"]},{id:"iwinv_config_required",title:"IWINV config has required keys",kind:"config",severity:"blocker",scopes:["doctor","preflight"],configKeys:["apiKey"]},{id:"template_capability_available",title:"Template lifecycle APIs are available",kind:"capability",severity:"warning",scopes:["doctor","preflight"],capabilityMethods:["listTemplates","getTemplate","createTemplate","updateTemplate","deleteTemplate"]},{id:"template_list_probe",title:"Template list API probe",kind:"api_probe",severity:"warning",scopes:["doctor","preflight"],probeOperation:"list_templates"}],notes:["Channel add/auth is not available via IWINV public API in current integration.","Template APIs are available and can be probed."]},aligo:{providerId:"aligo",providerName:"Aligo Smart SMS",channelOnboarding:"api",templateLifecycleApi:"available",plusIdPolicy:"required_if_no_inference",plusIdInference:"supported",liveTestSupport:"supported",checks:[{id:"aligo_config_required",title:"Aligo config has required keys",kind:"config",severity:"blocker",scopes:["doctor","preflight"],configKeys:["apiKey","userId"]},{id:"channel_api_capability_available",title:"Kakao channel APIs are available",kind:"capability",severity:"warning",scopes:["doctor","preflight"],capabilityMethods:["listKakaoChannels","requestKakaoChannelAuth","addKakaoChannel"]},{id:"channel_list_probe",title:"Kakao channel list API probe",kind:"api_probe",severity:"warning",scopes:["doctor","preflight"],probeOperation:"list_kakao_channels"},{id:"template_list_probe",title:"Template list API probe",kind:"api_probe",severity:"warning",scopes:["doctor","preflight"],probeOperation:"list_templates"}]},solapi:{providerId:"solapi",providerName:"SOLAPI Messaging Provider",channelOnboarding:"none",templateLifecycleApi:"unavailable",plusIdPolicy:"required_if_no_inference",plusIdInference:"unsupported",liveTestSupport:"partial",checks:[{id:"solapi_config_required",title:"SOLAPI config has required keys",kind:"config",severity:"blocker",scopes:["doctor","preflight"],configKeys:["apiKey","apiSecret"]}],notes:["SOLAPI ALIMTALK requires kakao profileId/pfId, but plusId inference is not available in current integration."]},mock:{providerId:"mock",providerName:"Mock Provider",channelOnboarding:"api",templateLifecycleApi:"available",plusIdPolicy:"optional",plusIdInference:"supported",liveTestSupport:"none",checks:[{id:"mock_template_capability_available",title:"Mock template APIs are available",kind:"capability",severity:"info",scopes:["doctor","preflight"],capabilityMethods:["listTemplates","getTemplate","createTemplate"]}]}};function ye(e){return ze[e]}function nr(){return Object.values(ze)}import{fail as oe,KMsgError as Ve,KMsgErrorCode as Ue,ok as qe}from"@k-msg/core";async function vt(e,t){try{let r={apikey:e.config.apiKey,userid:e.config.userId,...typeof t?.plusId==="string"&&t.plusId.trim().length>0?{plusid:t.plusId.trim()}:{},...typeof t?.senderKey==="string"&&t.senderKey.trim().length>0?{senderkey:t.senderKey.trim()}:{}},n=await D({host:e.alimtalkHost,endpoint:"/akv10/profile/list/",data:r,providerId:e.providerId}),i=U({providerId:e.providerId,response:n,fallbackMessage:"channel list failed"});if(i.isFailure)return i;let o=n.list,d=(Array.isArray(o)?o:[]).filter(v).map((a)=>({providerId:e.providerId,senderKey:String(a.senderKey??""),plusId:typeof a.uuid==="string"?a.uuid:void 0,name:typeof a.name==="string"?a.name:void 0,status:typeof a.status==="string"?a.status:void 0,createdAt:M(a.cdate),updatedAt:M(a.udate),raw:a})).filter((a)=>a.senderKey.length>0);return qe(d)}catch(r){return oe(V(r,e.providerId))}}async function bt(e){try{let t=await D({host:e.alimtalkHost,endpoint:"/akv10/category/",data:{apikey:e.config.apiKey,userid:e.config.userId},providerId:e.providerId}),r=U({providerId:e.providerId,response:t,fallbackMessage:"category list failed"});if(r.isFailure)return r;let n=v(t.data)?t.data:{},i=(o)=>{return(Array.isArray(o)?o:[]).filter(v).map((d)=>({code:String(d.code??""),name:String(d.name??""),parentCode:typeof d.parentCode==="string"&&d.parentCode.length>0?d.parentCode:void 0})).filter((d)=>d.code.length>0)};return qe({first:i(n.firstBusinessType),second:i(n.secondBusinessType),third:i(n.thirdBusinessType)})}catch(t){return oe(V(t,e.providerId))}}async function Rt(e,t){try{let r=t.plusId.trim(),n=t.phoneNumber.trim();if(!r||!n)return oe(new Ve(Ue.INVALID_REQUEST,"plusId and phoneNumber are required",{providerId:e.providerId}));let i=await D({host:e.alimtalkHost,endpoint:"/akv10/profile/auth/",data:{apikey:e.config.apiKey,userid:e.config.userId,plusid:r,phonenumber:n},providerId:e.providerId}),o=U({providerId:e.providerId,response:i,fallbackMessage:"channel auth failed"});if(o.isFailure)return o;return qe(void 0)}catch(r){return oe(V(r,e.providerId))}}async function At(e,t){try{let r=t.plusId.trim(),n=t.authNum.trim(),i=t.phoneNumber.trim(),o=t.categoryCode.trim();if(!r||!n||!i||!o)return oe(new Ve(Ue.INVALID_REQUEST,"plusId, authNum, phoneNumber, categoryCode are required",{providerId:e.providerId}));let l=await D({host:e.alimtalkHost,endpoint:"/akv10/profile/add/",data:{apikey:e.config.apiKey,userid:e.config.userId,plusid:r,authnum:n,phonenumber:i,categorycode:o},providerId:e.providerId}),d=U({providerId:e.providerId,response:l,fallbackMessage:"channel add failed"});if(d.isFailure)return d;let a=l.data,s=Array.isArray(a)?a.find(v):v(a)?a:void 0;if(!s)return oe(new Ve(Ue.PROVIDER_ERROR,"channel add returned empty data",{providerId:e.providerId,raw:l}));let p=String(s.senderKey??"");if(!p)return oe(new Ve(Ue.PROVIDER_ERROR,"channel add did not return senderKey",{providerId:e.providerId,raw:s}));return qe({providerId:e.providerId,senderKey:p,plusId:typeof s.uuid==="string"?s.uuid:r,name:typeof s.name==="string"?s.name:void 0,status:typeof s.status==="string"?s.status:void 0,createdAt:M(s.cdate),updatedAt:M(s.udate),raw:s})}catch(r){return oe(V(r,e.providerId))}}import{fail as q,KMsgError as se,KMsgErrorCode as ae,ok as $e}from"@k-msg/core";function ir(e,t){if(e.type!=="ALIMTALK")return;if(e.failover?.enabled!==!0)return;return[{code:"FAILOVER_PARTIAL_PROVIDER",message:"Aligo failover mapping is partial. API-level fallback may be attempted for non-Kakao-user failures.",details:{providerId:t,mappedFields:["failover","fmessage_1","fsubject_1"],unsupportedFields:["fallbackChannel"]}}]}async function or(e,t){let r=t.from||e.config.sender||"";if(!r)return q(new se(ae.INVALID_REQUEST,"from is required for SMS/LMS/MMS (options.from or config.sender)",{providerId:e.providerId}));let n={key:e.config.apiKey,user_id:e.config.userId,sender:r,receiver:t.to,msg:t.text,msg_type:t.type,title:t.subject,testmode_yn:e.config.testMode?"Y":"N"},i=t.options?.scheduledAt;if(i instanceof Date&&!Number.isNaN(i.getTime())){let{date:l,time:d}=Le(i);n.rdate=l,n.rtime=d}if(t.type==="MMS"){let l=Be({imageUrl:t.imageUrl,media:t.media,providerId:e.providerId});if(!l)return q(new se(ae.INVALID_REQUEST,"image is required for MMS (options.imageUrl or options.media.image.ref)",{providerId:e.providerId}));n.image=l}let o=await D({host:e.smsHost,endpoint:Pe("sendSMS",e.config),data:n,providerId:e.providerId});if(o.result_code!=="1")return q(Ee(o,e.providerId));return $e({messageId:t.messageId||crypto.randomUUID(),providerId:e.providerId,providerMessageId:o.msg_id,status:"PENDING",type:t.type,to:t.to,raw:o})}async function sr(e,t){let r=ir(t,e.providerId),n=(typeof t.kakao?.profileId==="string"?t.kakao.profileId:e.config.senderKey)||"";if(!n)return q(new se(ae.INVALID_REQUEST,"kakao profileId is required (options.kakao.profileId or config.senderKey)",{providerId:e.providerId}));let i=t.from||e.config.sender||"";if(!i)return q(new se(ae.INVALID_REQUEST,"from is required for ALIMTALK (options.from or config.sender)",{providerId:e.providerId}));let{variables:o,templateId:l}=t;if(!l||l.length===0)return q(new se(ae.INVALID_REQUEST,"templateId is required for ALIMTALK",{providerId:e.providerId}));let d=typeof t.providerOptions?.templateContent==="string"?t.providerOptions.templateContent:void 0,a={apikey:e.config.apiKey,userid:e.config.userId,senderkey:n,tpl_code:l,sender:i,receiver_1:t.to,subject_1:"알림톡",message_1:pt(o,d),testMode:e.config.testMode?"Y":"N"},s=typeof t.providerOptions?.failover==="string"?t.providerOptions.failover.trim().toUpperCase():"",p=s==="Y"||s==="N"?s:void 0,g=t.failover?.enabled===!0?"Y":t.failover?.enabled===!1?"N":void 0,u=p??g,c=typeof t.providerOptions?.fsubject_1==="string"&&t.providerOptions.fsubject_1.trim().length>0?t.providerOptions.fsubject_1.trim():typeof t.failover?.fallbackTitle==="string"&&t.failover.fallbackTitle.trim().length>0?t.failover.fallbackTitle.trim():void 0,S=typeof t.providerOptions?.fmessage_1==="string"&&t.providerOptions.fmessage_1.trim().length>0?t.providerOptions.fmessage_1.trim():typeof t.failover?.fallbackContent==="string"&&t.failover.fallbackContent.trim().length>0?t.failover.fallbackContent.trim():void 0;if(u)a.failover=u;if(c)a.fsubject_1=c;if(S)a.fmessage_1=S;let f=t.options?.scheduledAt;if(f instanceof Date&&!Number.isNaN(f.getTime())){let{date:b,time:m}=Le(f);a.reserve="Y",a.reserve_date=b,a.reserve_time=m}let y=await D({host:e.alimtalkHost,endpoint:Pe("sendAlimTalk",e.config),data:a,providerId:e.providerId});if(y.result_code!=="0")return q(Ee(y,e.providerId));return $e({messageId:t.messageId||crypto.randomUUID(),providerId:e.providerId,providerMessageId:y.msg_id,status:"PENDING",type:t.type,to:t.to,...Array.isArray(r)&&r.length>0?{warnings:r}:{},raw:y})}async function ar(e,t){let r=(typeof t.kakao?.profileId==="string"?t.kakao.profileId:e.config.senderKey)||"";if(!r)return q(new se(ae.INVALID_REQUEST,"kakao profileId is required (options.kakao.profileId or config.senderKey)",{providerId:e.providerId}));let n=t.from||e.config.sender||"";if(!n)return q(new se(ae.INVALID_REQUEST,"from is required for FRIENDTALK (options.from or config.sender)",{providerId:e.providerId}));let i={apikey:e.config.apiKey,userid:e.config.userId,senderkey:r,sender:n,receiver_1:t.to,subject_1:"친구톡",message_1:t.text,testMode:e.config.testMode?"Y":"N"},o=Be({imageUrl:t.imageUrl,media:t.media,providerId:e.providerId});if(o)i.image_1=o;let l=Array.isArray(t.kakao?.buttons)?t.kakao.buttons:t.buttons;if(l)i.button_1=JSON.stringify(l);let d=t.options?.scheduledAt;if(d instanceof Date&&!Number.isNaN(d.getTime())){let{date:s,time:p}=Le(d);i.reserve="Y",i.reserve_date=s,i.reserve_time=p}let a=await D({host:e.alimtalkHost,endpoint:Pe("sendFriendTalk",e.config),data:i,providerId:e.providerId});if(a.result_code!=="0")return q(Ee(a,e.providerId));return $e({messageId:t.messageId||crypto.randomUUID(),providerId:e.providerId,providerMessageId:a.msg_id,status:"PENDING",type:t.type,to:t.to,raw:a})}async function Tt(e,t){try{switch(t.type){case"ALIMTALK":return await sr(e,t);case"FRIENDTALK":return await ar(e,t);case"SMS":case"LMS":case"MMS":return await or(e,t);default:return q(new se(ae.INVALID_REQUEST,`AligoProvider does not support type ${t.type}`,{providerId:e.providerId,type:t.type}))}}catch(r){return q(Ee(r,e.providerId))}}function je(){return{apiKey:Ie("ALIGO_API_KEY")||"",userId:Ie("ALIGO_USER_ID")||"",senderKey:Ie("ALIGO_SENDER_KEY")||"",sender:Ie("ALIGO_SENDER")||"",friendtalkEndpoint:Ie("ALIGO_FRIENDTALK_ENDPOINT"),testMode:Ie("NODE_ENV")!=="production",debug:Ie("NODE_ENV")==="development"}}class Ae{id="aligo";name="Aligo Smart SMS";supportedTypes=["ALIMTALK","FRIENDTALK","SMS","LMS","MMS"];config;smsHost;alimtalkHost;getOnboardingSpec(){let e=ye(this.id);if(!e)throw Error(`Onboarding spec missing for provider: ${this.id}`);return e}constructor(e){if(!e||typeof e!=="object")throw Error("AligoProvider requires a config object");if(!e.apiKey||e.apiKey.length===0)throw Error("AligoProvider requires `apiKey`");if(!e.userId||e.userId.length===0)throw Error("AligoProvider requires `userId`");this.config=e,this.smsHost=e.smsBaseUrl||"https://apis.aligo.in",this.alimtalkHost=e.alimtalkBaseUrl||"https://kakaoapi.aligo.in"}getRuntimeContext(){return{providerId:this.id,config:this.config,smsHost:this.smsHost,alimtalkHost:this.alimtalkHost}}async healthCheck(){let e=Date.now(),t=[];try{if(!this.config.apiKey)t.push("Missing apiKey");if(!this.config.userId)t.push("Missing userId");if(!this.config.sender)t.push("Missing sender (default from)");try{new URL(this.smsHost)}catch{t.push("Invalid smsBaseUrl")}try{new URL(this.alimtalkHost)}catch{t.push("Invalid alimtalkBaseUrl")}return{healthy:t.length===0,issues:t,latencyMs:Date.now()-e,data:{provider:this.id,smsBaseUrl:this.smsHost,alimtalkBaseUrl:this.alimtalkHost}}}catch(r){return t.push(r instanceof Error?r.message:String(r)),{healthy:!1,issues:t,latencyMs:Date.now()-e}}}async send(e){let t=e.messageId||crypto.randomUUID(),r={...e,messageId:t};return Tt(this.getRuntimeContext(),r)}async listKakaoChannels(e){return vt(this.getRuntimeContext(),e)}async listKakaoChannelCategories(){return bt(this.getRuntimeContext())}async requestKakaoChannelAuth(e){return Rt(this.getRuntimeContext(),e)}async addKakaoChannel(e){return At(this.getRuntimeContext(),e)}}var nn=(e)=>new Ae(e),dr=()=>{let e=je();if(!e.apiKey||!e.userId)throw Error("ALIGO_API_KEY and ALIGO_USER_ID are required");return new Ae(e)};class lr{static create(e){return new Ae(e)}static createDefault(){return dr()}}class we extends Ae{async createTemplate(e,t){return ct(this.getRuntimeContext(),e,t)}async updateTemplate(e,t,r){return gt(this.getRuntimeContext(),e,t,r)}async deleteTemplate(e,t){return yt(this.getRuntimeContext(),e,t)}async getTemplate(e,t){return Fe(this.getRuntimeContext(),e,t)}async listTemplates(e,t){return It(this.getRuntimeContext(),e,t)}async requestTemplateInspection(e,t){return St(this.getRuntimeContext(),e,t)}}var pr=(e)=>new we(e),Nt=()=>{let e=je();return new we(e)};class Et{static create(e){return new we(e)}static createDefault(){return Nt()}}function ur(){}var fr={mock:{},aligo:{apiKey:{type:"string",required:!0,description:"Aligo API key",defaultValue:"env:ALIGO_API_KEY"},userId:{type:"string",required:!0,description:"Aligo user id",defaultValue:"env:ALIGO_USER_ID"},senderKey:{type:"string",description:"Default Kakao sender key",defaultValue:"env:ALIGO_SENDER_KEY"},sender:{type:"string",description:"Default SMS/LMS sender number",defaultValue:"env:ALIGO_SENDER"},testMode:{type:"boolean",description:"Enable Aligo test mode"},debug:{type:"boolean",description:"Enable debug logging"},smsBaseUrl:{type:"string",description:"Override SMS API base URL"},alimtalkBaseUrl:{type:"string",description:"Override AlimTalk API base URL"},friendtalkEndpoint:{type:"string",description:"Override FriendTalk endpoint path"}},iwinv:{apiKey:{type:"string",required:!0,description:"IWINV AlimTalk API key (AUTH header)",defaultValue:"env:IWINV_API_KEY"},smsApiKey:{type:"string",description:"IWINV SMS API key",defaultValue:"env:IWINV_SMS_API_KEY"},smsAuthKey:{type:"string",description:"IWINV SMS auth key",defaultValue:"env:IWINV_SMS_AUTH_KEY"},smsCompanyId:{type:"string",description:"IWINV SMS company id",defaultValue:"env:IWINV_SMS_COMPANY_ID"},senderNumber:{type:"string",description:"Default sender number",defaultValue:"env:IWINV_SENDER_NUMBER"},smsSenderNumber:{type:"string",description:"SMS/LMS sender number override"},sendEndpoint:{type:"string",description:"Override IWINV send endpoint path"},xForwardedFor:{type:"string",description:"X-Forwarded-For header override"},extraHeaders:{type:"stringRecord",description:"Additional HTTP headers"},ipRetryCount:{type:"number",description:"IP-restriction retry count"},ipRetryDelayMs:{type:"number",description:"IP-restriction retry delay in ms"},ipAlertWebhookUrl:{type:"string",description:"Webhook URL for IP restriction alerts"},debug:{type:"boolean",description:"Enable debug logging"}},solapi:{apiKey:{type:"string",required:!0,description:"SOLAPI API key",defaultValue:"env:SOLAPI_API_KEY"},apiSecret:{type:"string",required:!0,description:"SOLAPI API secret",defaultValue:"env:SOLAPI_API_SECRET"},defaultFrom:{type:"string",description:"Default sender number",defaultValue:"env:SOLAPI_DEFAULT_FROM"},kakaoPfId:{type:"string",description:"Default Kakao PF ID",defaultValue:"env:SOLAPI_KAKAO_PF_ID"},rcsBrandId:{type:"string",description:"Default RCS brand id"},naverTalkId:{type:"string",description:"Default Naver Talk id"},appId:{type:"string",description:"SOLAPI app id"},defaultCountry:{type:"string",description:"Default country code"},baseUrl:{type:"string",description:"Override SOLAPI API base URL"},debug:{type:"boolean",description:"Enable debug logging"}}};import{fail as k,KMsgError as C,KMsgErrorCode as z,ok as Ce}from"@k-msg/core";import{validateTemplatePayload as ht}from"@k-msg/template/send";function H(e){if(!e)return{};try{return JSON.parse(e)}catch{return e}}function de(e,t){return v(e)?e:t}import{KMsgErrorCode as le}from"@k-msg/core";function mr(e){let t="",r=0;while(r<e.length){let n=e[r++]??0,i=e[r++]??0,o=e[r++]??0,l=n<<16|i<<8|o;t+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[l>>18&63],t+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[l>>12&63],t+=r-2<e.length?"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[l>>6&63]:"=",t+=r-1<e.length?"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[l&63]:"="}return t}function ke(e){return mr(new TextEncoder().encode(e))}function wt(e){let t=e.sendEndpoint||"/api/v2/send/";return t.startsWith("/")?t:`/${t}`}function x(e){let r={AUTH:ke(e.apiKey),"Content-Type":"application/json;charset=UTF-8"};if(typeof e.xForwardedFor==="string"&&e.xForwardedFor.length>0)r["X-Forwarded-For"]=e.xForwardedFor;if(e.extraHeaders&&typeof e.extraHeaders==="object")return{...r,...e.extraHeaders};return r}function B(e){switch(e){case 201:case 206:case 401:case 403:return le.AUTHENTICATION_FAILED;case 429:return le.RATE_LIMIT_EXCEEDED;case 519:return le.INSUFFICIENT_BALANCE;case 404:case 501:return le.TEMPLATE_NOT_FOUND;case 502:case 503:case 504:case 505:case 506:case 507:case 508:case 509:case 510:case 511:case 512:case 513:case 514:case 515:case 516:case 517:case 540:return le.INVALID_REQUEST;case 518:return le.PROVIDER_ERROR;default:if(e>=500)return le.PROVIDER_ERROR;return le.INVALID_REQUEST}}function W(e){if(typeof e==="number"&&Number.isFinite(e))return e;if(typeof e==="string"){let t=e.trim();if(t.length===0)return;let r=Number(t);if(Number.isFinite(r))return r}return}function kt(e){if(typeof e!=="string")return;let t=e.trim().toUpperCase();if(!t)return;switch(t){case"Y":case"APPROVED":return"Y";case"I":case"INSPECTION":return"I";case"R":case"REJECTED":return"R";case"PENDING":return"I";default:return}}function Ye(e){switch(typeof e==="string"?e.trim().toUpperCase():""){case"Y":return"APPROVED";case"I":return"INSPECTION";case"R":return"REJECTED";default:return"PENDING"}}function Je(e,t){return new Date(e.getTime()+t*24*60*60*1000)}function Ge(e){let t=(r)=>r.toString().padStart(2,"0");return`${e.getFullYear()}-${t(e.getMonth()+1)}-${t(e.getDate())}`}function Se(e){if(typeof e!=="string")return;let t=e.trim();if(!t)return;let r=/^(\d{4})-(\d{2})-(\d{2})\s+(\d{2}):(\d{2}):(\d{2})$/.exec(t);if(!r)return;let n=Number(r[1]),i=Number(r[2]),o=Number(r[3]),l=Number(r[4]),d=Number(r[5]),a=Number(r[6]);if(!Number.isFinite(n)||!Number.isFinite(i)||!Number.isFinite(o)||!Number.isFinite(l)||!Number.isFinite(d)||!Number.isFinite(a))return;let s=new Date(n,i-1,o,l,d,a);if(Number.isNaN(s.getTime()))return;return s}function he(e){let t=(r)=>r.toString().padStart(2,"0");return`${e.getFullYear()}-${t(e.getMonth()+1)}-${t(e.getDate())} ${t(e.getHours())}:${t(e.getMinutes())}:${t(e.getSeconds())}`}function Xe(e){let t=(r)=>r.toString().padStart(2,"0");return`${e.getFullYear()}-${t(e.getMonth()+1)}-${t(e.getDate())} ${t(e.getHours())}:${t(e.getMinutes())}:${t(e.getSeconds())}`}async function _e(e){let t=await e.text(),r=H(t);return de(r,{code:W(r)??e.status,message:t||String(r||"")})}function Ct(e,t){return new C(e.code,e.message,{providerId:t,...e.details??{}})}async function _t(e){let{providerId:t,config:r,input:n}=e;if(!n||typeof n!=="object")return k(new C(z.INVALID_REQUEST,"Template input is required",{providerId:t}));let i=ht(n,{requireName:!0,requireContent:!0});if(i.isFailure)return k(Ct(i.error,t));let o=`${r.baseUrl}/api/template/add/`,l={templateName:i.value.name??n.name,templateContent:i.value.content??n.content,...i.value.buttons?{buttons:i.value.buttons}:{}};try{let d=await fetch(o,{method:"POST",headers:x(r),body:JSON.stringify(l)}),a=await _e(d),s=W(a.code)??d.status,p=typeof a.message==="string"&&a.message.length>0?a.message:"IWINV template create failed";if(!d.ok||s!==200)return k(new C(B(s),p,{providerId:t,originalCode:s}));let g=a.templateCode,u=typeof g==="string"&&g.trim().length>0?g.trim():"";if(!u)return k(new C(z.PROVIDER_ERROR,"IWINV template create did not return templateCode",{providerId:t,raw:a}));let c=new Date;return Ce({id:u,code:u,name:i.value.name??n.name,content:i.value.content??n.content,category:n.category,status:"INSPECTION",buttons:i.value.buttons,variables:n.variables,createdAt:c,updatedAt:c})}catch(d){return k(new C(z.NETWORK_ERROR,d instanceof Error?d.message:String(d),{providerId:t}))}}async function Ot(e){let{providerId:t,config:r,code:n,patch:i,ctx:o}=e,l=typeof n==="string"?n.trim():"";if(!l)return k(new C(z.INVALID_REQUEST,"code is required",{providerId:t}));let d=await He({providerId:t,config:r,code:l,ctx:o});if(d.isFailure)return d;let a=d.value,s=typeof i.name==="string"&&i.name.trim().length>0?i.name.trim():a.name,p=typeof i.content==="string"&&i.content.trim().length>0?i.content:a.content,g=i.buttons!==void 0?i.buttons:a.buttons,u=ht({name:s,content:p,buttons:g},{requireName:!0,requireContent:!0});if(u.isFailure)return k(Ct(u.error,t));let c=`${r.baseUrl}/api/template/modify/`,S={templateCode:l,templateName:u.value.name??s,templateContent:u.value.content??p,...u.value.buttons?{buttons:u.value.buttons}:{}};try{let f=await fetch(c,{method:"POST",headers:x(r),body:JSON.stringify(S)}),y=await _e(f),b=W(y.code)??f.status,m=typeof y.message==="string"&&y.message.length>0?y.message:"IWINV template update failed";if(!f.ok||b!==200)return k(new C(B(b),m,{providerId:t,originalCode:b}));let R=await He({providerId:t,config:r,code:l,ctx:o});if(R.isSuccess)return R;return Ce({...a,name:u.value.name??s,content:u.value.content??p,...i.category!==void 0?{category:i.category}:{},...i.variables!==void 0?{variables:i.variables}:{},...i.buttons!==void 0?{buttons:u.value.buttons}:{},updatedAt:new Date})}catch(f){return k(new C(z.NETWORK_ERROR,f instanceof Error?f.message:String(f),{providerId:t}))}}async function Dt(e){let{providerId:t,config:r,code:n}=e,i=typeof n==="string"?n.trim():"";if(!i)return k(new C(z.INVALID_REQUEST,"code is required",{providerId:t}));let o=`${r.baseUrl}/api/template/delete/`,l={templateCode:i};try{let d=await fetch(o,{method:"POST",headers:x(r),body:JSON.stringify(l)}),a=await _e(d),s=W(a.code)??d.status,p=typeof a.message==="string"&&a.message.length>0?a.message:typeof a.messgae==="string"&&a.messgae.length>0?a.messgae:"IWINV template delete failed";if(!d.ok||s!==200)return k(new C(B(s),p,{providerId:t,originalCode:s}));return Ce(void 0)}catch(d){return k(new C(z.NETWORK_ERROR,d instanceof Error?d.message:String(d),{providerId:t}))}}async function He(e){let{providerId:t,config:r,code:n}=e,i=typeof n==="string"?n.trim():"";if(!i)return k(new C(z.INVALID_REQUEST,"code is required",{providerId:t}));let o={pageNum:"1",pageSize:"15",templateCode:i},l=`${r.baseUrl}/api/template/`;try{let d=await fetch(l,{method:"POST",headers:x(r),body:JSON.stringify(o)}),a=await _e(d),s=W(a.code)??d.status,p=typeof a.message==="string"&&a.message.length>0?a.message:"IWINV template get failed";if(!d.ok||s!==200)return k(new C(B(s),p,{providerId:t,originalCode:s}));let g=a.list,c=(Array.isArray(g)?g:[]).find(v);if(!c)return k(new C(z.TEMPLATE_NOT_FOUND,"Template not found",{providerId:t,templateCode:i}));let S=c.templateCode,f=typeof S==="string"?S:String(S??""),y=typeof c.templateName==="string"?c.templateName:"",b=typeof c.templateContent==="string"?c.templateContent:"",m=Ye(c.status),R=Se(c.createDate)??new Date;return Ce({id:f,code:f,name:y,content:b,status:m,buttons:Array.isArray(c.buttons)?c.buttons:void 0,createdAt:R,updatedAt:R})}catch(d){return k(new C(z.NETWORK_ERROR,d instanceof Error?d.message:String(d),{providerId:t}))}}async function Mt(e){let{providerId:t,config:r,query:n}=e,i=typeof n?.page==="number"&&n.page>0?Math.floor(n.page):1,o=typeof n?.limit==="number"&&n.limit>0?Math.floor(n.limit):15,l=kt(n?.status),d={pageNum:String(i),pageSize:String(o),...l?{templateStatus:l}:{}},a=`${r.baseUrl}/api/template/`;try{let s=await fetch(a,{method:"POST",headers:x(r),body:JSON.stringify(d)}),p=await _e(s),g=W(p.code)??s.status,u=typeof p.message==="string"&&p.message.length>0?p.message:"IWINV template list failed";if(!s.ok||g!==200)return k(new C(B(g),u,{providerId:t,originalCode:g}));let c=p.list,f=(Array.isArray(c)?c:[]).filter(v).map((y)=>{let b=y.templateCode,m=typeof b==="string"?b:String(b??""),R=typeof y.templateName==="string"?y.templateName:"",N=typeof y.templateContent==="string"?y.templateContent:"",I=Ye(y.status),_=Se(y.createDate)??new Date;return{id:m,code:m,name:R,content:N,status:I,buttons:Array.isArray(y.buttons)?y.buttons:void 0,createdAt:_,updatedAt:_}}).filter((y)=>y.code.length>0);return Ce(f)}catch(s){return k(new C(z.NETWORK_ERROR,s instanceof Error?s.message:String(s),{providerId:t}))}}import{fail as X,KMsgError as K,KMsgErrorCode as F,ok as jt,readRuntimeEnv as Z}from"@k-msg/core";var Pt="https://alimtalk.bizservice.iwinv.kr",Lt="https://sms.bizservice.iwinv.kr";import{fail as $,KMsgError as j,KMsgErrorCode as G,ok as Te}from"@k-msg/core";import{KMsgErrorCode as Oe}from"@k-msg/core";function ee(e){return e.replace(/[^0-9]/g,"")}function te(){return Lt}function pe(e){if(e.smsApiKey&&e.smsAuthKey)return ke(`${e.smsApiKey}&${e.smsAuthKey}`);let t=e.smsAuthKey||e.smsApiKey;if(!t)return"";return ke(`${e.apiKey}&${t}`)}function ve(e){return pe(e).length>0}function Ze(e){if(typeof e==="number"&&Number.isFinite(e))return e.toString();if(typeof e==="string")return e.trim();return""}function et(e,t){return{"0":"전송 성공","1":"메시지가 전송되지 않았습니다.","11":"운영 중인 서비스가 아닙니다.","12":"요금제 충전 중입니다. 잠시 후 다시 시도해 보시기 바랍니다.","13":"등록되지 않은 발신번호입니다.","14":"인증 요청이 올바르지 않습니다.","15":"등록하지 않은 IP에서는 발송되지 않습니다.","21":"장문 메시지는 2000 Bytes까지만 입력이 가능합니다.","22":"제목 입력 가능 문자가 올바르지 않습니다.","23":"제목은 40 Byte까지만 입력이 가능합니다.","31":"파일 업로드는 100KB까지 가능합니다.","32":"허용되지 않는 파일 확장자입니다.","33":"이미지 업로드에 실패했습니다.","41":"수신 번호를 입력하여 주세요.","42":"예약 전송 가능 시간이 아닙니다.","43":"날짜와 시간 표현 형식에 맞춰 입력하여 주십시오.","44":"최대 1000건 전송 가능합니다.","50":"SMS 자동 충전 한도를 초과하였습니다.","202":"SMS API 인증 실패 또는 SMS 서비스 권한이 없습니다.","206":"등록하지 않은 IP에서는 발송되지 않습니다."}[e]||t}function tt(e,t){if(e==="14"||e==="15"||e==="202"||e==="206")return Oe.AUTHENTICATION_FAILED;if(e==="50")return Oe.INSUFFICIENT_BALANCE;if(e==="13"||e==="21"||e==="22"||e==="23"||e==="31"||e==="32"||e==="33"||e==="41"||e==="42"||e==="43"||e==="44")return Oe.INVALID_REQUEST;if(!t)return Oe.NETWORK_ERROR;return Oe.PROVIDER_ERROR}function rt(e,t){if(t&&t.trim().length>0)return t.trim();return e.slice(0,20)}function Kt(e,t){if(e==="06")return"DELIVERED";if(e==="1000")return"DELIVERED";if(typeof t==="string"){if(t.includes("전송 성공"))return"DELIVERED";if(t.includes("대기")||t.includes("처리중"))return"PENDING"}if(e==="00"||e==="01")return"PENDING";if(!e&&!t)return"UNKNOWN";return"FAILED"}async function Ft(e){let{providerId:t,config:r,query:n}=e,i=n.providerMessageId.trim();if(!i)return $(new j(G.INVALID_REQUEST,"providerMessageId is required",{providerId:t}));let o=ee(n.to);if(!o)return $(new j(G.INVALID_REQUEST,"to is required",{providerId:t}));let l=Number(i),d=Number.isFinite(l)?l:void 0,a=he(Je(n.requestedAt,-1)),s=he(new Date),p={pageNum:1,pageSize:15,phone:o,startDate:a,endDate:s,...d!==void 0?{seqNo:d}:{},...n.scheduledAt instanceof Date&&!Number.isNaN(n.scheduledAt.getTime())?{reserve:"Y"}:{}},g=`${r.baseUrl}/api/history/`;try{let u=await fetch(g,{method:"POST",headers:x(r),body:JSON.stringify(p)}),c=await u.text(),S=H(c),f=de(S,{}),y=f.code,b=typeof y==="number"?y:void 0,m=typeof f.message==="string"&&f.message.length>0?f.message:"IWINV history query failed";if(!u.ok||b!==200)return $(new j(B(b??W(S)??u.status),m,{providerId:t,originalCode:y??u.status}));let R=f.list,N=Array.isArray(R)?R:[];if(N.length===0)return Te(null);let I=(()=>{if(d===void 0)return N[0];return N.find((A)=>v(A)&&A.seqNo===d)??N[0]})();if(!v(I))return Te(null);let _=typeof I.statusCode==="string"?I.statusCode:void 0,O=typeof I.statusCodeName==="string"?I.statusCodeName:void 0,E=Se(I.sendDate),ie=Se(I.receiveDate),J=_==="OK"||typeof O==="string"&&O.includes("성공");return Te({providerId:t,providerMessageId:i,status:J?"DELIVERED":E?"FAILED":"PENDING",statusCode:_,statusMessage:O,sentAt:E,deliveredAt:J?ie||E:void 0,failedAt:!J&&E?E:void 0,raw:I})}catch(u){return $(new j(G.NETWORK_ERROR,u instanceof Error?u.message:String(u),{providerId:t}))}}async function Vt(e){let{providerId:t,config:r,query:n}=e;if(!ve(r))return $(new j(G.INVALID_REQUEST,"SMS v2 configuration missing (smsApiKey/smsAuthKey)",{providerId:t}));if(!r.smsCompanyId||r.smsCompanyId.length===0)return $(new j(G.INVALID_REQUEST,"smsCompanyId required for history (config.smsCompanyId)",{providerId:t}));let i=n.providerMessageId.trim();if(!i)return $(new j(G.INVALID_REQUEST,"providerMessageId is required",{providerId:t}));let o=ee(n.to);if(!o)return $(new j(G.INVALID_REQUEST,"to is required",{providerId:t}));let l=Je(n.requestedAt,-1),d=new Date;if(d.getTime()-l.getTime()>7776000000)return $(new j(G.INVALID_REQUEST,"SMS history date range must be within 90 days",{providerId:t}));let p={version:"1.0",companyid:r.smsCompanyId,startDate:Ge(l),endDate:Ge(d),requestNo:i,pageNum:1,pageSize:15,phone:o},u={"Content-Type":"application/json;charset=UTF-8",secret:pe(r)};if(typeof r.xForwardedFor==="string"&&r.xForwardedFor.length>0)u["X-Forwarded-For"]=r.xForwardedFor;let c=r.extraHeaders&&typeof r.extraHeaders==="object"?{...u,...r.extraHeaders}:u,S=`${te()}/api/history/`;try{let f=await fetch(S,{method:"POST",headers:c,body:JSON.stringify(p)}),y=await f.text(),b=H(y),m=de(b,{}),R=m.resultCode,N=typeof R==="number"?R:typeof R==="string"?Number(R):NaN,I=typeof m.message==="string"&&m.message.length>0?m.message:"IWINV SMS history query failed";if(!f.ok||N!==0)return $(new j(G.PROVIDER_ERROR,I,{providerId:t,originalCode:R??f.status}));let _=m.list,O=Array.isArray(_)?_:[];if(O.length===0)return Te(null);let E=(()=>{return O.find((ue)=>{if(!v(ue))return!1;let Q=ue.requestNo;return Q!==void 0&&Q!==null?String(Q)===i:!1})??O[0]})();if(!v(E))return Te(null);let ie=typeof E.sendStatusCode==="string"?E.sendStatusCode:void 0,J=typeof E.sendStatusMsg==="string"?E.sendStatusMsg:typeof E.sendStatus==="string"?E.sendStatus:void 0,be=Se(E.sendDate),A=Kt(ie,J);return Te({providerId:t,providerMessageId:i,status:A,statusCode:ie,statusMessage:J,sentAt:be,deliveredAt:A==="DELIVERED"?be:void 0,failedAt:A==="FAILED"?be:void 0,raw:E})}catch(f){return $(new j(G.NETWORK_ERROR,f instanceof Error?f.message:String(f),{providerId:t}))}}import{fail as h,KMsgError as w,KMsgErrorCode as P,ok as ot}from"@k-msg/core";import{fail as Ut,KMsgError as qt,KMsgErrorCode as Ht,ok as nt}from"@k-msg/core";function xt(e){let t=e.split(/[?#]/,1)[0]??e,r=t.lastIndexOf(".");if(r<=0||r===t.length-1)return"";return t.slice(r).toLowerCase()}function it(e){switch(xt(e)){case".jpg":case".jpeg":return"image/jpeg";case".png":return"image/png";case".gif":return"image/gif";case".webp":return"image/webp";default:return}}function Bt(e,t){let r=e&&typeof e==="object"?e:{},i=(r.media&&typeof r.media==="object"?r.media:void 0)?.image;if(i&&typeof i==="object"){if(i.bytes instanceof Uint8Array)return nt({bytes:i.bytes,filename:typeof i.filename==="string"?i.filename:void 0,contentType:typeof i.contentType==="string"?i.contentType:void 0});if(i.blob instanceof Blob)return nt({blob:i.blob,filename:typeof i.filename==="string"?i.filename:void 0,contentType:typeof i.contentType==="string"?i.contentType:void 0});if(typeof i.ref==="string"&&i.ref.trim().length>0)return Ut(new qt(Ht.INVALID_REQUEST,"IWINV MMS caller must provide blob/bytes in options.media.image",{providerId:t,field:"media.image.ref"}))}let o=r.imageUrl;if(typeof o==="string"&&o.trim().length>0)return Ut(new qt(Ht.INVALID_REQUEST,"IWINV MMS caller must provide blob/bytes in options.media.image",{providerId:t,field:"imageUrl"}));return nt(void 0)}async function Qt(e){if("blob"in e){let o=e.contentType||e.blob.type||"application/octet-stream",l=e.filename||"image",d=e.contentType&&e.contentType!==e.blob.type?new Blob([await e.blob.arrayBuffer()],{type:o}):e.blob;return{blob:d,filename:l,contentType:o,size:d.size}}let t=e.contentType||"application/octet-stream",r=new Uint8Array(e.bytes.byteLength);r.set(e.bytes);let n=new Blob([r],{type:t}),i=e.filename||"image";return{blob:n,filename:i,contentType:t,size:n.size}}function Wt(e){if(xt(e.filename).length>0)return e.filename;let r=it(e.filename)==="image/png"?".png":it(e.filename)==="image/gif"?".gif":it(e.filename)==="image/webp"?".webp":e.contentType==="image/png"?".png":e.contentType==="image/gif"?".gif":e.contentType==="image/webp"?".webp":".jpg";return`${e.filename}${r}`}async function zt(e){let{providerId:t,config:r,options:n}=e,i=n.templateId;if(!i||i.length===0)return h(new w(P.INVALID_REQUEST,"templateId is required for ALIMTALK",{providerId:t}));let o=n.options?.scheduledAt,l=o instanceof Date&&!Number.isNaN(o.getTime()),d=l?"Y":"N",a=l?he(o):void 0,s=ee(n.to);if(!s)return h(new w(P.INVALID_REQUEST,"to is required",{providerId:t}));let p=n.providerOptions?.templateParam,g=Array.isArray(p)?p.map((A)=>A===null||A===void 0?"":String(A)):Object.values(n.variables||{}).map((A)=>A===null||A===void 0?"":String(A)),u=n.failover,c=(typeof n.from==="string"&&n.from.length>0?n.from:r.senderNumber||r.smsSenderNumber)||"",S=c?ee(c):"",f=typeof n.providerOptions?.reSend==="string"?n.providerOptions.reSend.trim().toUpperCase():"",y=f==="Y"||f==="N"?f:void 0,b=u?.enabled===!0?"Y":u?.enabled===!1?"N":void 0,m=y??b??(S?"Y":"N"),N=(typeof n.providerOptions?.resendCallback==="string"?ee(n.providerOptions.resendCallback):"")||S;if(m==="Y"&&!N)return h(new w(P.INVALID_REQUEST,"resendCallback is required when reSend is 'Y' (options.from or providerOptions.resendCallback)",{providerId:t}));let I=typeof n.providerOptions?.resendType==="string"?n.providerOptions.resendType.trim().toUpperCase():"",_=I==="Y"||I==="N"?I:void 0;if(typeof n.providerOptions?.resendType==="string"&&n.providerOptions.resendType.length>0&&!_)return h(new w(P.INVALID_REQUEST,"resendType must be 'Y' or 'N'",{providerId:t}));let O=u?.fallbackChannel==="lms"?"Y":u?.fallbackChannel==="sms"?"N":void 0,E=typeof n.providerOptions?.resendTitle==="string"&&n.providerOptions.resendTitle.trim().length>0?n.providerOptions.resendTitle.trim():typeof u?.fallbackTitle==="string"&&u.fallbackTitle.trim().length>0?u.fallbackTitle.trim():void 0,ie=typeof n.providerOptions?.resendContent==="string"&&n.providerOptions.resendContent.trim().length>0?n.providerOptions.resendContent.trim():typeof u?.fallbackContent==="string"&&u.fallbackContent.trim().length>0?u.fallbackContent.trim():void 0,J={templateCode:i,reserve:d,...a?{sendDate:a}:{},list:[{phone:s,templateParam:g.length>0?g:void 0}],reSend:m,...N?{resendCallback:N}:{},..._??O?{resendType:_??O}:{},...E?{resendTitle:E}:{},...ie?{resendContent:ie}:{}},be=`${r.baseUrl}${wt(r)}`;try{let A=await fetch(be,{method:"POST",headers:x(r),body:JSON.stringify(J)}),xe=await A.text(),ue=H(xe),Q=v(ue)?ue:{code:W(ue)??A.status,message:xe||String(ue||"")};if(!A.ok||Q.code!==200)return h(new w(B(Q.code),Q.message||"IWINV send failed",{providerId:t,originalCode:Q.code}));return ot({messageId:n.messageId||crypto.randomUUID(),providerId:t,providerMessageId:typeof Q.seqNo==="number"?String(Q.seqNo):void 0,status:l?"PENDING":"SENT",type:n.type,to:n.to,raw:Q})}catch(A){return h(new w(P.NETWORK_ERROR,A instanceof Error?A.message:String(A),{providerId:t}))}}async function cr(e){let{providerId:t,config:r,options:n,to:i,from:o,text:l,scheduledAtValid:d,scheduledAt:a}=e;if(n.type!=="MMS")return h(new w(P.INVALID_REQUEST,"IWINVProvider: MMS handler called with non-MMS options",{providerId:t,type:n.type}));let s=rt(l,n.subject),p=Bt(n,t);if(p.isFailure)return p;let g=p.value;if(!g)return h(new w(P.INVALID_REQUEST,"image is required for MMS; caller must provide options.media.image.blob or bytes",{providerId:t}));let u;try{u=await Qt(g)}catch(m){return h(m instanceof w?m:new w(P.NETWORK_ERROR,m instanceof Error?m.message:String(m),{providerId:t}))}if(u.size>102400)return h(new w(P.INVALID_REQUEST,"MMS image must be <= 100KB",{providerId:t,bytes:u.size}));let c=new FormData;if(c.append("version","1.0"),c.append("from",o),c.append("to",i),c.append("title",s),c.append("text",l),d&&a)c.append("date",Xe(a));c.append("image",u.blob,Wt(u));let f={secret:pe(r)};if(typeof r.xForwardedFor==="string"&&r.xForwardedFor.length>0)f["X-Forwarded-For"]=r.xForwardedFor;let y={...f};if(r.extraHeaders&&typeof r.extraHeaders==="object")for(let[m,R]of Object.entries(r.extraHeaders)){if(m.toLowerCase()==="content-type")continue;y[m]=R}let b=`${te()}/api/v2/send/`;try{let m=await fetch(b,{method:"POST",headers:y,body:c}),R=await m.text(),N=H(R),I=v(N)?N:{resultCode:N},_=I.resultCode??I.code,O=Ze(_),E=typeof I.message==="string"&&I.message.length>0?I.message:et(O,"MMS send failed");if(!(m.ok&&O==="0"))return h(new w(tt(O,m.ok),E,{providerId:t,originalCode:_}));let J=typeof I.requestNo==="string"&&I.requestNo.length>0?I.requestNo:typeof I.msgid==="string"&&I.msgid.length>0?I.msgid:void 0;return ot({messageId:n.messageId||crypto.randomUUID(),providerId:t,providerMessageId:J,status:d?"PENDING":"SENT",type:n.type,to:n.to,raw:I})}catch(m){return h(new w(P.NETWORK_ERROR,m instanceof Error?m.message:String(m),{providerId:t}))}}async function $t(e){let{providerId:t,config:r,options:n}=e;if(!ve(r))return h(new w(P.INVALID_REQUEST,"SMS v2 configuration missing (smsApiKey/smsAuthKey)",{providerId:t}));let i=ee(n.to);if(!i)return h(new w(P.INVALID_REQUEST,"to is required",{providerId:t}));let o=n.text;if(!o||o.trim().length===0)return h(new w(P.INVALID_REQUEST,"text is required for SMS/LMS/MMS",{providerId:t}));let l=(typeof n.from==="string"&&n.from.length>0?n.from:r.smsSenderNumber||r.senderNumber)||"",d=l?ee(l):"";if(!d)return h(new w(P.INVALID_REQUEST,"from is required for SMS/LMS/MMS (options.from or config.smsSenderNumber)",{providerId:t}));let a=n.options?.scheduledAt,s=a instanceof Date&&!Number.isNaN(a.getTime());if(n.type==="MMS")return await cr({providerId:t,config:r,options:n,to:i,from:d,text:o,scheduledAtValid:s,scheduledAt:s?a:void 0});let p={version:"1.0",from:d,to:[i],text:o};if(n.type==="LMS")p.title=rt(o,n.subject);else{let f=typeof n.providerOptions?.msgType==="string"&&n.providerOptions.msgType.trim().length>0?n.providerOptions.msgType.trim():void 0;p.msgType=f||n.type}if(s)p.date=Xe(a);let u={"Content-Type":"application/json;charset=UTF-8",secret:pe(r)};if(typeof r.xForwardedFor==="string"&&r.xForwardedFor.length>0)u["X-Forwarded-For"]=r.xForwardedFor;let c=r.extraHeaders&&typeof r.extraHeaders==="object"?{...u,...r.extraHeaders}:u,S=`${te()}/api/v2/send/`;try{let f=await fetch(S,{method:"POST",headers:c,body:JSON.stringify(p)}),y=await f.text(),b=H(y),m=v(b)?b:{resultCode:b},R=m.resultCode??m.code,N=Ze(R),I=typeof m.message==="string"&&m.message.length>0?m.message:et(N,"SMS send failed");if(!(f.ok&&N==="0"))return h(new w(tt(N,f.ok),I,{providerId:t,originalCode:R}));let O=typeof m.requestNo==="string"&&m.requestNo.length>0?m.requestNo:typeof m.msgid==="string"&&m.msgid.length>0?m.msgid:void 0;return ot({messageId:n.messageId||crypto.randomUUID(),providerId:t,providerMessageId:O,status:s?"PENDING":"SENT",type:n.type,to:n.to,raw:m})}catch(f){return h(new w(P.NETWORK_ERROR,f instanceof Error?f.message:String(f),{providerId:t}))}}function gr(e){return{...e,baseUrl:Pt,sendEndpoint:e.sendEndpoint||"/api/v2/send/"}}function st(){return{apiKey:Z("IWINV_API_KEY")||"",smsApiKey:Z("IWINV_SMS_API_KEY"),smsAuthKey:Z("IWINV_SMS_AUTH_KEY"),smsCompanyId:Z("IWINV_SMS_COMPANY_ID"),senderNumber:Z("IWINV_SENDER_NUMBER")||Z("IWINV_SMS_SENDER_NUMBER"),smsSenderNumber:Z("IWINV_SMS_SENDER_NUMBER"),sendEndpoint:Z("IWINV_SEND_ENDPOINT")||"/api/v2/send/",xForwardedFor:Z("IWINV_X_FORWARDED_FOR"),debug:Z("NODE_ENV")==="development"}}class Ne{id="iwinv";name="IWINV Messaging Provider";supportedTypes;config;getOnboardingSpec(){let e=ye(this.id);if(!e)throw new K(F.INVALID_REQUEST,`Onboarding spec missing for provider: ${this.id}`,{providerId:this.id});return e}constructor(e){if(!e||typeof e!=="object")throw new K(F.INVALID_REQUEST,"IWINVProvider requires a config object",{providerId:this.id});if(!e.apiKey||e.apiKey.length===0)throw new K(F.INVALID_REQUEST,"IWINVProvider requires `apiKey` configuration",{providerId:this.id});this.config=gr(e);let t=["ALIMTALK"];if(ve(this.config))t.push("SMS","LMS","MMS");this.supportedTypes=t}async healthCheck(){let e=Date.now(),t=[];try{try{new URL(this.config.baseUrl)}catch{t.push("Invalid baseUrl")}if(ve(this.config))try{new URL(te())}catch{t.push("Invalid smsBaseUrl")}return{healthy:t.length===0,issues:t,latencyMs:Date.now()-e,data:{provider:this.id,baseUrl:this.config.baseUrl,smsBaseUrl:te()}}}catch(r){return t.push(r instanceof Error?r.message:String(r)),{healthy:!1,issues:t,latencyMs:Date.now()-e}}}async send(e){let t=e.messageId||crypto.randomUUID(),r={...e,messageId:t};switch(r.type){case"ALIMTALK":return zt({providerId:this.id,config:this.config,options:r});case"SMS":case"LMS":case"MMS":return $t({providerId:this.id,config:this.config,options:r});default:return X(new K(F.INVALID_REQUEST,`IWINVProvider does not support type ${r.type}`,{providerId:this.id,type:r.type}))}}async getDeliveryStatus(e){switch(e.type){case"ALIMTALK":return Ft({providerId:this.id,config:this.config,query:e});case"SMS":case"LMS":case"MMS":return Vt({providerId:this.id,config:this.config,query:e});default:return X(new K(F.INVALID_REQUEST,`IWINVProvider does not support type ${e.type}`,{providerId:this.id,type:e.type}))}}async getBalance(e){let t=e?.channel??"ALIMTALK";switch(t){case"ALIMTALK":return this.getAlimTalkBalance(t);case"SMS":case"LMS":case"MMS":return this.getSmsBalance(t);default:return X(new K(F.INVALID_REQUEST,`IWINVProvider does not support balance query for type ${t}`,{providerId:this.id,type:t}))}}async getAlimTalkBalance(e){let t=`${this.config.baseUrl}/api/charge/`;try{let r=await fetch(t,{method:"POST",headers:x(this.config),body:JSON.stringify({})}),n=await r.text(),i=H(n),o=de(i,{}),l=o.code,d=typeof l==="string"?Number(l):void 0,a=typeof l==="number"?l:typeof d==="number"&&Number.isFinite(d)?d:void 0,s=typeof o.message==="string"&&o.message.length>0?o.message:"IWINV AlimTalk charge query failed";if(!r.ok||a!==200)return X(new K(B(a??r.status),s,{providerId:this.id,originalCode:l??r.status}));let p=o.charge,g=typeof p==="number"?p:typeof p==="string"?Number(p):NaN;if(!Number.isFinite(g))return X(new K(F.PROVIDER_ERROR,"Invalid charge value from IWINV AlimTalk charge API",{providerId:this.id,raw:o}));return jt({providerId:this.id,channel:e,amount:g,currency:"KRW",raw:o})}catch(r){return X(new K(F.NETWORK_ERROR,r instanceof Error?r.message:String(r),{providerId:this.id}))}}async getSmsBalance(e){if(!this.config.smsApiKey||!this.config.smsAuthKey)return X(new K(F.INVALID_REQUEST,"smsApiKey and smsAuthKey are required for SMS/LMS/MMS balance query",{providerId:this.id}));let r={"Content-Type":"application/json;charset=UTF-8",secret:pe(this.config)};if(typeof this.config.xForwardedFor==="string"&&this.config.xForwardedFor.length>0)r["X-Forwarded-For"]=this.config.xForwardedFor;let n=this.config.extraHeaders&&typeof this.config.extraHeaders==="object"?{...r,...this.config.extraHeaders}:r,i=`${te()}/api/charge/`;try{let o=await fetch(i,{method:"POST",headers:n,body:JSON.stringify({version:"1.0"})}),l=await o.text(),d=H(l),a=de(d,{}),s=a.code??a.resultCode,p=typeof s==="string"?Number(s):void 0,g=typeof s==="number"?s:typeof p==="number"&&Number.isFinite(p)?p:NaN,u=typeof a.message==="string"&&a.message.length>0?a.message:"IWINV SMS charge query failed";if(!o.ok||g!==0)return X(new K(F.PROVIDER_ERROR,u,{providerId:this.id,originalCode:s??o.status}));let c=a.charge,S=typeof c==="number"?c:typeof c==="string"?Number(c):NaN;if(!Number.isFinite(S))return X(new K(F.PROVIDER_ERROR,"Invalid charge value from IWINV SMS charge API",{providerId:this.id,raw:a}));return jt({providerId:this.id,channel:e,amount:S,currency:"KRW",raw:a})}catch(o){return X(new K(F.NETWORK_ERROR,o instanceof Error?o.message:String(o),{providerId:this.id}))}}}var ei=(e)=>new Ne(e),yr=()=>{let e=st();if(!e.apiKey)throw new K(F.INVALID_REQUEST,"IWINV_API_KEY environment variable is required",{providerId:"iwinv"});return new Ne(e)};class Ir{static create(e){return new Ne(e)}static createDefault(){return yr()}}class De extends Ne{async createTemplate(e,t){return _t({providerId:this.id,config:this.config,input:e})}async updateTemplate(e,t,r){return Ot({providerId:this.id,config:this.config,code:e,patch:t,ctx:r})}async deleteTemplate(e,t){return Dt({providerId:this.id,config:this.config,code:e})}async getTemplate(e,t){return He({providerId:this.id,config:this.config,code:e,ctx:t})}async listTemplates(e,t){return Mt({providerId:this.id,config:this.config,query:e,ctx:t})}}var Sr=(e)=>new De(e),Yt=()=>{let e=st();return new De(e)};class Jt{static create(e){return new De(e)}static createDefault(){return Yt()}}function vr(){}var br={mock:{label:"Mock (local test)",routingSeedTypes:["ALIMTALK","FRIENDTALK","SMS","LMS","MMS","NSA","VOICE","FAX","RCS_SMS","RCS_LMS","RCS_MMS","RCS_TPL","RCS_ITPL","RCS_LTPL"],defaultKakaoSenderKey:"env:MOCK_SENDER_KEY"},aligo:{label:"Aligo",routingSeedTypes:["ALIMTALK","FRIENDTALK","SMS","LMS","MMS"],defaultKakaoSenderKey:"env:ALIGO_SENDER_KEY"},iwinv:{label:"IWINV",routingSeedTypes:["ALIMTALK","SMS","LMS","MMS"]},solapi:{label:"SOLAPI",routingSeedTypes:["ALIMTALK","FRIENDTALK","SMS","LMS","MMS","NSA","VOICE","FAX","RCS_SMS","RCS_LMS","RCS_MMS","RCS_TPL","RCS_ITPL","RCS_LTPL"],defaultKakaoSenderKey:"env:SOLAPI_KAKAO_PF_ID"}};import{fail as re,KMsgError as ne,KMsgErrorCode as T,ok as Y}from"@k-msg/core";var Gt=(e)=>new Promise((t)=>{setTimeout(t,Math.max(0,Math.floor(e)))}),Rr=(e)=>{if(e===T.INVALID_REQUEST||e===T.AUTHENTICATION_FAILED||e===T.INSUFFICIENT_BALANCE||e===T.TEMPLATE_NOT_FOUND||e===T.RATE_LIMIT_EXCEEDED||e===T.NETWORK_ERROR||e===T.NETWORK_TIMEOUT||e===T.NETWORK_SERVICE_UNAVAILABLE||e===T.PROVIDER_ERROR||e===T.MESSAGE_SEND_FAILED||e===T.UNKNOWN_ERROR)return e;return T.PROVIDER_ERROR};class Xt{id="mock";name="Mock Provider";supportedTypes=["ALIMTALK","FRIENDTALK","SMS","LMS","MMS","NSA","VOICE","FAX","RCS_SMS","RCS_LMS","RCS_MMS","RCS_TPL","RCS_ITPL","RCS_LTPL"];calls=[];failureCount=0;scenario=[];scenarioCursor=0;templates=new Map;templateSeq=0;channelSeq=0;kakaoChannels=new Map;getOnboardingSpec(){let e=ye(this.id);if(!e)throw Error(`Onboarding spec missing for provider: ${this.id}`);return e}constructor(){let e=new Date,t={id:"MOCK_TPL_SEED",code:"MOCK_TPL_SEED",name:"Mock Seed Template",content:"Hello #{name}",status:"APPROVED",createdAt:e,updatedAt:e};this.templates.set(t.code,t);let r={providerId:this.id,senderKey:"mock-sender-seed",plusId:"@mock",name:"Mock Seed Channel",status:"A",createdAt:e,updatedAt:e};this.kakaoChannels.set(r.senderKey,r)}async healthCheck(){return{healthy:!0,issues:[]}}async send(e){this.calls.push(e);let t=this.nextScenarioOutcome();while(t.outcome==="delay")await Gt(t.durationMs??0),t=this.nextScenarioOutcome();if(t.outcome==="timeout")return await Gt(t.durationMs??0),re(new ne(T.NETWORK_TIMEOUT,t.message??"Mock provider simulated timeout",{provider:this.id},{providerErrorCode:t.providerErrorCode??"TIMEOUT",providerErrorText:t.providerErrorText,httpStatus:t.httpStatus,retryAfterMs:t.retryAfterMs}));if(t.outcome==="failure"){let n=Rr(t.code);return re(new ne(n,t.message??"Mock provider simulated failure",{provider:this.id},{providerErrorCode:t.providerErrorCode,providerErrorText:t.providerErrorText,httpStatus:t.httpStatus,retryAfterMs:t.retryAfterMs,causeChain:t.causeChain}))}if(t.outcome!=="success")return re(new ne(T.UNKNOWN_ERROR,`Unsupported mock outcome: ${String(t.outcome)}`,{provider:this.id}));let r={messageId:e.messageId||crypto.randomUUID(),status:"SENT",providerId:this.id,providerMessageId:`mock-${Date.now()}-${Math.random().toString(36).substring(2,11)}`,type:e.type,to:e.to,...e.type==="ALIMTALK"&&e.failover?.enabled===!0?{warnings:[{code:"FAILOVER_UNSUPPORTED_PROVIDER",message:"Mock provider does not support native ALIMTALK failover.",details:{providerId:this.id}}]}:{}};return Y(r)}mockSuccess(){this.failureCount=0,this.clearScenario()}mockFailure(e){this.failureCount=e,this.clearScenario()}mockScenario(e){this.scenario=Array.isArray(e)?e.slice():[],this.scenarioCursor=0}clearScenario(){this.scenario=[],this.scenarioCursor=0}nextScenarioOutcome(){if(this.scenarioCursor<this.scenario.length){let e=this.scenario[this.scenarioCursor];return this.scenarioCursor+=1,e}if(this.failureCount>0)return this.failureCount-=1,{outcome:"failure",code:T.PROVIDER_ERROR,message:"Mock provider simulated failure"};return{outcome:"success"}}getHistory(){return this.calls}clearHistory(){this.calls=[]}async createTemplate(e,t){this.templateSeq+=1;let r=`MOCK_TPL_${this.templateSeq}`,n={id:r,code:r,name:e.name,content:e.content,category:e.category,buttons:e.buttons,variables:e.variables,status:"APPROVED",createdAt:new Date,updatedAt:new Date};return this.templates.set(n.code,n),Y(n)}async updateTemplate(e,t,r){let n=this.templates.get(e);if(!n)return re(new ne(T.TEMPLATE_NOT_FOUND,`Template not found: ${e}`));let i={...n,...typeof t.name==="string"?{name:t.name}:{},...typeof t.content==="string"?{content:t.content}:{},...t.category!==void 0?{category:t.category}:{},...t.buttons!==void 0?{buttons:t.buttons}:{},...t.variables!==void 0?{variables:t.variables}:{},updatedAt:new Date};return this.templates.set(e,i),Y(i)}async deleteTemplate(e,t){if(!this.templates.has(e))return re(new ne(T.TEMPLATE_NOT_FOUND,`Template not found: ${e}`));return this.templates.delete(e),Y(void 0)}async getTemplate(e,t){let r=this.templates.get(e);if(!r)return re(new ne(T.TEMPLATE_NOT_FOUND,`Template not found: ${e}`));return Y(r)}async listTemplates(e,t){let r=Array.from(this.templates.values());if(e?.status)r=r.filter((d)=>d.status===e.status);let n=e?.page||1,i=e?.limit||10,o=(n-1)*i,l=o+i;return Y(r.slice(o,l))}async requestTemplateInspection(e,t){if(!this.templates.has(e))return re(new ne(T.TEMPLATE_NOT_FOUND,`Template not found: ${e}`));return Y(void 0)}async listKakaoChannels(e){let t=Array.from(this.kakaoChannels.values());if(e?.plusId)t=t.filter((r)=>r.plusId===e.plusId);if(e?.senderKey)t=t.filter((r)=>r.senderKey===e.senderKey);return Y(t)}async listKakaoChannelCategories(){return Y({first:[{code:"001",name:"Mock First"}],second:[{code:"001001",name:"Mock Second",parentCode:"001"}],third:[{code:"001001001",name:"Mock Third",parentCode:"001001"}]})}async requestKakaoChannelAuth(e){if(!e.plusId||!e.phoneNumber)return re(new ne(T.INVALID_REQUEST,"plusId and phoneNumber are required",{providerId:this.id}));return Y(void 0)}async addKakaoChannel(e){if(!e.plusId||!e.authNum||!e.phoneNumber||!e.categoryCode)return re(new ne(T.INVALID_REQUEST,"plusId, authNum, phoneNumber, categoryCode are required",{providerId:this.id}));this.channelSeq+=1;let t=`mock-sender-${this.channelSeq}`,r={providerId:this.id,senderKey:t,plusId:e.plusId,name:"Mock Channel",status:"A",createdAt:new Date,updatedAt:new Date};return this.kakaoChannels.set(t,r),Y(r)}}export{ze as providerOnboardingSpecs,fr as providerConfigFieldSpecs,br as providerCliMetadata,nr as listProviderOnboardingSpecs,vr as initializeIWINV,ur as initializeAligo,ye as getProviderOnboardingSpec,Sr as createIWINVProvider,Yt as createDefaultIWINVProvider,Nt as createDefaultAligoProvider,pr as createAligoProvider,Xt as MockProvider,Jt as IWINVProviderFactory,De as IWINVProvider,Et as AligoProviderFactory,we as AligoProvider};
|
|
3
3
|
|
|
4
|
-
//# debugId=
|
|
4
|
+
//# debugId=614A8E193FA2E31864756E2164756E21
|
|
5
5
|
//# sourceMappingURL=index.mjs.map
|
package/dist/iwinv/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var{defineProperty:te,getOwnPropertyNames:_e,getOwnPropertyDescriptor:Ve}=Object,Pe=Object.prototype.hasOwnProperty;var ue=new WeakMap,Me=(e)=>{var t=ue.get(e),n;if(t)return t;if(t=te({},"__esModule",{value:!0}),e&&typeof e==="object"||typeof e==="function")_e(e).map((r)=>!Pe.call(t,r)&&te(t,r,{get:()=>e[r],enumerable:!(n=Ve(e,r))||n.enumerable}));return ue.set(e,t),t};var Fe=(e,t)=>{for(var n in t)te(e,n,{get:t[n],enumerable:!0,configurable:!0,set:(r)=>t[n]=()=>r})};var He={};Fe(He,{default:()=>Q,IWINV_STATUS_CODES:()=>ze,IWINVProvider:()=>Q});module.exports=Me(He);var c=require("@k-msg/core");var me={iwinv:{providerId:"iwinv",providerName:"IWINV Messaging Provider",channelOnboarding:"manual",templateLifecycleApi:"available",plusIdPolicy:"optional",plusIdInference:"unsupported",liveTestSupport:"supported",checks:[{id:"channel_registered_in_console",title:"Kakao channel is registered in IWINV console",description:"IWINV channel onboarding is manual. Confirm channel registration and approval in console.",kind:"manual",severity:"blocker",scopes:["doctor","preflight"]},{id:"iwinv_config_required",title:"IWINV config has required keys",kind:"config",severity:"blocker",scopes:["doctor","preflight"],configKeys:["apiKey"]},{id:"template_capability_available",title:"Template lifecycle APIs are available",kind:"capability",severity:"warning",scopes:["doctor","preflight"],capabilityMethods:["listTemplates","getTemplate","createTemplate","updateTemplate","deleteTemplate"]},{id:"template_list_probe",title:"Template list API probe",kind:"api_probe",severity:"warning",scopes:["doctor","preflight"],probeOperation:"list_templates"}],notes:["Channel add/auth is not available via IWINV public API in current integration.","Template APIs are available and can be probed."]},aligo:{providerId:"aligo",providerName:"Aligo Smart SMS",channelOnboarding:"api",templateLifecycleApi:"available",plusIdPolicy:"required_if_no_inference",plusIdInference:"supported",liveTestSupport:"supported",checks:[{id:"aligo_config_required",title:"Aligo config has required keys",kind:"config",severity:"blocker",scopes:["doctor","preflight"],configKeys:["apiKey","userId"]},{id:"channel_api_capability_available",title:"Kakao channel APIs are available",kind:"capability",severity:"warning",scopes:["doctor","preflight"],capabilityMethods:["listKakaoChannels","requestKakaoChannelAuth","addKakaoChannel"]},{id:"channel_list_probe",title:"Kakao channel list API probe",kind:"api_probe",severity:"warning",scopes:["doctor","preflight"],probeOperation:"list_kakao_channels"},{id:"template_list_probe",title:"Template list API probe",kind:"api_probe",severity:"warning",scopes:["doctor","preflight"],probeOperation:"list_templates"}]},solapi:{providerId:"solapi",providerName:"SOLAPI Messaging Provider",channelOnboarding:"none",templateLifecycleApi:"unavailable",plusIdPolicy:"required_if_no_inference",plusIdInference:"unsupported",liveTestSupport:"partial",checks:[{id:"solapi_config_required",title:"SOLAPI config has required keys",kind:"config",severity:"blocker",scopes:["doctor","preflight"],configKeys:["apiKey","apiSecret"]}],notes:["SOLAPI ALIMTALK requires kakao profileId/pfId, but plusId inference is not available in current integration."]},mock:{providerId:"mock",providerName:"Mock Provider",channelOnboarding:"api",templateLifecycleApi:"available",plusIdPolicy:"optional",plusIdInference:"supported",liveTestSupport:"none",checks:[{id:"mock_template_capability_available",title:"Mock template APIs are available",kind:"capability",severity:"info",scopes:["doctor","preflight"],capabilityMethods:["listTemplates","getTemplate","createTemplate"]}]}};function fe(e){return me[e]}function $e(){return Object.values(me)}function O(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function k(e){if(!e)return{};try{return JSON.parse(e)}catch{return e}}function z(e,t){return O(e)?e:t}var L=require("@k-msg/core");function Le(e){let t="",n=0;while(n<e.length){let r=e[n++]??0,s=e[n++]??0,d=e[n++]??0,u=r<<16|s<<8|d;t+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[u>>18&63],t+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[u>>12&63],t+=n-2<e.length?"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[u>>6&63]:"=",t+=n-1<e.length?"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[u&63]:"="}return t}function J(e){return Le(new TextEncoder().encode(e))}function ge(e){let t=e.sendEndpoint||"/api/v2/send/";return t.startsWith("/")?t:`/${t}`}function _(e){let n={AUTH:J(e.apiKey),"Content-Type":"application/json;charset=UTF-8"};if(typeof e.xForwardedFor==="string"&&e.xForwardedFor.length>0)n["X-Forwarded-For"]=e.xForwardedFor;if(e.extraHeaders&&typeof e.extraHeaders==="object")return{...n,...e.extraHeaders};return n}function V(e){switch(e){case 201:case 206:case 401:case 403:return L.KMsgErrorCode.AUTHENTICATION_FAILED;case 429:return L.KMsgErrorCode.RATE_LIMIT_EXCEEDED;case 519:return L.KMsgErrorCode.INSUFFICIENT_BALANCE;case 404:case 501:return L.KMsgErrorCode.TEMPLATE_NOT_FOUND;case 502:case 503:case 504:case 505:case 506:case 507:case 508:case 509:case 510:case 511:case 512:case 513:case 514:case 515:case 516:case 517:case 540:return L.KMsgErrorCode.INVALID_REQUEST;case 518:return L.KMsgErrorCode.PROVIDER_ERROR;default:if(e>=500)return L.KMsgErrorCode.PROVIDER_ERROR;return L.KMsgErrorCode.INVALID_REQUEST}}function M(e){if(typeof e==="number"&&Number.isFinite(e))return e;if(typeof e==="string"){let t=e.trim();if(t.length===0)return;let n=Number(t);if(Number.isFinite(n))return n}return}function ye(e){if(typeof e!=="string")return;let t=e.trim().toUpperCase();if(!t)return;switch(t){case"Y":case"APPROVED":return"Y";case"I":case"INSPECTION":return"I";case"R":case"REJECTED":return"R";case"PENDING":return"I";default:return}}function ne(e){switch(typeof e==="string"?e.trim().toUpperCase():""){case"Y":return"APPROVED";case"I":return"INSPECTION";case"R":return"REJECTED";default:return"PENDING"}}var Ie="https://alimtalk.bizservice.iwinv.kr",be="https://sms.bizservice.iwinv.kr";var y=require("@k-msg/core");var Y=require("@k-msg/core");function U(e){return e.replace(/[^0-9]/g,"")}function K(){return be}function H(e){if(e.smsApiKey&&e.smsAuthKey)return J(`${e.smsApiKey}&${e.smsAuthKey}`);let t=e.smsAuthKey||e.smsApiKey;if(!t)return"";return J(`${e.apiKey}&${t}`)}function $(e){return H(e).length>0}function re(e){if(typeof e==="number"&&Number.isFinite(e))return e.toString();if(typeof e==="string")return e.trim();return""}function se(e,t){return{"0":"전송 성공","1":"메시지가 전송되지 않았습니다.","11":"운영 중인 서비스가 아닙니다.","12":"요금제 충전 중입니다. 잠시 후 다시 시도해 보시기 바랍니다.","13":"등록되지 않은 발신번호입니다.","14":"인증 요청이 올바르지 않습니다.","15":"등록하지 않은 IP에서는 발송되지 않습니다.","21":"장문 메시지는 2000 Bytes까지만 입력이 가능합니다.","22":"제목 입력 가능 문자가 올바르지 않습니다.","23":"제목은 40 Byte까지만 입력이 가능합니다.","31":"파일 업로드는 100KB까지 가능합니다.","32":"허용되지 않는 파일 확장자입니다.","33":"이미지 업로드에 실패했습니다.","41":"수신 번호를 입력하여 주세요.","42":"예약 전송 가능 시간이 아닙니다.","43":"날짜와 시간 표현 형식에 맞춰 입력하여 주십시오.","44":"최대 1000건 전송 가능합니다.","50":"SMS 자동 충전 한도를 초과하였습니다.","202":"SMS API 인증 실패 또는 SMS 서비스 권한이 없습니다.","206":"등록하지 않은 IP에서는 발송되지 않습니다."}[e]||t}function oe(e,t){if(e==="14"||e==="15"||e==="202"||e==="206")return Y.KMsgErrorCode.AUTHENTICATION_FAILED;if(e==="50")return Y.KMsgErrorCode.INSUFFICIENT_BALANCE;if(e==="13"||e==="21"||e==="22"||e==="23"||e==="31"||e==="32"||e==="33"||e==="41"||e==="42"||e==="43"||e==="44")return Y.KMsgErrorCode.INVALID_REQUEST;if(!t)return Y.KMsgErrorCode.NETWORK_ERROR;return Y.KMsgErrorCode.PROVIDER_ERROR}function ie(e,t){if(t&&t.trim().length>0)return t.trim();return e.slice(0,20)}function Se(e,t){if(e==="06")return"DELIVERED";if(e==="1000")return"DELIVERED";if(typeof t==="string"){if(t.includes("전송 성공"))return"DELIVERED";if(t.includes("대기")||t.includes("처리중"))return"PENDING"}if(e==="00"||e==="01")return"PENDING";if(!e&&!t)return"UNKNOWN";return"FAILED"}function ae(e,t){return new Date(e.getTime()+t*24*60*60*1000)}function de(e){let t=(n)=>n.toString().padStart(2,"0");return`${e.getFullYear()}-${t(e.getMonth()+1)}-${t(e.getDate())}`}function B(e){if(typeof e!=="string")return;let t=e.trim();if(!t)return;let n=/^(\d{4})-(\d{2})-(\d{2})\s+(\d{2}):(\d{2}):(\d{2})$/.exec(t);if(!n)return;let r=Number(n[1]),s=Number(n[2]),d=Number(n[3]),u=Number(n[4]),i=Number(n[5]),a=Number(n[6]);if(!Number.isFinite(r)||!Number.isFinite(s)||!Number.isFinite(d)||!Number.isFinite(u)||!Number.isFinite(i)||!Number.isFinite(a))return;let m=new Date(r,s-1,d,u,i,a);if(Number.isNaN(m.getTime()))return;return m}function G(e){let t=(n)=>n.toString().padStart(2,"0");return`${e.getFullYear()}-${t(e.getMonth()+1)}-${t(e.getDate())} ${t(e.getHours())}:${t(e.getMinutes())}:${t(e.getSeconds())}`}function pe(e){let t=(n)=>n.toString().padStart(2,"0");return`${e.getFullYear()}-${t(e.getMonth()+1)}-${t(e.getDate())} ${t(e.getHours())}:${t(e.getMinutes())}:${t(e.getSeconds())}`}async function Ne(e){let{providerId:t,config:n,query:r}=e,s=r.providerMessageId.trim();if(!s)return y.fail(new y.KMsgError(y.KMsgErrorCode.INVALID_REQUEST,"providerMessageId is required",{providerId:t}));let d=U(r.to);if(!d)return y.fail(new y.KMsgError(y.KMsgErrorCode.INVALID_REQUEST,"to is required",{providerId:t}));let u=Number(s),i=Number.isFinite(u)?u:void 0,a=G(ae(r.requestedAt,-1)),m=G(new Date),b={pageNum:1,pageSize:15,phone:d,startDate:a,endDate:m,...i!==void 0?{seqNo:i}:{},...r.scheduledAt instanceof Date&&!Number.isNaN(r.scheduledAt.getTime())?{reserve:"Y"}:{}},w=`${n.baseUrl}/api/history/`;try{let l=await fetch(w,{method:"POST",headers:_(n),body:JSON.stringify(b)}),I=await l.text(),R=k(I),g=z(R,{}),S=g.code,v=typeof S==="number"?S:void 0,f=typeof g.message==="string"&&g.message.length>0?g.message:"IWINV history query failed";if(!l.ok||v!==200)return y.fail(new y.KMsgError(V(v??M(R)??l.status),f,{providerId:t,originalCode:S??l.status}));let T=g.list,h=Array.isArray(T)?T:[];if(h.length===0)return y.ok(null);let N=(()=>{if(i===void 0)return h[0];return h.find((E)=>O(E)&&E.seqNo===i)??h[0]})();if(!O(N))return y.ok(null);let D=typeof N.statusCode==="string"?N.statusCode:void 0,C=typeof N.statusCodeName==="string"?N.statusCodeName:void 0,A=B(N.sendDate),q=B(N.receiveDate),F=D==="OK"||typeof C==="string"&&C.includes("성공");return y.ok({providerId:t,providerMessageId:s,status:F?"DELIVERED":A?"FAILED":"PENDING",statusCode:D,statusMessage:C,sentAt:A,deliveredAt:F?q||A:void 0,failedAt:!F&&A?A:void 0,raw:N})}catch(l){return y.fail(new y.KMsgError(y.KMsgErrorCode.NETWORK_ERROR,l instanceof Error?l.message:String(l),{providerId:t}))}}async function we(e){let{providerId:t,config:n,query:r}=e;if(!$(n))return y.fail(new y.KMsgError(y.KMsgErrorCode.INVALID_REQUEST,"SMS v2 configuration missing (smsApiKey/smsAuthKey)",{providerId:t}));if(!n.smsCompanyId||n.smsCompanyId.length===0)return y.fail(new y.KMsgError(y.KMsgErrorCode.INVALID_REQUEST,"smsCompanyId required for history (config.smsCompanyId)",{providerId:t}));let s=r.providerMessageId.trim();if(!s)return y.fail(new y.KMsgError(y.KMsgErrorCode.INVALID_REQUEST,"providerMessageId is required",{providerId:t}));let d=U(r.to);if(!d)return y.fail(new y.KMsgError(y.KMsgErrorCode.INVALID_REQUEST,"to is required",{providerId:t}));let u=ae(r.requestedAt,-1),i=new Date;if(i.getTime()-u.getTime()>7776000000)return y.fail(new y.KMsgError(y.KMsgErrorCode.INVALID_REQUEST,"SMS history date range must be within 90 days",{providerId:t}));let b={version:"1.0",companyid:n.smsCompanyId,startDate:de(u),endDate:de(i),requestNo:s,pageNum:1,pageSize:15,phone:d},l={"Content-Type":"application/json;charset=UTF-8",secret:H(n)};if(typeof n.xForwardedFor==="string"&&n.xForwardedFor.length>0)l["X-Forwarded-For"]=n.xForwardedFor;let I=n.extraHeaders&&typeof n.extraHeaders==="object"?{...l,...n.extraHeaders}:l,R=`${K()}/api/history/`;try{let g=await fetch(R,{method:"POST",headers:I,body:JSON.stringify(b)}),S=await g.text(),v=k(S),f=z(v,{}),T=f.resultCode,h=typeof T==="number"?T:typeof T==="string"?Number(T):NaN,N=typeof f.message==="string"&&f.message.length>0?f.message:"IWINV SMS history query failed";if(!g.ok||h!==0)return y.fail(new y.KMsgError(y.KMsgErrorCode.PROVIDER_ERROR,N,{providerId:t,originalCode:T??g.status}));let D=f.list,C=Array.isArray(D)?D:[];if(C.length===0)return y.ok(null);let A=(()=>{return C.find((W)=>{if(!O(W))return!1;let P=W.requestNo;return P!==void 0&&P!==null?String(P)===s:!1})??C[0]})();if(!O(A))return y.ok(null);let q=typeof A.sendStatusCode==="string"?A.sendStatusCode:void 0,F=typeof A.sendStatusMsg==="string"?A.sendStatusMsg:typeof A.sendStatus==="string"?A.sendStatus:void 0,j=B(A.sendDate),E=Se(q,F);return y.ok({providerId:t,providerMessageId:s,status:E,statusCode:q,statusMessage:F,sentAt:j,deliveredAt:E==="DELIVERED"?j:void 0,failedAt:E==="FAILED"?j:void 0,raw:A})}catch(g){return y.fail(new y.KMsgError(y.KMsgErrorCode.NETWORK_ERROR,g instanceof Error?g.message:String(g),{providerId:t}))}}var o=require("@k-msg/core");var x=require("@k-msg/core");function Te(e){let t=e.split(/[?#]/,1)[0]??e,n=t.lastIndexOf(".");if(n<=0||n===t.length-1)return"";return t.slice(n).toLowerCase()}function ce(e){switch(Te(e)){case".jpg":case".jpeg":return"image/jpeg";case".png":return"image/png";case".gif":return"image/gif";case".webp":return"image/webp";default:return}}function ve(e,t){let n=e&&typeof e==="object"?e:{},s=(n.media&&typeof n.media==="object"?n.media:void 0)?.image;if(s&&typeof s==="object"){if(s.bytes instanceof Uint8Array)return x.ok({bytes:s.bytes,filename:typeof s.filename==="string"?s.filename:void 0,contentType:typeof s.contentType==="string"?s.contentType:void 0});if(s.blob instanceof Blob)return x.ok({blob:s.blob,filename:typeof s.filename==="string"?s.filename:void 0,contentType:typeof s.contentType==="string"?s.contentType:void 0});if(typeof s.ref==="string"&&s.ref.trim().length>0)return x.fail(new x.KMsgError(x.KMsgErrorCode.INVALID_REQUEST,"IWINV MMS caller must provide blob/bytes in options.media.image",{providerId:t,field:"media.image.ref"}))}let d=n.imageUrl;if(typeof d==="string"&&d.trim().length>0)return x.fail(new x.KMsgError(x.KMsgErrorCode.INVALID_REQUEST,"IWINV MMS caller must provide blob/bytes in options.media.image",{providerId:t,field:"imageUrl"}));return x.ok(void 0)}async function Ee(e){if("blob"in e){let d=e.contentType||e.blob.type||"application/octet-stream",u=e.filename||"image",i=e.contentType&&e.contentType!==e.blob.type?new Blob([await e.blob.arrayBuffer()],{type:d}):e.blob;return{blob:i,filename:u,contentType:d,size:i.size}}let t=e.contentType||"application/octet-stream",n=new Uint8Array(e.bytes.byteLength);n.set(e.bytes);let r=new Blob([n],{type:t}),s=e.filename||"image";return{blob:r,filename:s,contentType:t,size:r.size}}function Re(e){if(Te(e.filename).length>0)return e.filename;let n=ce(e.filename)==="image/png"?".png":ce(e.filename)==="image/gif"?".gif":ce(e.filename)==="image/webp"?".webp":e.contentType==="image/png"?".png":e.contentType==="image/gif"?".gif":e.contentType==="image/webp"?".webp":".jpg";return`${e.filename}${n}`}async function he(e){let{providerId:t,config:n,options:r}=e,s=r.templateId;if(!s||s.length===0)return o.fail(new o.KMsgError(o.KMsgErrorCode.INVALID_REQUEST,"templateId is required for ALIMTALK",{providerId:t}));let d=r.options?.scheduledAt,u=d instanceof Date&&!Number.isNaN(d.getTime()),i=u?"Y":"N",a=u?G(d):void 0,m=U(r.to);if(!m)return o.fail(new o.KMsgError(o.KMsgErrorCode.INVALID_REQUEST,"to is required",{providerId:t}));let b=r.providerOptions?.templateParam,w=Array.isArray(b)?b.map((E)=>E===null||E===void 0?"":String(E)):Object.values(r.variables||{}).map((E)=>E===null||E===void 0?"":String(E)),l=r.failover,I=(typeof r.from==="string"&&r.from.length>0?r.from:n.senderNumber||n.smsSenderNumber)||"",R=I?U(I):"",g=typeof r.providerOptions?.reSend==="string"?r.providerOptions.reSend.trim().toUpperCase():"",S=g==="Y"||g==="N"?g:void 0,v=l?.enabled===!0?"Y":l?.enabled===!1?"N":void 0,f=S??v??(R?"Y":"N"),h=(typeof r.providerOptions?.resendCallback==="string"?U(r.providerOptions.resendCallback):"")||R;if(f==="Y"&&!h)return o.fail(new o.KMsgError(o.KMsgErrorCode.INVALID_REQUEST,"resendCallback is required when reSend is 'Y' (options.from or providerOptions.resendCallback)",{providerId:t}));let N=typeof r.providerOptions?.resendType==="string"?r.providerOptions.resendType.trim().toUpperCase():"",D=N==="Y"||N==="N"?N:void 0;if(typeof r.providerOptions?.resendType==="string"&&r.providerOptions.resendType.length>0&&!D)return o.fail(new o.KMsgError(o.KMsgErrorCode.INVALID_REQUEST,"resendType must be 'Y' or 'N'",{providerId:t}));let C=l?.fallbackChannel==="lms"?"Y":l?.fallbackChannel==="sms"?"N":void 0,A=typeof r.providerOptions?.resendTitle==="string"&&r.providerOptions.resendTitle.trim().length>0?r.providerOptions.resendTitle.trim():typeof l?.fallbackTitle==="string"&&l.fallbackTitle.trim().length>0?l.fallbackTitle.trim():void 0,q=typeof r.providerOptions?.resendContent==="string"&&r.providerOptions.resendContent.trim().length>0?r.providerOptions.resendContent.trim():typeof l?.fallbackContent==="string"&&l.fallbackContent.trim().length>0?l.fallbackContent.trim():void 0,F={templateCode:s,reserve:i,...a?{sendDate:a}:{},list:[{phone:m,templateParam:w.length>0?w:void 0}],reSend:f,...h?{resendCallback:h}:{},...D??C?{resendType:D??C}:{},...A?{resendTitle:A}:{},...q?{resendContent:q}:{}},j=`${n.baseUrl}${ge(n)}`;try{let E=await fetch(j,{method:"POST",headers:_(n),body:JSON.stringify(F)}),ee=await E.text(),W=k(ee),P=O(W)?W:{code:M(W)??E.status,message:ee||String(W||"")};if(!E.ok||P.code!==200)return o.fail(new o.KMsgError(V(P.code),P.message||"IWINV send failed",{providerId:t,originalCode:P.code}));return o.ok({messageId:r.messageId||crypto.randomUUID(),providerId:t,providerMessageId:typeof P.seqNo==="number"?String(P.seqNo):void 0,status:u?"PENDING":"SENT",type:r.type,to:r.to,raw:P})}catch(E){return o.fail(new o.KMsgError(o.KMsgErrorCode.NETWORK_ERROR,E instanceof Error?E.message:String(E),{providerId:t}))}}async function Ue(e){let{providerId:t,config:n,options:r,to:s,from:d,text:u,scheduledAtValid:i,scheduledAt:a}=e;if(r.type!=="MMS")return o.fail(new o.KMsgError(o.KMsgErrorCode.INVALID_REQUEST,"IWINVProvider: MMS handler called with non-MMS options",{providerId:t,type:r.type}));let m=ie(u,r.subject),b=ve(r,t);if(b.isFailure)return b;let w=b.value;if(!w)return o.fail(new o.KMsgError(o.KMsgErrorCode.INVALID_REQUEST,"image is required for MMS; caller must provide options.media.image.blob or bytes",{providerId:t}));let l;try{l=await Ee(w)}catch(f){return o.fail(f instanceof o.KMsgError?f:new o.KMsgError(o.KMsgErrorCode.NETWORK_ERROR,f instanceof Error?f.message:String(f),{providerId:t}))}if(l.size>102400)return o.fail(new o.KMsgError(o.KMsgErrorCode.INVALID_REQUEST,"MMS image must be <= 100KB",{providerId:t,bytes:l.size}));let I=new FormData;if(I.append("version","1.0"),I.append("from",d),I.append("to",s),I.append("title",m),I.append("text",u),i&&a)I.append("date",pe(a));I.append("image",l.blob,Re(l));let g={secret:H(n)};if(typeof n.xForwardedFor==="string"&&n.xForwardedFor.length>0)g["X-Forwarded-For"]=n.xForwardedFor;let S={...g};if(n.extraHeaders&&typeof n.extraHeaders==="object")for(let[f,T]of Object.entries(n.extraHeaders)){if(f.toLowerCase()==="content-type")continue;S[f]=T}let v=`${K()}/api/v2/send/`;try{let f=await fetch(v,{method:"POST",headers:S,body:I}),T=await f.text(),h=k(T),N=O(h)?h:{resultCode:h},D=N.resultCode??N.code,C=re(D),A=typeof N.message==="string"&&N.message.length>0?N.message:se(C,"MMS send failed");if(!(f.ok&&C==="0"))return o.fail(new o.KMsgError(oe(C,f.ok),A,{providerId:t,originalCode:D}));let F=typeof N.requestNo==="string"&&N.requestNo.length>0?N.requestNo:typeof N.msgid==="string"&&N.msgid.length>0?N.msgid:void 0;return o.ok({messageId:r.messageId||crypto.randomUUID(),providerId:t,providerMessageId:F,status:i?"PENDING":"SENT",type:r.type,to:r.to,raw:N})}catch(f){return o.fail(new o.KMsgError(o.KMsgErrorCode.NETWORK_ERROR,f instanceof Error?f.message:String(f),{providerId:t}))}}async function Ae(e){let{providerId:t,config:n,options:r}=e;if(!$(n))return o.fail(new o.KMsgError(o.KMsgErrorCode.INVALID_REQUEST,"SMS v2 configuration missing (smsApiKey/smsAuthKey)",{providerId:t}));let s=U(r.to);if(!s)return o.fail(new o.KMsgError(o.KMsgErrorCode.INVALID_REQUEST,"to is required",{providerId:t}));let d=r.text;if(!d||d.trim().length===0)return o.fail(new o.KMsgError(o.KMsgErrorCode.INVALID_REQUEST,"text is required for SMS/LMS/MMS",{providerId:t}));let u=(typeof r.from==="string"&&r.from.length>0?r.from:n.smsSenderNumber||n.senderNumber)||"",i=u?U(u):"";if(!i)return o.fail(new o.KMsgError(o.KMsgErrorCode.INVALID_REQUEST,"from is required for SMS/LMS/MMS (options.from or config.smsSenderNumber)",{providerId:t}));let a=r.options?.scheduledAt,m=a instanceof Date&&!Number.isNaN(a.getTime());if(r.type==="MMS")return await Ue({providerId:t,config:n,options:r,to:s,from:i,text:d,scheduledAtValid:m,scheduledAt:m?a:void 0});let b={version:"1.0",from:i,to:[s],text:d};if(r.type==="LMS")b.title=ie(d,r.subject);else{let g=typeof r.providerOptions?.msgType==="string"&&r.providerOptions.msgType.trim().length>0?r.providerOptions.msgType.trim():void 0;b.msgType=g||r.type}if(m)b.date=pe(a);let l={"Content-Type":"application/json;charset=UTF-8",secret:H(n)};if(typeof n.xForwardedFor==="string"&&n.xForwardedFor.length>0)l["X-Forwarded-For"]=n.xForwardedFor;let I=n.extraHeaders&&typeof n.extraHeaders==="object"?{...l,...n.extraHeaders}:l,R=`${K()}/api/v2/send/`;try{let g=await fetch(R,{method:"POST",headers:I,body:JSON.stringify(b)}),S=await g.text(),v=k(S),f=O(v)?v:{resultCode:v},T=f.resultCode??f.code,h=re(T),N=typeof f.message==="string"&&f.message.length>0?f.message:se(h,"SMS send failed");if(!(g.ok&&h==="0"))return o.fail(new o.KMsgError(oe(h,g.ok),N,{providerId:t,originalCode:T}));let C=typeof f.requestNo==="string"&&f.requestNo.length>0?f.requestNo:typeof f.msgid==="string"&&f.msgid.length>0?f.msgid:void 0;return o.ok({messageId:r.messageId||crypto.randomUUID(),providerId:t,providerMessageId:C,status:m?"PENDING":"SENT",type:r.type,to:r.to,raw:f})}catch(g){return o.fail(new o.KMsgError(o.KMsgErrorCode.NETWORK_ERROR,g instanceof Error?g.message:String(g),{providerId:t}))}}var p=require("@k-msg/core"),le=require("@k-msg/template");async function X(e){let t=await e.text(),n=k(t);return z(n,{code:M(n)??e.status,message:t||String(n||"")})}function De(e,t){return new p.KMsgError(e.code,e.message,{providerId:t,...e.details??{}})}async function Ce(e){let{providerId:t,config:n,input:r}=e;if(!r||typeof r!=="object")return p.fail(new p.KMsgError(p.KMsgErrorCode.INVALID_REQUEST,"Template input is required",{providerId:t}));let s=le.validateTemplatePayload(r,{requireName:!0,requireContent:!0});if(s.isFailure)return p.fail(De(s.error,t));let d=`${n.baseUrl}/api/template/add/`,u={templateName:s.value.name??r.name,templateContent:s.value.content??r.content,...s.value.buttons?{buttons:s.value.buttons}:{}};try{let i=await fetch(d,{method:"POST",headers:_(n),body:JSON.stringify(u)}),a=await X(i),m=M(a.code)??i.status,b=typeof a.message==="string"&&a.message.length>0?a.message:"IWINV template create failed";if(!i.ok||m!==200)return p.fail(new p.KMsgError(V(m),b,{providerId:t,originalCode:m}));let w=a.templateCode,l=typeof w==="string"&&w.trim().length>0?w.trim():"";if(!l)return p.fail(new p.KMsgError(p.KMsgErrorCode.PROVIDER_ERROR,"IWINV template create did not return templateCode",{providerId:t,raw:a}));let I=new Date;return p.ok({id:l,code:l,name:s.value.name??r.name,content:s.value.content??r.content,category:r.category,status:"INSPECTION",buttons:s.value.buttons,variables:r.variables,createdAt:I,updatedAt:I})}catch(i){return p.fail(new p.KMsgError(p.KMsgErrorCode.NETWORK_ERROR,i instanceof Error?i.message:String(i),{providerId:t}))}}async function Oe(e){let{providerId:t,config:n,code:r,patch:s,ctx:d}=e,u=typeof r==="string"?r.trim():"";if(!u)return p.fail(new p.KMsgError(p.KMsgErrorCode.INVALID_REQUEST,"code is required",{providerId:t}));let i=await Z({providerId:t,config:n,code:u,ctx:d});if(i.isFailure)return i;let a=i.value,m=typeof s.name==="string"&&s.name.trim().length>0?s.name.trim():a.name,b=typeof s.content==="string"&&s.content.trim().length>0?s.content:a.content,w=s.buttons!==void 0?s.buttons:a.buttons,l=le.validateTemplatePayload({name:m,content:b,buttons:w},{requireName:!0,requireContent:!0});if(l.isFailure)return p.fail(De(l.error,t));let I=`${n.baseUrl}/api/template/modify/`,R={templateCode:u,templateName:l.value.name??m,templateContent:l.value.content??b,...l.value.buttons?{buttons:l.value.buttons}:{}};try{let g=await fetch(I,{method:"POST",headers:_(n),body:JSON.stringify(R)}),S=await X(g),v=M(S.code)??g.status,f=typeof S.message==="string"&&S.message.length>0?S.message:"IWINV template update failed";if(!g.ok||v!==200)return p.fail(new p.KMsgError(V(v),f,{providerId:t,originalCode:v}));let T=await Z({providerId:t,config:n,code:u,ctx:d});if(T.isSuccess)return T;return p.ok({...a,name:l.value.name??m,content:l.value.content??b,...s.category!==void 0?{category:s.category}:{},...s.variables!==void 0?{variables:s.variables}:{},...s.buttons!==void 0?{buttons:l.value.buttons}:{},updatedAt:new Date})}catch(g){return p.fail(new p.KMsgError(p.KMsgErrorCode.NETWORK_ERROR,g instanceof Error?g.message:String(g),{providerId:t}))}}async function xe(e){let{providerId:t,config:n,code:r}=e,s=typeof r==="string"?r.trim():"";if(!s)return p.fail(new p.KMsgError(p.KMsgErrorCode.INVALID_REQUEST,"code is required",{providerId:t}));let d=`${n.baseUrl}/api/template/delete/`,u={templateCode:s};try{let i=await fetch(d,{method:"POST",headers:_(n),body:JSON.stringify(u)}),a=await X(i),m=M(a.code)??i.status,b=typeof a.message==="string"&&a.message.length>0?a.message:typeof a.messgae==="string"&&a.messgae.length>0?a.messgae:"IWINV template delete failed";if(!i.ok||m!==200)return p.fail(new p.KMsgError(V(m),b,{providerId:t,originalCode:m}));return p.ok(void 0)}catch(i){return p.fail(new p.KMsgError(p.KMsgErrorCode.NETWORK_ERROR,i instanceof Error?i.message:String(i),{providerId:t}))}}async function Z(e){let{providerId:t,config:n,code:r}=e,s=typeof r==="string"?r.trim():"";if(!s)return p.fail(new p.KMsgError(p.KMsgErrorCode.INVALID_REQUEST,"code is required",{providerId:t}));let d={pageNum:"1",pageSize:"15",templateCode:s},u=`${n.baseUrl}/api/template/`;try{let i=await fetch(u,{method:"POST",headers:_(n),body:JSON.stringify(d)}),a=await X(i),m=M(a.code)??i.status,b=typeof a.message==="string"&&a.message.length>0?a.message:"IWINV template get failed";if(!i.ok||m!==200)return p.fail(new p.KMsgError(V(m),b,{providerId:t,originalCode:m}));let w=a.list,I=(Array.isArray(w)?w:[]).find(O);if(!I)return p.fail(new p.KMsgError(p.KMsgErrorCode.TEMPLATE_NOT_FOUND,"Template not found",{providerId:t,templateCode:s}));let R=I.templateCode,g=typeof R==="string"?R:String(R??""),S=typeof I.templateName==="string"?I.templateName:"",v=typeof I.templateContent==="string"?I.templateContent:"",f=ne(I.status),T=B(I.createDate)??new Date;return p.ok({id:g,code:g,name:S,content:v,status:f,buttons:Array.isArray(I.buttons)?I.buttons:void 0,createdAt:T,updatedAt:T})}catch(i){return p.fail(new p.KMsgError(p.KMsgErrorCode.NETWORK_ERROR,i instanceof Error?i.message:String(i),{providerId:t}))}}async function ke(e){let{providerId:t,config:n,query:r}=e,s=typeof r?.page==="number"&&r.page>0?Math.floor(r.page):1,d=typeof r?.limit==="number"&&r.limit>0?Math.floor(r.limit):15,u=ye(r?.status),i={pageNum:String(s),pageSize:String(d),...u?{templateStatus:u}:{}},a=`${n.baseUrl}/api/template/`;try{let m=await fetch(a,{method:"POST",headers:_(n),body:JSON.stringify(i)}),b=await X(m),w=M(b.code)??m.status,l=typeof b.message==="string"&&b.message.length>0?b.message:"IWINV template list failed";if(!m.ok||w!==200)return p.fail(new p.KMsgError(V(w),l,{providerId:t,originalCode:w}));let I=b.list,g=(Array.isArray(I)?I:[]).filter(O).map((S)=>{let v=S.templateCode,f=typeof v==="string"?v:String(v??""),T=typeof S.templateName==="string"?S.templateName:"",h=typeof S.templateContent==="string"?S.templateContent:"",N=ne(S.status),D=B(S.createDate)??new Date;return{id:f,code:f,name:T,content:h,status:N,buttons:Array.isArray(S.buttons)?S.buttons:void 0,createdAt:D,updatedAt:D}}).filter((S)=>S.code.length>0);return p.ok(g)}catch(m){return p.fail(new p.KMsgError(p.KMsgErrorCode.NETWORK_ERROR,m instanceof Error?m.message:String(m),{providerId:t}))}}class Q{id="iwinv";name="IWINV Messaging Provider";supportedTypes;config;getOnboardingSpec(){let e=fe(this.id);if(!e)throw new c.KMsgError(c.KMsgErrorCode.INVALID_REQUEST,`Onboarding spec missing for provider: ${this.id}`,{providerId:this.id});return e}constructor(e){if(!e||typeof e!=="object")throw new c.KMsgError(c.KMsgErrorCode.INVALID_REQUEST,"IWINVProvider requires a config object",{providerId:this.id});if(!e.apiKey||e.apiKey.length===0)throw new c.KMsgError(c.KMsgErrorCode.INVALID_REQUEST,"IWINVProvider requires `apiKey` configuration",{providerId:this.id});this.config={...e,baseUrl:Ie,sendEndpoint:e.sendEndpoint||"/api/v2/send/"};let t=["ALIMTALK"];if($(this.config))t.push("SMS","LMS","MMS");this.supportedTypes=t}async healthCheck(){let e=Date.now(),t=[];try{try{new URL(this.config.baseUrl)}catch{t.push("Invalid baseUrl")}if($(this.config))try{new URL(K())}catch{t.push("Invalid smsBaseUrl")}return{healthy:t.length===0,issues:t,latencyMs:Date.now()-e,data:{provider:this.id,baseUrl:this.config.baseUrl,smsBaseUrl:K()}}}catch(n){return t.push(n instanceof Error?n.message:String(n)),{healthy:!1,issues:t,latencyMs:Date.now()-e}}}async send(e){let t=e.messageId||crypto.randomUUID(),n={...e,messageId:t};switch(n.type){case"ALIMTALK":return he({providerId:this.id,config:this.config,options:n});case"SMS":case"LMS":case"MMS":return Ae({providerId:this.id,config:this.config,options:n});default:return c.fail(new c.KMsgError(c.KMsgErrorCode.INVALID_REQUEST,`IWINVProvider does not support type ${n.type}`,{providerId:this.id,type:n.type}))}}async getDeliveryStatus(e){switch(e.type){case"ALIMTALK":return Ne({providerId:this.id,config:this.config,query:e});case"SMS":case"LMS":case"MMS":return we({providerId:this.id,config:this.config,query:e});default:return c.fail(new c.KMsgError(c.KMsgErrorCode.INVALID_REQUEST,`IWINVProvider does not support type ${e.type}`,{providerId:this.id,type:e.type}))}}async getBalance(e){let t=e?.channel??"ALIMTALK";switch(t){case"ALIMTALK":return this.getAlimTalkBalance(t);case"SMS":case"LMS":case"MMS":return this.getSmsBalance(t);default:return c.fail(new c.KMsgError(c.KMsgErrorCode.INVALID_REQUEST,`IWINVProvider does not support balance query for type ${t}`,{providerId:this.id,type:t}))}}async getAlimTalkBalance(e){let t=`${this.config.baseUrl}/api/charge/`;try{let n=await fetch(t,{method:"POST",headers:_(this.config),body:JSON.stringify({})}),r=await n.text(),s=k(r),d=z(s,{}),u=d.code,i=typeof u==="string"?Number(u):void 0,a=typeof u==="number"?u:typeof i==="number"&&Number.isFinite(i)?i:void 0,m=typeof d.message==="string"&&d.message.length>0?d.message:"IWINV AlimTalk charge query failed";if(!n.ok||a!==200)return c.fail(new c.KMsgError(V(a??n.status),m,{providerId:this.id,originalCode:u??n.status}));let b=d.charge,w=typeof b==="number"?b:typeof b==="string"?Number(b):NaN;if(!Number.isFinite(w))return c.fail(new c.KMsgError(c.KMsgErrorCode.PROVIDER_ERROR,"Invalid charge value from IWINV AlimTalk charge API",{providerId:this.id,raw:d}));return c.ok({providerId:this.id,channel:e,amount:w,currency:"KRW",raw:d})}catch(n){return c.fail(new c.KMsgError(c.KMsgErrorCode.NETWORK_ERROR,n instanceof Error?n.message:String(n),{providerId:this.id}))}}async getSmsBalance(e){if(!this.config.smsApiKey||!this.config.smsAuthKey)return c.fail(new c.KMsgError(c.KMsgErrorCode.INVALID_REQUEST,"smsApiKey and smsAuthKey are required for SMS/LMS/MMS balance query",{providerId:this.id}));let n={"Content-Type":"application/json;charset=UTF-8",secret:H(this.config)};if(typeof this.config.xForwardedFor==="string"&&this.config.xForwardedFor.length>0)n["X-Forwarded-For"]=this.config.xForwardedFor;let r=this.config.extraHeaders&&typeof this.config.extraHeaders==="object"?{...n,...this.config.extraHeaders}:n,s=`${K()}/api/charge/`;try{let d=await fetch(s,{method:"POST",headers:r,body:JSON.stringify({version:"1.0"})}),u=await d.text(),i=k(u),a=z(i,{}),m=a.code??a.resultCode,b=typeof m==="string"?Number(m):void 0,w=typeof m==="number"?m:typeof b==="number"&&Number.isFinite(b)?b:NaN,l=typeof a.message==="string"&&a.message.length>0?a.message:"IWINV SMS charge query failed";if(!d.ok||w!==0)return c.fail(new c.KMsgError(c.KMsgErrorCode.PROVIDER_ERROR,l,{providerId:this.id,originalCode:m??d.status}));let I=a.charge,R=typeof I==="number"?I:typeof I==="string"?Number(I):NaN;if(!Number.isFinite(R))return c.fail(new c.KMsgError(c.KMsgErrorCode.PROVIDER_ERROR,"Invalid charge value from IWINV SMS charge API",{providerId:this.id,raw:a}));return c.ok({providerId:this.id,channel:e,amount:R,currency:"KRW",raw:a})}catch(d){return c.fail(new c.KMsgError(c.KMsgErrorCode.NETWORK_ERROR,d instanceof Error?d.message:String(d),{providerId:this.id}))}}async createTemplate(e,t){return Ce({providerId:this.id,config:this.config,input:e})}async updateTemplate(e,t,n){return Oe({providerId:this.id,config:this.config,code:e,patch:t,ctx:n})}async deleteTemplate(e,t){return xe({providerId:this.id,config:this.config,code:e})}async getTemplate(e,t){return Z({providerId:this.id,config:this.config,code:e,ctx:t})}async listTemplates(e,t){return ke({providerId:this.id,config:this.config,query:e,ctx:t})}}var xt=(e)=>new Q(e),Ke=()=>{let e={apiKey:c.readRuntimeEnv("IWINV_API_KEY")||"",smsApiKey:c.readRuntimeEnv("IWINV_SMS_API_KEY"),smsAuthKey:c.readRuntimeEnv("IWINV_SMS_AUTH_KEY"),smsCompanyId:c.readRuntimeEnv("IWINV_SMS_COMPANY_ID"),senderNumber:c.readRuntimeEnv("IWINV_SENDER_NUMBER")||c.readRuntimeEnv("IWINV_SMS_SENDER_NUMBER"),smsSenderNumber:c.readRuntimeEnv("IWINV_SMS_SENDER_NUMBER"),sendEndpoint:c.readRuntimeEnv("IWINV_SEND_ENDPOINT")||"/api/v2/send/",xForwardedFor:c.readRuntimeEnv("IWINV_X_FORWARDED_FOR"),debug:c.readRuntimeEnv("NODE_ENV")==="development"};if(!e.apiKey)throw new c.KMsgError(c.KMsgErrorCode.INVALID_REQUEST,"IWINV_API_KEY environment variable is required",{providerId:"iwinv"});return new Q(e)};class qe{static create(e){return new Q(e)}static createDefault(){return Ke()}}function kt(){}var ze={SUCCESS:200,AUTH_FAILED:201,BAD_REQUEST:400,UNAUTHORIZED:401,FORBIDDEN:403,NOT_FOUND:404,TOO_MANY_REQUESTS:429,INTERNAL_SERVER_ERROR:500};
|
|
1
|
+
var{defineProperty:ne,getOwnPropertyNames:Pe,getOwnPropertyDescriptor:Ve}=Object,Fe=Object.prototype.hasOwnProperty;var fe=new WeakMap,Le=(e)=>{var t=fe.get(e),n;if(t)return t;if(t=ne({},"__esModule",{value:!0}),e&&typeof e==="object"||typeof e==="function")Pe(e).map((r)=>!Fe.call(t,r)&&ne(t,r,{get:()=>e[r],enumerable:!(n=Ve(e,r))||n.enumerable}));return fe.set(e,t),t};var Ue=(e,t)=>{for(var n in t)ne(e,n,{get:t[n],enumerable:!0,configurable:!0,set:(r)=>t[n]=()=>r})};var je={};Ue(je,{default:()=>W,IWINV_STATUS_CODES:()=>We,IWINVProvider:()=>W});module.exports=Le(je);var p=require("@k-msg/core"),ae=require("@k-msg/template/send");function O(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function _(e){if(!e)return{};try{return JSON.parse(e)}catch{return e}}function z(e,t){return O(e)?e:t}var L=require("@k-msg/core");function Ke(e){let t="",n=0;while(n<e.length){let r=e[n++]??0,s=e[n++]??0,d=e[n++]??0,u=r<<16|s<<8|d;t+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[u>>18&63],t+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[u>>12&63],t+=n-2<e.length?"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[u>>6&63]:"=",t+=n-1<e.length?"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[u&63]:"="}return t}function G(e){return Ke(new TextEncoder().encode(e))}function ge(e){let t=e.sendEndpoint||"/api/v2/send/";return t.startsWith("/")?t:`/${t}`}function k(e){let n={AUTH:G(e.apiKey),"Content-Type":"application/json;charset=UTF-8"};if(typeof e.xForwardedFor==="string"&&e.xForwardedFor.length>0)n["X-Forwarded-For"]=e.xForwardedFor;if(e.extraHeaders&&typeof e.extraHeaders==="object")return{...n,...e.extraHeaders};return n}function M(e){switch(e){case 201:case 206:case 401:case 403:return L.KMsgErrorCode.AUTHENTICATION_FAILED;case 429:return L.KMsgErrorCode.RATE_LIMIT_EXCEEDED;case 519:return L.KMsgErrorCode.INSUFFICIENT_BALANCE;case 404:case 501:return L.KMsgErrorCode.TEMPLATE_NOT_FOUND;case 502:case 503:case 504:case 505:case 506:case 507:case 508:case 509:case 510:case 511:case 512:case 513:case 514:case 515:case 516:case 517:case 540:return L.KMsgErrorCode.INVALID_REQUEST;case 518:return L.KMsgErrorCode.PROVIDER_ERROR;default:if(e>=500)return L.KMsgErrorCode.PROVIDER_ERROR;return L.KMsgErrorCode.INVALID_REQUEST}}function V(e){if(typeof e==="number"&&Number.isFinite(e))return e;if(typeof e==="string"){let t=e.trim();if(t.length===0)return;let n=Number(t);if(Number.isFinite(n))return n}return}function ye(e){if(typeof e!=="string")return;let t=e.trim().toUpperCase();if(!t)return;switch(t){case"Y":case"APPROVED":return"Y";case"I":case"INSPECTION":return"I";case"R":case"REJECTED":return"R";case"PENDING":return"I";default:return}}function re(e){switch(typeof e==="string"?e.trim().toUpperCase():""){case"Y":return"APPROVED";case"I":return"INSPECTION";case"R":return"REJECTED";default:return"PENDING"}}function se(e,t){return new Date(e.getTime()+t*24*60*60*1000)}function oe(e){let t=(n)=>n.toString().padStart(2,"0");return`${e.getFullYear()}-${t(e.getMonth()+1)}-${t(e.getDate())}`}function B(e){if(typeof e!=="string")return;let t=e.trim();if(!t)return;let n=/^(\d{4})-(\d{2})-(\d{2})\s+(\d{2}):(\d{2}):(\d{2})$/.exec(t);if(!n)return;let r=Number(n[1]),s=Number(n[2]),d=Number(n[3]),u=Number(n[4]),i=Number(n[5]),a=Number(n[6]);if(!Number.isFinite(r)||!Number.isFinite(s)||!Number.isFinite(d)||!Number.isFinite(u)||!Number.isFinite(i)||!Number.isFinite(a))return;let m=new Date(r,s-1,d,u,i,a);if(Number.isNaN(m.getTime()))return;return m}function X(e){let t=(n)=>n.toString().padStart(2,"0");return`${e.getFullYear()}-${t(e.getMonth()+1)}-${t(e.getDate())} ${t(e.getHours())}:${t(e.getMinutes())}:${t(e.getSeconds())}`}function ie(e){let t=(n)=>n.toString().padStart(2,"0");return`${e.getFullYear()}-${t(e.getMonth()+1)}-${t(e.getDate())} ${t(e.getHours())}:${t(e.getMinutes())}:${t(e.getSeconds())}`}async function Z(e){let t=await e.text(),n=_(t);return z(n,{code:V(n)??e.status,message:t||String(n||"")})}function Ie(e,t){return new p.KMsgError(e.code,e.message,{providerId:t,...e.details??{}})}async function be(e){let{providerId:t,config:n,input:r}=e;if(!r||typeof r!=="object")return p.fail(new p.KMsgError(p.KMsgErrorCode.INVALID_REQUEST,"Template input is required",{providerId:t}));let s=ae.validateTemplatePayload(r,{requireName:!0,requireContent:!0});if(s.isFailure)return p.fail(Ie(s.error,t));let d=`${n.baseUrl}/api/template/add/`,u={templateName:s.value.name??r.name,templateContent:s.value.content??r.content,...s.value.buttons?{buttons:s.value.buttons}:{}};try{let i=await fetch(d,{method:"POST",headers:k(n),body:JSON.stringify(u)}),a=await Z(i),m=V(a.code)??i.status,b=typeof a.message==="string"&&a.message.length>0?a.message:"IWINV template create failed";if(!i.ok||m!==200)return p.fail(new p.KMsgError(M(m),b,{providerId:t,originalCode:m}));let T=a.templateCode,l=typeof T==="string"&&T.trim().length>0?T.trim():"";if(!l)return p.fail(new p.KMsgError(p.KMsgErrorCode.PROVIDER_ERROR,"IWINV template create did not return templateCode",{providerId:t,raw:a}));let I=new Date;return p.ok({id:l,code:l,name:s.value.name??r.name,content:s.value.content??r.content,category:r.category,status:"INSPECTION",buttons:s.value.buttons,variables:r.variables,createdAt:I,updatedAt:I})}catch(i){return p.fail(new p.KMsgError(p.KMsgErrorCode.NETWORK_ERROR,i instanceof Error?i.message:String(i),{providerId:t}))}}async function Se(e){let{providerId:t,config:n,code:r,patch:s,ctx:d}=e,u=typeof r==="string"?r.trim():"";if(!u)return p.fail(new p.KMsgError(p.KMsgErrorCode.INVALID_REQUEST,"code is required",{providerId:t}));let i=await ee({providerId:t,config:n,code:u,ctx:d});if(i.isFailure)return i;let a=i.value,m=typeof s.name==="string"&&s.name.trim().length>0?s.name.trim():a.name,b=typeof s.content==="string"&&s.content.trim().length>0?s.content:a.content,T=s.buttons!==void 0?s.buttons:a.buttons,l=ae.validateTemplatePayload({name:m,content:b,buttons:T},{requireName:!0,requireContent:!0});if(l.isFailure)return p.fail(Ie(l.error,t));let I=`${n.baseUrl}/api/template/modify/`,h={templateCode:u,templateName:l.value.name??m,templateContent:l.value.content??b,...l.value.buttons?{buttons:l.value.buttons}:{}};try{let g=await fetch(I,{method:"POST",headers:k(n),body:JSON.stringify(h)}),S=await Z(g),E=V(S.code)??g.status,f=typeof S.message==="string"&&S.message.length>0?S.message:"IWINV template update failed";if(!g.ok||E!==200)return p.fail(new p.KMsgError(M(E),f,{providerId:t,originalCode:E}));let w=await ee({providerId:t,config:n,code:u,ctx:d});if(w.isSuccess)return w;return p.ok({...a,name:l.value.name??m,content:l.value.content??b,...s.category!==void 0?{category:s.category}:{},...s.variables!==void 0?{variables:s.variables}:{},...s.buttons!==void 0?{buttons:l.value.buttons}:{},updatedAt:new Date})}catch(g){return p.fail(new p.KMsgError(p.KMsgErrorCode.NETWORK_ERROR,g instanceof Error?g.message:String(g),{providerId:t}))}}async function Ne(e){let{providerId:t,config:n,code:r}=e,s=typeof r==="string"?r.trim():"";if(!s)return p.fail(new p.KMsgError(p.KMsgErrorCode.INVALID_REQUEST,"code is required",{providerId:t}));let d=`${n.baseUrl}/api/template/delete/`,u={templateCode:s};try{let i=await fetch(d,{method:"POST",headers:k(n),body:JSON.stringify(u)}),a=await Z(i),m=V(a.code)??i.status,b=typeof a.message==="string"&&a.message.length>0?a.message:typeof a.messgae==="string"&&a.messgae.length>0?a.messgae:"IWINV template delete failed";if(!i.ok||m!==200)return p.fail(new p.KMsgError(M(m),b,{providerId:t,originalCode:m}));return p.ok(void 0)}catch(i){return p.fail(new p.KMsgError(p.KMsgErrorCode.NETWORK_ERROR,i instanceof Error?i.message:String(i),{providerId:t}))}}async function ee(e){let{providerId:t,config:n,code:r}=e,s=typeof r==="string"?r.trim():"";if(!s)return p.fail(new p.KMsgError(p.KMsgErrorCode.INVALID_REQUEST,"code is required",{providerId:t}));let d={pageNum:"1",pageSize:"15",templateCode:s},u=`${n.baseUrl}/api/template/`;try{let i=await fetch(u,{method:"POST",headers:k(n),body:JSON.stringify(d)}),a=await Z(i),m=V(a.code)??i.status,b=typeof a.message==="string"&&a.message.length>0?a.message:"IWINV template get failed";if(!i.ok||m!==200)return p.fail(new p.KMsgError(M(m),b,{providerId:t,originalCode:m}));let T=a.list,I=(Array.isArray(T)?T:[]).find(O);if(!I)return p.fail(new p.KMsgError(p.KMsgErrorCode.TEMPLATE_NOT_FOUND,"Template not found",{providerId:t,templateCode:s}));let h=I.templateCode,g=typeof h==="string"?h:String(h??""),S=typeof I.templateName==="string"?I.templateName:"",E=typeof I.templateContent==="string"?I.templateContent:"",f=re(I.status),w=B(I.createDate)??new Date;return p.ok({id:g,code:g,name:S,content:E,status:f,buttons:Array.isArray(I.buttons)?I.buttons:void 0,createdAt:w,updatedAt:w})}catch(i){return p.fail(new p.KMsgError(p.KMsgErrorCode.NETWORK_ERROR,i instanceof Error?i.message:String(i),{providerId:t}))}}async function Te(e){let{providerId:t,config:n,query:r}=e,s=typeof r?.page==="number"&&r.page>0?Math.floor(r.page):1,d=typeof r?.limit==="number"&&r.limit>0?Math.floor(r.limit):15,u=ye(r?.status),i={pageNum:String(s),pageSize:String(d),...u?{templateStatus:u}:{}},a=`${n.baseUrl}/api/template/`;try{let m=await fetch(a,{method:"POST",headers:k(n),body:JSON.stringify(i)}),b=await Z(m),T=V(b.code)??m.status,l=typeof b.message==="string"&&b.message.length>0?b.message:"IWINV template list failed";if(!m.ok||T!==200)return p.fail(new p.KMsgError(M(T),l,{providerId:t,originalCode:T}));let I=b.list,g=(Array.isArray(I)?I:[]).filter(O).map((S)=>{let E=S.templateCode,f=typeof E==="string"?E:String(E??""),w=typeof S.templateName==="string"?S.templateName:"",v=typeof S.templateContent==="string"?S.templateContent:"",N=re(S.status),D=B(S.createDate)??new Date;return{id:f,code:f,name:w,content:v,status:N,buttons:Array.isArray(S.buttons)?S.buttons:void 0,createdAt:D,updatedAt:D}}).filter((S)=>S.code.length>0);return p.ok(g)}catch(m){return p.fail(new p.KMsgError(p.KMsgErrorCode.NETWORK_ERROR,m instanceof Error?m.message:String(m),{providerId:t}))}}var c=require("@k-msg/core");var we={iwinv:{providerId:"iwinv",providerName:"IWINV Messaging Provider",channelOnboarding:"manual",templateLifecycleApi:"available",plusIdPolicy:"optional",plusIdInference:"unsupported",liveTestSupport:"supported",checks:[{id:"channel_registered_in_console",title:"Kakao channel is registered in IWINV console",description:"IWINV channel onboarding is manual. Confirm channel registration and approval in console.",kind:"manual",severity:"blocker",scopes:["doctor","preflight"]},{id:"iwinv_config_required",title:"IWINV config has required keys",kind:"config",severity:"blocker",scopes:["doctor","preflight"],configKeys:["apiKey"]},{id:"template_capability_available",title:"Template lifecycle APIs are available",kind:"capability",severity:"warning",scopes:["doctor","preflight"],capabilityMethods:["listTemplates","getTemplate","createTemplate","updateTemplate","deleteTemplate"]},{id:"template_list_probe",title:"Template list API probe",kind:"api_probe",severity:"warning",scopes:["doctor","preflight"],probeOperation:"list_templates"}],notes:["Channel add/auth is not available via IWINV public API in current integration.","Template APIs are available and can be probed."]},aligo:{providerId:"aligo",providerName:"Aligo Smart SMS",channelOnboarding:"api",templateLifecycleApi:"available",plusIdPolicy:"required_if_no_inference",plusIdInference:"supported",liveTestSupport:"supported",checks:[{id:"aligo_config_required",title:"Aligo config has required keys",kind:"config",severity:"blocker",scopes:["doctor","preflight"],configKeys:["apiKey","userId"]},{id:"channel_api_capability_available",title:"Kakao channel APIs are available",kind:"capability",severity:"warning",scopes:["doctor","preflight"],capabilityMethods:["listKakaoChannels","requestKakaoChannelAuth","addKakaoChannel"]},{id:"channel_list_probe",title:"Kakao channel list API probe",kind:"api_probe",severity:"warning",scopes:["doctor","preflight"],probeOperation:"list_kakao_channels"},{id:"template_list_probe",title:"Template list API probe",kind:"api_probe",severity:"warning",scopes:["doctor","preflight"],probeOperation:"list_templates"}]},solapi:{providerId:"solapi",providerName:"SOLAPI Messaging Provider",channelOnboarding:"none",templateLifecycleApi:"unavailable",plusIdPolicy:"required_if_no_inference",plusIdInference:"unsupported",liveTestSupport:"partial",checks:[{id:"solapi_config_required",title:"SOLAPI config has required keys",kind:"config",severity:"blocker",scopes:["doctor","preflight"],configKeys:["apiKey","apiSecret"]}],notes:["SOLAPI ALIMTALK requires kakao profileId/pfId, but plusId inference is not available in current integration."]},mock:{providerId:"mock",providerName:"Mock Provider",channelOnboarding:"api",templateLifecycleApi:"available",plusIdPolicy:"optional",plusIdInference:"supported",liveTestSupport:"none",checks:[{id:"mock_template_capability_available",title:"Mock template APIs are available",kind:"capability",severity:"info",scopes:["doctor","preflight"],capabilityMethods:["listTemplates","getTemplate","createTemplate"]}]}};function Ee(e){return we[e]}function dt(){return Object.values(we)}var Re="https://alimtalk.bizservice.iwinv.kr",he="https://sms.bizservice.iwinv.kr";var y=require("@k-msg/core");var Y=require("@k-msg/core");function U(e){return e.replace(/[^0-9]/g,"")}function K(){return he}function H(e){if(e.smsApiKey&&e.smsAuthKey)return G(`${e.smsApiKey}&${e.smsAuthKey}`);let t=e.smsAuthKey||e.smsApiKey;if(!t)return"";return G(`${e.apiKey}&${t}`)}function Q(e){return H(e).length>0}function de(e){if(typeof e==="number"&&Number.isFinite(e))return e.toString();if(typeof e==="string")return e.trim();return""}function pe(e,t){return{"0":"전송 성공","1":"메시지가 전송되지 않았습니다.","11":"운영 중인 서비스가 아닙니다.","12":"요금제 충전 중입니다. 잠시 후 다시 시도해 보시기 바랍니다.","13":"등록되지 않은 발신번호입니다.","14":"인증 요청이 올바르지 않습니다.","15":"등록하지 않은 IP에서는 발송되지 않습니다.","21":"장문 메시지는 2000 Bytes까지만 입력이 가능합니다.","22":"제목 입력 가능 문자가 올바르지 않습니다.","23":"제목은 40 Byte까지만 입력이 가능합니다.","31":"파일 업로드는 100KB까지 가능합니다.","32":"허용되지 않는 파일 확장자입니다.","33":"이미지 업로드에 실패했습니다.","41":"수신 번호를 입력하여 주세요.","42":"예약 전송 가능 시간이 아닙니다.","43":"날짜와 시간 표현 형식에 맞춰 입력하여 주십시오.","44":"최대 1000건 전송 가능합니다.","50":"SMS 자동 충전 한도를 초과하였습니다.","202":"SMS API 인증 실패 또는 SMS 서비스 권한이 없습니다.","206":"등록하지 않은 IP에서는 발송되지 않습니다."}[e]||t}function ce(e,t){if(e==="14"||e==="15"||e==="202"||e==="206")return Y.KMsgErrorCode.AUTHENTICATION_FAILED;if(e==="50")return Y.KMsgErrorCode.INSUFFICIENT_BALANCE;if(e==="13"||e==="21"||e==="22"||e==="23"||e==="31"||e==="32"||e==="33"||e==="41"||e==="42"||e==="43"||e==="44")return Y.KMsgErrorCode.INVALID_REQUEST;if(!t)return Y.KMsgErrorCode.NETWORK_ERROR;return Y.KMsgErrorCode.PROVIDER_ERROR}function le(e,t){if(t&&t.trim().length>0)return t.trim();return e.slice(0,20)}function ve(e,t){if(e==="06")return"DELIVERED";if(e==="1000")return"DELIVERED";if(typeof t==="string"){if(t.includes("전송 성공"))return"DELIVERED";if(t.includes("대기")||t.includes("처리중"))return"PENDING"}if(e==="00"||e==="01")return"PENDING";if(!e&&!t)return"UNKNOWN";return"FAILED"}async function Ae(e){let{providerId:t,config:n,query:r}=e,s=r.providerMessageId.trim();if(!s)return y.fail(new y.KMsgError(y.KMsgErrorCode.INVALID_REQUEST,"providerMessageId is required",{providerId:t}));let d=U(r.to);if(!d)return y.fail(new y.KMsgError(y.KMsgErrorCode.INVALID_REQUEST,"to is required",{providerId:t}));let u=Number(s),i=Number.isFinite(u)?u:void 0,a=X(se(r.requestedAt,-1)),m=X(new Date),b={pageNum:1,pageSize:15,phone:d,startDate:a,endDate:m,...i!==void 0?{seqNo:i}:{},...r.scheduledAt instanceof Date&&!Number.isNaN(r.scheduledAt.getTime())?{reserve:"Y"}:{}},T=`${n.baseUrl}/api/history/`;try{let l=await fetch(T,{method:"POST",headers:k(n),body:JSON.stringify(b)}),I=await l.text(),h=_(I),g=z(h,{}),S=g.code,E=typeof S==="number"?S:void 0,f=typeof g.message==="string"&&g.message.length>0?g.message:"IWINV history query failed";if(!l.ok||E!==200)return y.fail(new y.KMsgError(M(E??V(h)??l.status),f,{providerId:t,originalCode:S??l.status}));let w=g.list,v=Array.isArray(w)?w:[];if(v.length===0)return y.ok(null);let N=(()=>{if(i===void 0)return v[0];return v.find((R)=>O(R)&&R.seqNo===i)??v[0]})();if(!O(N))return y.ok(null);let D=typeof N.statusCode==="string"?N.statusCode:void 0,C=typeof N.statusCodeName==="string"?N.statusCodeName:void 0,A=B(N.sendDate),q=B(N.receiveDate),F=D==="OK"||typeof C==="string"&&C.includes("성공");return y.ok({providerId:t,providerMessageId:s,status:F?"DELIVERED":A?"FAILED":"PENDING",statusCode:D,statusMessage:C,sentAt:A,deliveredAt:F?q||A:void 0,failedAt:!F&&A?A:void 0,raw:N})}catch(l){return y.fail(new y.KMsgError(y.KMsgErrorCode.NETWORK_ERROR,l instanceof Error?l.message:String(l),{providerId:t}))}}async function De(e){let{providerId:t,config:n,query:r}=e;if(!Q(n))return y.fail(new y.KMsgError(y.KMsgErrorCode.INVALID_REQUEST,"SMS v2 configuration missing (smsApiKey/smsAuthKey)",{providerId:t}));if(!n.smsCompanyId||n.smsCompanyId.length===0)return y.fail(new y.KMsgError(y.KMsgErrorCode.INVALID_REQUEST,"smsCompanyId required for history (config.smsCompanyId)",{providerId:t}));let s=r.providerMessageId.trim();if(!s)return y.fail(new y.KMsgError(y.KMsgErrorCode.INVALID_REQUEST,"providerMessageId is required",{providerId:t}));let d=U(r.to);if(!d)return y.fail(new y.KMsgError(y.KMsgErrorCode.INVALID_REQUEST,"to is required",{providerId:t}));let u=se(r.requestedAt,-1),i=new Date;if(i.getTime()-u.getTime()>7776000000)return y.fail(new y.KMsgError(y.KMsgErrorCode.INVALID_REQUEST,"SMS history date range must be within 90 days",{providerId:t}));let b={version:"1.0",companyid:n.smsCompanyId,startDate:oe(u),endDate:oe(i),requestNo:s,pageNum:1,pageSize:15,phone:d},l={"Content-Type":"application/json;charset=UTF-8",secret:H(n)};if(typeof n.xForwardedFor==="string"&&n.xForwardedFor.length>0)l["X-Forwarded-For"]=n.xForwardedFor;let I=n.extraHeaders&&typeof n.extraHeaders==="object"?{...l,...n.extraHeaders}:l,h=`${K()}/api/history/`;try{let g=await fetch(h,{method:"POST",headers:I,body:JSON.stringify(b)}),S=await g.text(),E=_(S),f=z(E,{}),w=f.resultCode,v=typeof w==="number"?w:typeof w==="string"?Number(w):NaN,N=typeof f.message==="string"&&f.message.length>0?f.message:"IWINV SMS history query failed";if(!g.ok||v!==0)return y.fail(new y.KMsgError(y.KMsgErrorCode.PROVIDER_ERROR,N,{providerId:t,originalCode:w??g.status}));let D=f.list,C=Array.isArray(D)?D:[];if(C.length===0)return y.ok(null);let A=(()=>{return C.find(($)=>{if(!O($))return!1;let P=$.requestNo;return P!==void 0&&P!==null?String(P)===s:!1})??C[0]})();if(!O(A))return y.ok(null);let q=typeof A.sendStatusCode==="string"?A.sendStatusCode:void 0,F=typeof A.sendStatusMsg==="string"?A.sendStatusMsg:typeof A.sendStatus==="string"?A.sendStatus:void 0,j=B(A.sendDate),R=ve(q,F);return y.ok({providerId:t,providerMessageId:s,status:R,statusCode:q,statusMessage:F,sentAt:j,deliveredAt:R==="DELIVERED"?j:void 0,failedAt:R==="FAILED"?j:void 0,raw:A})}catch(g){return y.fail(new y.KMsgError(y.KMsgErrorCode.NETWORK_ERROR,g instanceof Error?g.message:String(g),{providerId:t}))}}var o=require("@k-msg/core");var x=require("@k-msg/core");function Ce(e){let t=e.split(/[?#]/,1)[0]??e,n=t.lastIndexOf(".");if(n<=0||n===t.length-1)return"";return t.slice(n).toLowerCase()}function ue(e){switch(Ce(e)){case".jpg":case".jpeg":return"image/jpeg";case".png":return"image/png";case".gif":return"image/gif";case".webp":return"image/webp";default:return}}function Oe(e,t){let n=e&&typeof e==="object"?e:{},s=(n.media&&typeof n.media==="object"?n.media:void 0)?.image;if(s&&typeof s==="object"){if(s.bytes instanceof Uint8Array)return x.ok({bytes:s.bytes,filename:typeof s.filename==="string"?s.filename:void 0,contentType:typeof s.contentType==="string"?s.contentType:void 0});if(s.blob instanceof Blob)return x.ok({blob:s.blob,filename:typeof s.filename==="string"?s.filename:void 0,contentType:typeof s.contentType==="string"?s.contentType:void 0});if(typeof s.ref==="string"&&s.ref.trim().length>0)return x.fail(new x.KMsgError(x.KMsgErrorCode.INVALID_REQUEST,"IWINV MMS caller must provide blob/bytes in options.media.image",{providerId:t,field:"media.image.ref"}))}let d=n.imageUrl;if(typeof d==="string"&&d.trim().length>0)return x.fail(new x.KMsgError(x.KMsgErrorCode.INVALID_REQUEST,"IWINV MMS caller must provide blob/bytes in options.media.image",{providerId:t,field:"imageUrl"}));return x.ok(void 0)}async function xe(e){if("blob"in e){let d=e.contentType||e.blob.type||"application/octet-stream",u=e.filename||"image",i=e.contentType&&e.contentType!==e.blob.type?new Blob([await e.blob.arrayBuffer()],{type:d}):e.blob;return{blob:i,filename:u,contentType:d,size:i.size}}let t=e.contentType||"application/octet-stream",n=new Uint8Array(e.bytes.byteLength);n.set(e.bytes);let r=new Blob([n],{type:t}),s=e.filename||"image";return{blob:r,filename:s,contentType:t,size:r.size}}function _e(e){if(Ce(e.filename).length>0)return e.filename;let n=ue(e.filename)==="image/png"?".png":ue(e.filename)==="image/gif"?".gif":ue(e.filename)==="image/webp"?".webp":e.contentType==="image/png"?".png":e.contentType==="image/gif"?".gif":e.contentType==="image/webp"?".webp":".jpg";return`${e.filename}${n}`}async function ke(e){let{providerId:t,config:n,options:r}=e,s=r.templateId;if(!s||s.length===0)return o.fail(new o.KMsgError(o.KMsgErrorCode.INVALID_REQUEST,"templateId is required for ALIMTALK",{providerId:t}));let d=r.options?.scheduledAt,u=d instanceof Date&&!Number.isNaN(d.getTime()),i=u?"Y":"N",a=u?X(d):void 0,m=U(r.to);if(!m)return o.fail(new o.KMsgError(o.KMsgErrorCode.INVALID_REQUEST,"to is required",{providerId:t}));let b=r.providerOptions?.templateParam,T=Array.isArray(b)?b.map((R)=>R===null||R===void 0?"":String(R)):Object.values(r.variables||{}).map((R)=>R===null||R===void 0?"":String(R)),l=r.failover,I=(typeof r.from==="string"&&r.from.length>0?r.from:n.senderNumber||n.smsSenderNumber)||"",h=I?U(I):"",g=typeof r.providerOptions?.reSend==="string"?r.providerOptions.reSend.trim().toUpperCase():"",S=g==="Y"||g==="N"?g:void 0,E=l?.enabled===!0?"Y":l?.enabled===!1?"N":void 0,f=S??E??(h?"Y":"N"),v=(typeof r.providerOptions?.resendCallback==="string"?U(r.providerOptions.resendCallback):"")||h;if(f==="Y"&&!v)return o.fail(new o.KMsgError(o.KMsgErrorCode.INVALID_REQUEST,"resendCallback is required when reSend is 'Y' (options.from or providerOptions.resendCallback)",{providerId:t}));let N=typeof r.providerOptions?.resendType==="string"?r.providerOptions.resendType.trim().toUpperCase():"",D=N==="Y"||N==="N"?N:void 0;if(typeof r.providerOptions?.resendType==="string"&&r.providerOptions.resendType.length>0&&!D)return o.fail(new o.KMsgError(o.KMsgErrorCode.INVALID_REQUEST,"resendType must be 'Y' or 'N'",{providerId:t}));let C=l?.fallbackChannel==="lms"?"Y":l?.fallbackChannel==="sms"?"N":void 0,A=typeof r.providerOptions?.resendTitle==="string"&&r.providerOptions.resendTitle.trim().length>0?r.providerOptions.resendTitle.trim():typeof l?.fallbackTitle==="string"&&l.fallbackTitle.trim().length>0?l.fallbackTitle.trim():void 0,q=typeof r.providerOptions?.resendContent==="string"&&r.providerOptions.resendContent.trim().length>0?r.providerOptions.resendContent.trim():typeof l?.fallbackContent==="string"&&l.fallbackContent.trim().length>0?l.fallbackContent.trim():void 0,F={templateCode:s,reserve:i,...a?{sendDate:a}:{},list:[{phone:m,templateParam:T.length>0?T:void 0}],reSend:f,...v?{resendCallback:v}:{},...D??C?{resendType:D??C}:{},...A?{resendTitle:A}:{},...q?{resendContent:q}:{}},j=`${n.baseUrl}${ge(n)}`;try{let R=await fetch(j,{method:"POST",headers:k(n),body:JSON.stringify(F)}),te=await R.text(),$=_(te),P=O($)?$:{code:V($)??R.status,message:te||String($||"")};if(!R.ok||P.code!==200)return o.fail(new o.KMsgError(M(P.code),P.message||"IWINV send failed",{providerId:t,originalCode:P.code}));return o.ok({messageId:r.messageId||crypto.randomUUID(),providerId:t,providerMessageId:typeof P.seqNo==="number"?String(P.seqNo):void 0,status:u?"PENDING":"SENT",type:r.type,to:r.to,raw:P})}catch(R){return o.fail(new o.KMsgError(o.KMsgErrorCode.NETWORK_ERROR,R instanceof Error?R.message:String(R),{providerId:t}))}}async function qe(e){let{providerId:t,config:n,options:r,to:s,from:d,text:u,scheduledAtValid:i,scheduledAt:a}=e;if(r.type!=="MMS")return o.fail(new o.KMsgError(o.KMsgErrorCode.INVALID_REQUEST,"IWINVProvider: MMS handler called with non-MMS options",{providerId:t,type:r.type}));let m=le(u,r.subject),b=Oe(r,t);if(b.isFailure)return b;let T=b.value;if(!T)return o.fail(new o.KMsgError(o.KMsgErrorCode.INVALID_REQUEST,"image is required for MMS; caller must provide options.media.image.blob or bytes",{providerId:t}));let l;try{l=await xe(T)}catch(f){return o.fail(f instanceof o.KMsgError?f:new o.KMsgError(o.KMsgErrorCode.NETWORK_ERROR,f instanceof Error?f.message:String(f),{providerId:t}))}if(l.size>102400)return o.fail(new o.KMsgError(o.KMsgErrorCode.INVALID_REQUEST,"MMS image must be <= 100KB",{providerId:t,bytes:l.size}));let I=new FormData;if(I.append("version","1.0"),I.append("from",d),I.append("to",s),I.append("title",m),I.append("text",u),i&&a)I.append("date",ie(a));I.append("image",l.blob,_e(l));let g={secret:H(n)};if(typeof n.xForwardedFor==="string"&&n.xForwardedFor.length>0)g["X-Forwarded-For"]=n.xForwardedFor;let S={...g};if(n.extraHeaders&&typeof n.extraHeaders==="object")for(let[f,w]of Object.entries(n.extraHeaders)){if(f.toLowerCase()==="content-type")continue;S[f]=w}let E=`${K()}/api/v2/send/`;try{let f=await fetch(E,{method:"POST",headers:S,body:I}),w=await f.text(),v=_(w),N=O(v)?v:{resultCode:v},D=N.resultCode??N.code,C=de(D),A=typeof N.message==="string"&&N.message.length>0?N.message:pe(C,"MMS send failed");if(!(f.ok&&C==="0"))return o.fail(new o.KMsgError(ce(C,f.ok),A,{providerId:t,originalCode:D}));let F=typeof N.requestNo==="string"&&N.requestNo.length>0?N.requestNo:typeof N.msgid==="string"&&N.msgid.length>0?N.msgid:void 0;return o.ok({messageId:r.messageId||crypto.randomUUID(),providerId:t,providerMessageId:F,status:i?"PENDING":"SENT",type:r.type,to:r.to,raw:N})}catch(f){return o.fail(new o.KMsgError(o.KMsgErrorCode.NETWORK_ERROR,f instanceof Error?f.message:String(f),{providerId:t}))}}async function Me(e){let{providerId:t,config:n,options:r}=e;if(!Q(n))return o.fail(new o.KMsgError(o.KMsgErrorCode.INVALID_REQUEST,"SMS v2 configuration missing (smsApiKey/smsAuthKey)",{providerId:t}));let s=U(r.to);if(!s)return o.fail(new o.KMsgError(o.KMsgErrorCode.INVALID_REQUEST,"to is required",{providerId:t}));let d=r.text;if(!d||d.trim().length===0)return o.fail(new o.KMsgError(o.KMsgErrorCode.INVALID_REQUEST,"text is required for SMS/LMS/MMS",{providerId:t}));let u=(typeof r.from==="string"&&r.from.length>0?r.from:n.smsSenderNumber||n.senderNumber)||"",i=u?U(u):"";if(!i)return o.fail(new o.KMsgError(o.KMsgErrorCode.INVALID_REQUEST,"from is required for SMS/LMS/MMS (options.from or config.smsSenderNumber)",{providerId:t}));let a=r.options?.scheduledAt,m=a instanceof Date&&!Number.isNaN(a.getTime());if(r.type==="MMS")return await qe({providerId:t,config:n,options:r,to:s,from:i,text:d,scheduledAtValid:m,scheduledAt:m?a:void 0});let b={version:"1.0",from:i,to:[s],text:d};if(r.type==="LMS")b.title=le(d,r.subject);else{let g=typeof r.providerOptions?.msgType==="string"&&r.providerOptions.msgType.trim().length>0?r.providerOptions.msgType.trim():void 0;b.msgType=g||r.type}if(m)b.date=ie(a);let l={"Content-Type":"application/json;charset=UTF-8",secret:H(n)};if(typeof n.xForwardedFor==="string"&&n.xForwardedFor.length>0)l["X-Forwarded-For"]=n.xForwardedFor;let I=n.extraHeaders&&typeof n.extraHeaders==="object"?{...l,...n.extraHeaders}:l,h=`${K()}/api/v2/send/`;try{let g=await fetch(h,{method:"POST",headers:I,body:JSON.stringify(b)}),S=await g.text(),E=_(S),f=O(E)?E:{resultCode:E},w=f.resultCode??f.code,v=de(w),N=typeof f.message==="string"&&f.message.length>0?f.message:pe(v,"SMS send failed");if(!(g.ok&&v==="0"))return o.fail(new o.KMsgError(ce(v,g.ok),N,{providerId:t,originalCode:w}));let C=typeof f.requestNo==="string"&&f.requestNo.length>0?f.requestNo:typeof f.msgid==="string"&&f.msgid.length>0?f.msgid:void 0;return o.ok({messageId:r.messageId||crypto.randomUUID(),providerId:t,providerMessageId:C,status:m?"PENDING":"SENT",type:r.type,to:r.to,raw:f})}catch(g){return o.fail(new o.KMsgError(o.KMsgErrorCode.NETWORK_ERROR,g instanceof Error?g.message:String(g),{providerId:t}))}}function ze(e){return{...e,baseUrl:Re,sendEndpoint:e.sendEndpoint||"/api/v2/send/"}}function me(){return{apiKey:c.readRuntimeEnv("IWINV_API_KEY")||"",smsApiKey:c.readRuntimeEnv("IWINV_SMS_API_KEY"),smsAuthKey:c.readRuntimeEnv("IWINV_SMS_AUTH_KEY"),smsCompanyId:c.readRuntimeEnv("IWINV_SMS_COMPANY_ID"),senderNumber:c.readRuntimeEnv("IWINV_SENDER_NUMBER")||c.readRuntimeEnv("IWINV_SMS_SENDER_NUMBER"),smsSenderNumber:c.readRuntimeEnv("IWINV_SMS_SENDER_NUMBER"),sendEndpoint:c.readRuntimeEnv("IWINV_SEND_ENDPOINT")||"/api/v2/send/",xForwardedFor:c.readRuntimeEnv("IWINV_X_FORWARDED_FOR"),debug:c.readRuntimeEnv("NODE_ENV")==="development"}}class J{id="iwinv";name="IWINV Messaging Provider";supportedTypes;config;getOnboardingSpec(){let e=Ee(this.id);if(!e)throw new c.KMsgError(c.KMsgErrorCode.INVALID_REQUEST,`Onboarding spec missing for provider: ${this.id}`,{providerId:this.id});return e}constructor(e){if(!e||typeof e!=="object")throw new c.KMsgError(c.KMsgErrorCode.INVALID_REQUEST,"IWINVProvider requires a config object",{providerId:this.id});if(!e.apiKey||e.apiKey.length===0)throw new c.KMsgError(c.KMsgErrorCode.INVALID_REQUEST,"IWINVProvider requires `apiKey` configuration",{providerId:this.id});this.config=ze(e);let t=["ALIMTALK"];if(Q(this.config))t.push("SMS","LMS","MMS");this.supportedTypes=t}async healthCheck(){let e=Date.now(),t=[];try{try{new URL(this.config.baseUrl)}catch{t.push("Invalid baseUrl")}if(Q(this.config))try{new URL(K())}catch{t.push("Invalid smsBaseUrl")}return{healthy:t.length===0,issues:t,latencyMs:Date.now()-e,data:{provider:this.id,baseUrl:this.config.baseUrl,smsBaseUrl:K()}}}catch(n){return t.push(n instanceof Error?n.message:String(n)),{healthy:!1,issues:t,latencyMs:Date.now()-e}}}async send(e){let t=e.messageId||crypto.randomUUID(),n={...e,messageId:t};switch(n.type){case"ALIMTALK":return ke({providerId:this.id,config:this.config,options:n});case"SMS":case"LMS":case"MMS":return Me({providerId:this.id,config:this.config,options:n});default:return c.fail(new c.KMsgError(c.KMsgErrorCode.INVALID_REQUEST,`IWINVProvider does not support type ${n.type}`,{providerId:this.id,type:n.type}))}}async getDeliveryStatus(e){switch(e.type){case"ALIMTALK":return Ae({providerId:this.id,config:this.config,query:e});case"SMS":case"LMS":case"MMS":return De({providerId:this.id,config:this.config,query:e});default:return c.fail(new c.KMsgError(c.KMsgErrorCode.INVALID_REQUEST,`IWINVProvider does not support type ${e.type}`,{providerId:this.id,type:e.type}))}}async getBalance(e){let t=e?.channel??"ALIMTALK";switch(t){case"ALIMTALK":return this.getAlimTalkBalance(t);case"SMS":case"LMS":case"MMS":return this.getSmsBalance(t);default:return c.fail(new c.KMsgError(c.KMsgErrorCode.INVALID_REQUEST,`IWINVProvider does not support balance query for type ${t}`,{providerId:this.id,type:t}))}}async getAlimTalkBalance(e){let t=`${this.config.baseUrl}/api/charge/`;try{let n=await fetch(t,{method:"POST",headers:k(this.config),body:JSON.stringify({})}),r=await n.text(),s=_(r),d=z(s,{}),u=d.code,i=typeof u==="string"?Number(u):void 0,a=typeof u==="number"?u:typeof i==="number"&&Number.isFinite(i)?i:void 0,m=typeof d.message==="string"&&d.message.length>0?d.message:"IWINV AlimTalk charge query failed";if(!n.ok||a!==200)return c.fail(new c.KMsgError(M(a??n.status),m,{providerId:this.id,originalCode:u??n.status}));let b=d.charge,T=typeof b==="number"?b:typeof b==="string"?Number(b):NaN;if(!Number.isFinite(T))return c.fail(new c.KMsgError(c.KMsgErrorCode.PROVIDER_ERROR,"Invalid charge value from IWINV AlimTalk charge API",{providerId:this.id,raw:d}));return c.ok({providerId:this.id,channel:e,amount:T,currency:"KRW",raw:d})}catch(n){return c.fail(new c.KMsgError(c.KMsgErrorCode.NETWORK_ERROR,n instanceof Error?n.message:String(n),{providerId:this.id}))}}async getSmsBalance(e){if(!this.config.smsApiKey||!this.config.smsAuthKey)return c.fail(new c.KMsgError(c.KMsgErrorCode.INVALID_REQUEST,"smsApiKey and smsAuthKey are required for SMS/LMS/MMS balance query",{providerId:this.id}));let n={"Content-Type":"application/json;charset=UTF-8",secret:H(this.config)};if(typeof this.config.xForwardedFor==="string"&&this.config.xForwardedFor.length>0)n["X-Forwarded-For"]=this.config.xForwardedFor;let r=this.config.extraHeaders&&typeof this.config.extraHeaders==="object"?{...n,...this.config.extraHeaders}:n,s=`${K()}/api/charge/`;try{let d=await fetch(s,{method:"POST",headers:r,body:JSON.stringify({version:"1.0"})}),u=await d.text(),i=_(u),a=z(i,{}),m=a.code??a.resultCode,b=typeof m==="string"?Number(m):void 0,T=typeof m==="number"?m:typeof b==="number"&&Number.isFinite(b)?b:NaN,l=typeof a.message==="string"&&a.message.length>0?a.message:"IWINV SMS charge query failed";if(!d.ok||T!==0)return c.fail(new c.KMsgError(c.KMsgErrorCode.PROVIDER_ERROR,l,{providerId:this.id,originalCode:m??d.status}));let I=a.charge,h=typeof I==="number"?I:typeof I==="string"?Number(I):NaN;if(!Number.isFinite(h))return c.fail(new c.KMsgError(c.KMsgErrorCode.PROVIDER_ERROR,"Invalid charge value from IWINV SMS charge API",{providerId:this.id,raw:a}));return c.ok({providerId:this.id,channel:e,amount:h,currency:"KRW",raw:a})}catch(d){return c.fail(new c.KMsgError(c.KMsgErrorCode.NETWORK_ERROR,d instanceof Error?d.message:String(d),{providerId:this.id}))}}}var Pt=(e)=>new J(e),He=()=>{let e=me();if(!e.apiKey)throw new c.KMsgError(c.KMsgErrorCode.INVALID_REQUEST,"IWINV_API_KEY environment variable is required",{providerId:"iwinv"});return new J(e)};class $e{static create(e){return new J(e)}static createDefault(){return He()}}class W extends J{async createTemplate(e,t){return be({providerId:this.id,config:this.config,input:e})}async updateTemplate(e,t,n){return Se({providerId:this.id,config:this.config,code:e,patch:t,ctx:n})}async deleteTemplate(e,t){return Ne({providerId:this.id,config:this.config,code:e})}async getTemplate(e,t){return ee({providerId:this.id,config:this.config,code:e,ctx:t})}async listTemplates(e,t){return Te({providerId:this.id,config:this.config,query:e,ctx:t})}}var Ut=(e)=>new W(e),Be=()=>{let e=me();return new W(e)};class Qe{static create(e){return new W(e)}static createDefault(){return Be()}}function Kt(){}var We={SUCCESS:200,AUTH_FAILED:201,BAD_REQUEST:400,UNAUTHORIZED:401,FORBIDDEN:403,NOT_FOUND:404,TOO_MANY_REQUESTS:429,INTERNAL_SERVER_ERROR:500};
|
|
2
2
|
|
|
3
|
-
//# debugId=
|
|
3
|
+
//# debugId=D8D3AF573343E24964756E2164756E21
|
|
4
4
|
//# sourceMappingURL=index.js.map
|