UNPKG

@k-msg/provider

Version:

Complete provider system with adapters and implementations for K-Message platform

5 lines (3 loc) 36.8 kB
var{defineProperty:me,getOwnPropertyNames:He,getOwnPropertyDescriptor:$e}=Object,Be=Object.prototype.hasOwnProperty;var Ee=new WeakMap,Qe=(e)=>{var t=Ee.get(e),n;if(t)return t;if(t=me({},"__esModule",{value:!0}),e&&typeof e==="object"||typeof e==="function")He(e).map((r)=>!Be.call(t,r)&&me(t,r,{get:()=>e[r],enumerable:!(n=$e(e,r))||n.enumerable}));return Ee.set(e,t),t};var We=(e,t)=>{for(var n in t)me(e,n,{get:t[n],enumerable:!0,configurable:!0,set:(r)=>t[n]=()=>r})};var ot={};We(ot,{updateTemplate:()=>ae,listTemplates:()=>pe,getTemplate:()=>X,deleteTemplate:()=>de,createTemplate:()=>ie,createIWINVTemplateProvider:()=>st,createDefaultIWINVTemplateProvider:()=>Ke,IWINVTemplateProviderFactory:()=>ze,IWINVTemplateProvider:()=>se});module.exports=Qe(ot);var ee=require("@k-msg/core");var oe="https://alimtalk.bizservice.iwinv.kr",Re="https://sms.bizservice.iwinv.kr";var p=require("@k-msg/core"),be=require("@k-msg/template/send");function x(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function _(e){if(!e)return{};try{return JSON.parse(e)}catch{return e}}function $(e,t){return x(e)?e:t}var q=require("@k-msg/core");function je(e){let t="",n=0;while(n<e.length){let r=e[n++]??0,s=e[n++]??0,i=e[n++]??0,c=r<<16|s<<8|i;t+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[c>>18&63],t+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[c>>12&63],t+=n-2<e.length?"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[c>>6&63]:"=",t+=n-1<e.length?"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[c&63]:"="}return t}function te(e){return je(new TextEncoder().encode(e))}function Ae(e){let t=e.sendEndpoint||"/api/v2/send/";return t.startsWith("/")?t:`/${t}`}function P(e){let n={AUTH:te(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 q.KMsgErrorCode.AUTHENTICATION_FAILED;case 429:return q.KMsgErrorCode.RATE_LIMIT_EXCEEDED;case 519:return q.KMsgErrorCode.INSUFFICIENT_BALANCE;case 404:case 501:return q.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 q.KMsgErrorCode.INVALID_REQUEST;case 518:return q.KMsgErrorCode.PROVIDER_ERROR;default:if(e>=500)return q.KMsgErrorCode.PROVIDER_ERROR;return q.KMsgErrorCode.INVALID_REQUEST}}function F(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 Ce(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 fe(e){switch(typeof e==="string"?e.trim().toUpperCase():""){case"Y":return"APPROVED";case"I":return"INSPECTION";case"R":return"REJECTED";default:return"PENDING"}}function ge(e,t){return new Date(e.getTime()+t*24*60*60*1000)}function ye(e){let t=(n)=>n.toString().padStart(2,"0");return`${e.getFullYear()}-${t(e.getMonth()+1)}-${t(e.getDate())}`}function j(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]),i=Number(n[3]),c=Number(n[4]),a=Number(n[5]),o=Number(n[6]);if(!Number.isFinite(r)||!Number.isFinite(s)||!Number.isFinite(i)||!Number.isFinite(c)||!Number.isFinite(a)||!Number.isFinite(o))return;let m=new Date(r,s-1,i,c,a,o);if(Number.isNaN(m.getTime()))return;return m}function ne(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 re(e){let t=await e.text(),n=_(t);return $(n,{code:F(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 ie(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=be.validateTemplatePayload(r,{requireName:!0,requireContent:!0});if(s.isFailure)return p.fail(De(s.error,t));let i=`${n.baseUrl}/api/template/add/`,c={templateName:s.value.name??r.name,templateContent:s.value.content??r.content,...s.value.buttons?{buttons:s.value.buttons}:{}};try{let a=await fetch(i,{method:"POST",headers:P(n),body:JSON.stringify(c)}),o=await re(a),m=F(o.code)??a.status,I=typeof o.message==="string"&&o.message.length>0?o.message:"IWINV template create failed";if(!a.ok||m!==200)return p.fail(new p.KMsgError(M(m),I,{providerId:t,originalCode:m}));let b=o.templateCode,N=typeof b==="string"&&b.trim().length>0?b.trim():"";if(!N)return p.fail(new p.KMsgError(p.KMsgErrorCode.PROVIDER_ERROR,"IWINV template create did not return templateCode",{providerId:t,raw:o}));let d=new Date;return p.ok({id:N,code:N,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:d,updatedAt:d})}catch(a){return p.fail(new p.KMsgError(p.KMsgErrorCode.NETWORK_ERROR,a instanceof Error?a.message:String(a),{providerId:t}))}}async function ae(e){let{providerId:t,config:n,code:r,patch:s,ctx:i}=e,c=typeof r==="string"?r.trim():"";if(!c)return p.fail(new p.KMsgError(p.KMsgErrorCode.INVALID_REQUEST,"code is required",{providerId:t}));let a=await X({providerId:t,config:n,code:c,ctx:i});if(a.isFailure)return a;let o=a.value,m=typeof s.name==="string"&&s.name.trim().length>0?s.name.trim():o.name,I=typeof s.content==="string"&&s.content.trim().length>0?s.content:o.content,b=s.buttons!==void 0?s.buttons:o.buttons,N=be.validateTemplatePayload({name:m,content:I,buttons:b},{requireName:!0,requireContent:!0});if(N.isFailure)return p.fail(De(N.error,t));let d=`${n.baseUrl}/api/template/modify/`,w={templateCode:c,templateName:N.value.name??m,templateContent:N.value.content??I,...N.value.buttons?{buttons:N.value.buttons}:{}};try{let T=await fetch(d,{method:"POST",headers:P(n),body:JSON.stringify(w)}),f=await re(T),v=F(f.code)??T.status,A=typeof f.message==="string"&&f.message.length>0?f.message:"IWINV template update failed";if(!T.ok||v!==200)return p.fail(new p.KMsgError(M(v),A,{providerId:t,originalCode:v}));let g=await X({providerId:t,config:n,code:c,ctx:i});if(g.isSuccess)return g;return p.ok({...o,name:N.value.name??m,content:N.value.content??I,...s.category!==void 0?{category:s.category}:{},...s.variables!==void 0?{variables:s.variables}:{},...s.buttons!==void 0?{buttons:N.value.buttons}:{},updatedAt:new Date})}catch(T){return p.fail(new p.KMsgError(p.KMsgErrorCode.NETWORK_ERROR,T instanceof Error?T.message:String(T),{providerId:t}))}}async function de(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 i=`${n.baseUrl}/api/template/delete/`,c={templateCode:s};try{let a=await fetch(i,{method:"POST",headers:P(n),body:JSON.stringify(c)}),o=await re(a),m=F(o.code)??a.status,I=typeof o.message==="string"&&o.message.length>0?o.message:typeof o.messgae==="string"&&o.messgae.length>0?o.messgae:"IWINV template delete failed";if(!a.ok||m!==200)return p.fail(new p.KMsgError(M(m),I,{providerId:t,originalCode:m}));return p.ok(void 0)}catch(a){return p.fail(new p.KMsgError(p.KMsgErrorCode.NETWORK_ERROR,a instanceof Error?a.message:String(a),{providerId:t}))}}async function X(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 i={pageNum:"1",pageSize:"15",templateCode:s},c=`${n.baseUrl}/api/template/`;try{let a=await fetch(c,{method:"POST",headers:P(n),body:JSON.stringify(i)}),o=await re(a),m=F(o.code)??a.status,I=typeof o.message==="string"&&o.message.length>0?o.message:"IWINV template get failed";if(!a.ok||m!==200)return p.fail(new p.KMsgError(M(m),I,{providerId:t,originalCode:m}));let b=o.list,d=(Array.isArray(b)?b:[]).find(x);if(!d)return p.fail(new p.KMsgError(p.KMsgErrorCode.TEMPLATE_NOT_FOUND,"Template not found",{providerId:t,templateCode:s}));let w=d.templateCode,T=typeof w==="string"?w:String(w??""),f=typeof d.templateName==="string"?d.templateName:"",v=typeof d.templateContent==="string"?d.templateContent:"",A=fe(d.status),g=j(d.createDate)??new Date;return p.ok({id:T,code:T,name:f,content:v,status:A,buttons:Array.isArray(d.buttons)?d.buttons:void 0,createdAt:g,updatedAt:g})}catch(a){return p.fail(new p.KMsgError(p.KMsgErrorCode.NETWORK_ERROR,a instanceof Error?a.message:String(a),{providerId:t}))}}async function pe(e){let{providerId:t,config:n,query:r}=e,s=typeof r?.page==="number"&&r.page>0?Math.floor(r.page):1,i=typeof r?.limit==="number"&&r.limit>0?Math.floor(r.limit):15,c=Ce(r?.status),a={pageNum:String(s),pageSize:String(i),...c?{templateStatus:c}:{}},o=`${n.baseUrl}/api/template/`;try{let m=await fetch(o,{method:"POST",headers:P(n),body:JSON.stringify(a)}),I=await re(m),b=F(I.code)??m.status,N=typeof I.message==="string"&&I.message.length>0?I.message:"IWINV template list failed";if(!m.ok||b!==200)return p.fail(new p.KMsgError(M(b),N,{providerId:t,originalCode:b}));let d=I.list,T=(Array.isArray(d)?d:[]).filter(x).map((f)=>{let v=f.templateCode,A=typeof v==="string"?v:String(v??""),g=typeof f.templateName==="string"?f.templateName:"",C=typeof f.templateContent==="string"?f.templateContent:"",h=fe(f.status),S=j(f.createDate)??new Date;return{id:A,code:A,name:g,content:C,status:h,buttons:Array.isArray(f.buttons)?f.buttons:void 0,createdAt:S,updatedAt:S}}).filter((f)=>f.code.length>0);return p.ok(T)}catch(m){return p.fail(new p.KMsgError(p.KMsgErrorCode.NETWORK_ERROR,m instanceof Error?m.message:String(m),{providerId:t}))}}var u=require("@k-msg/core");var xe={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 Oe(e){return xe[e]}function Nt(){return Object.values(xe)}var y=require("@k-msg/core");var U=require("@k-msg/core");function Ye(e){if(typeof DOMException<"u"&&e instanceof DOMException&&e.name==="TimeoutError")return!0;return typeof e==="object"&&e!==null&&"code"in e&&e.code===U.KMsgErrorCode.NETWORK_TIMEOUT}function Je(e){return typeof DOMException<"u"&&e instanceof DOMException&&e.name==="AbortError"}function Ge(e){if(e instanceof Error)return e.message;if(typeof e==="string"&&e.length>0)return e;return"Provider request aborted"}function Xe(e,t,n){if(!t?.aborted)return;if(e instanceof U.KMsgError)return e;let r=t.reason??e,s=Je(r)?e:r;return new U.KMsgError(Ye(r)?U.KMsgErrorCode.NETWORK_TIMEOUT:U.KMsgErrorCode.REQUEST_ABORTED,Ge(s),{providerId:n})}function ue(e,t){if(e instanceof U.KMsgError)return e;return new U.KMsgError(U.KMsgErrorCode.NETWORK_ERROR,e instanceof Error?e.message:String(e),{providerId:t})}function B(e,t,n){return Xe(e,t,n)??ue(e,n)}async function Y(e,t,n,r){let s=e?.fetch??globalThis.fetch;if(typeof s!=="function")throw ue(Error("No fetch implementation is available; provide ProviderRequestContext.fetch or use a runtime with native fetch support"),r);try{return await s(t,{...n,signal:e?.signal})}catch(i){throw B(i,e?.signal,r)}}var Z=require("@k-msg/core");function K(e){return e.replace(/[^0-9]/g,"")}function z(){return Re}function Q(e){if(e.smsApiKey&&e.smsAuthKey)return te(`${e.smsApiKey}&${e.smsAuthKey}`);let t=e.smsAuthKey||e.smsApiKey;if(!t)return"";return te(`${e.apiKey}&${t}`)}function J(e){return Q(e).length>0}function Se(e){if(typeof e==="number"&&Number.isFinite(e))return e.toString();if(typeof e==="string")return e.trim();return""}function Ne(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 we(e,t){if(e==="14"||e==="15"||e==="202"||e==="206")return Z.KMsgErrorCode.AUTHENTICATION_FAILED;if(e==="50")return Z.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 Z.KMsgErrorCode.INVALID_REQUEST;if(!t)return Z.KMsgErrorCode.NETWORK_ERROR;return Z.KMsgErrorCode.PROVIDER_ERROR}function Te(e,t){if(t&&t.trim().length>0)return t.trim();return e.slice(0,20)}function ke(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 _e(e){let{providerId:t,config:n,query:r,context:s}=e,i=r.providerMessageId.trim();if(!i)return y.fail(new y.KMsgError(y.KMsgErrorCode.INVALID_REQUEST,"providerMessageId is required",{providerId:t}));let c=K(r.to);if(!c)return y.fail(new y.KMsgError(y.KMsgErrorCode.INVALID_REQUEST,"to is required",{providerId:t}));let a=Number(i),o=Number.isFinite(a)?a:void 0,m=ne(ge(r.requestedAt,-1)),I=ne(new Date),b={pageNum:1,pageSize:15,phone:c,startDate:m,endDate:I,...o!==void 0?{seqNo:o}:{},...r.scheduledAt instanceof Date&&!Number.isNaN(r.scheduledAt.getTime())?{reserve:"Y"}:{}},N=`${n.baseUrl}/api/history/`;try{let d=await Y(s,N,{method:"POST",headers:P(n),body:JSON.stringify(b)},t),w=await d.text(),T=_(w),f=$(T,{}),v=f.code,A=typeof v==="number"?v:void 0,g=typeof f.message==="string"&&f.message.length>0?f.message:"IWINV history query failed";if(!d.ok||A!==200)return y.fail(new y.KMsgError(M(A??F(T)??d.status),g,{providerId:t,originalCode:v??d.status}));let C=f.list,h=Array.isArray(C)?C:[];if(h.length===0)return y.ok(null);let S=(()=>{if(o===void 0)return h[0];return h.find((R)=>x(R)&&R.seqNo===o)??h[0]})();if(!x(S))return y.ok(null);let O=typeof S.statusCode==="string"?S.statusCode:void 0,D=typeof S.statusCodeName==="string"?S.statusCodeName:void 0,E=j(S.sendDate),H=j(S.receiveDate),L=O==="OK"||typeof D==="string"&&D.includes("성공");return y.ok({providerId:t,providerMessageId:i,status:L?"DELIVERED":E?"FAILED":"PENDING",statusCode:O,statusMessage:D,sentAt:E,deliveredAt:L?H||E:void 0,failedAt:!L&&E?E:void 0,raw:S})}catch(d){return y.fail(B(d,s?.signal,t))}}async function Pe(e){let{providerId:t,config:n,query:r,context:s}=e;if(!J(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 i=r.providerMessageId.trim();if(!i)return y.fail(new y.KMsgError(y.KMsgErrorCode.INVALID_REQUEST,"providerMessageId is required",{providerId:t}));let c=K(r.to);if(!c)return y.fail(new y.KMsgError(y.KMsgErrorCode.INVALID_REQUEST,"to is required",{providerId:t}));let a=ge(r.requestedAt,-1),o=new Date;if(o.getTime()-a.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:ye(a),endDate:ye(o),requestNo:i,pageNum:1,pageSize:15,phone:c},d={"Content-Type":"application/json;charset=UTF-8",secret:Q(n)};if(typeof n.xForwardedFor==="string"&&n.xForwardedFor.length>0)d["X-Forwarded-For"]=n.xForwardedFor;let w=n.extraHeaders&&typeof n.extraHeaders==="object"?{...d,...n.extraHeaders}:d,T=`${z()}/api/history/`;try{let f=await Y(s,T,{method:"POST",headers:w,body:JSON.stringify(b)},t),v=await f.text(),A=_(v),g=$(A,{}),C=g.resultCode,h=typeof C==="number"?C:typeof C==="string"?Number(C):NaN,S=typeof g.message==="string"&&g.message.length>0?g.message:"IWINV SMS history query failed";if(!f.ok||h!==0)return y.fail(new y.KMsgError(y.KMsgErrorCode.PROVIDER_ERROR,S,{providerId:t,originalCode:C??f.status}));let O=g.list,D=Array.isArray(O)?O:[];if(D.length===0)return y.ok(null);let E=(()=>{return D.find((W)=>{if(!x(W))return!1;let V=W.requestNo;return V!==void 0&&V!==null?String(V)===i:!1})??D[0]})();if(!x(E))return y.ok(null);let H=typeof E.sendStatusCode==="string"?E.sendStatusCode:void 0,L=typeof E.sendStatusMsg==="string"?E.sendStatusMsg:typeof E.sendStatus==="string"?E.sendStatus:void 0,G=j(E.sendDate),R=ke(H,L);return y.ok({providerId:t,providerMessageId:i,status:R,statusCode:H,statusMessage:L,sentAt:G,deliveredAt:R==="DELIVERED"?G:void 0,failedAt:R==="FAILED"?G:void 0,raw:E})}catch(f){return y.fail(B(f,s?.signal,t))}}var l=require("@k-msg/core");var k=require("@k-msg/core");function Me(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 ve(e){switch(Me(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 k.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 k.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 k.fail(new k.KMsgError(k.KMsgErrorCode.INVALID_REQUEST,"IWINV MMS caller must provide blob/bytes in options.media.image",{providerId:t,field:"media.image.ref"}))}let i=n.imageUrl;if(typeof i==="string"&&i.trim().length>0)return k.fail(new k.KMsgError(k.KMsgErrorCode.INVALID_REQUEST,"IWINV MMS caller must provide blob/bytes in options.media.image",{providerId:t,field:"imageUrl"}));return k.ok(void 0)}async function Fe(e){if("blob"in e){let i=e.contentType||e.blob.type||"application/octet-stream",c=e.filename||"image",a=e.contentType&&e.contentType!==e.blob.type?new Blob([await e.blob.arrayBuffer()],{type:i}):e.blob;return{blob:a,filename:c,contentType:i,size:a.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 Le(e){if(Me(e.filename).length>0)return e.filename;let n=ve(e.filename)==="image/png"?".png":ve(e.filename)==="image/gif"?".gif":ve(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 Ue(e){let{providerId:t,config:n,options:r,context:s}=e,i=r.templateId;if(!i||i.length===0)return l.fail(new l.KMsgError(l.KMsgErrorCode.INVALID_REQUEST,"templateId is required for ALIMTALK",{providerId:t}));let c=r.options?.scheduledAt,a=c instanceof Date&&!Number.isNaN(c.getTime()),o=a?"Y":"N",m=a?ne(c):void 0,I=K(r.to);if(!I)return l.fail(new l.KMsgError(l.KMsgErrorCode.INVALID_REQUEST,"to is required",{providerId:t}));let b=r.providerOptions?.templateParam,N=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)),d=r.failover,w=(typeof r.from==="string"&&r.from.length>0?r.from:n.senderNumber||n.smsSenderNumber)||"",T=w?K(w):"",f=typeof r.providerOptions?.reSend==="string"?r.providerOptions.reSend.trim().toUpperCase():"",v=f==="Y"||f==="N"?f:void 0,A=d?.enabled===!0?"Y":d?.enabled===!1?"N":void 0,g=v??A??(T?"Y":"N"),h=(typeof r.providerOptions?.resendCallback==="string"?K(r.providerOptions.resendCallback):"")||T;if(g==="Y"&&!h)return l.fail(new l.KMsgError(l.KMsgErrorCode.INVALID_REQUEST,"resendCallback is required when reSend is 'Y' (options.from or providerOptions.resendCallback)",{providerId:t}));let S=typeof r.providerOptions?.resendType==="string"?r.providerOptions.resendType.trim().toUpperCase():"",O=S==="Y"||S==="N"?S:void 0;if(typeof r.providerOptions?.resendType==="string"&&r.providerOptions.resendType.length>0&&!O)return l.fail(new l.KMsgError(l.KMsgErrorCode.INVALID_REQUEST,"resendType must be 'Y' or 'N'",{providerId:t}));let D=d?.fallbackChannel==="lms"?"Y":d?.fallbackChannel==="sms"?"N":void 0,E=typeof r.providerOptions?.resendTitle==="string"&&r.providerOptions.resendTitle.trim().length>0?r.providerOptions.resendTitle.trim():typeof d?.fallbackTitle==="string"&&d.fallbackTitle.trim().length>0?d.fallbackTitle.trim():void 0,H=typeof r.providerOptions?.resendContent==="string"&&r.providerOptions.resendContent.trim().length>0?r.providerOptions.resendContent.trim():typeof d?.fallbackContent==="string"&&d.fallbackContent.trim().length>0?d.fallbackContent.trim():void 0,L={templateCode:i,reserve:o,...m?{sendDate:m}:{},list:[{phone:I,templateParam:N.length>0?N:void 0}],reSend:g,...h?{resendCallback:h}:{},...O??D?{resendType:O??D}:{},...E?{resendTitle:E}:{},...H?{resendContent:H}:{}},G=`${n.baseUrl}${Ae(n)}`;try{let R=await Y(s,G,{method:"POST",headers:P(n),body:JSON.stringify(L)},t),le=await R.text(),W=_(le),V=x(W)?W:{code:F(W)??R.status,message:le||String(W||"")};if(!R.ok||V.code!==200)return l.fail(new l.KMsgError(M(V.code),V.message||"IWINV send failed",{providerId:t,originalCode:V.code}));return l.ok({messageId:r.messageId||crypto.randomUUID(),providerId:t,providerMessageId:typeof V.seqNo==="number"?String(V.seqNo):void 0,status:a?"PENDING":"SENT",type:r.type,to:r.to,raw:V})}catch(R){return l.fail(B(R,s?.signal,t))}}async function Ze(e){let{providerId:t,config:n,options:r,to:s,from:i,text:c,scheduledAtValid:a,scheduledAt:o,context:m}=e;if(r.type!=="MMS")return l.fail(new l.KMsgError(l.KMsgErrorCode.INVALID_REQUEST,"IWINVProvider: MMS handler called with non-MMS options",{providerId:t,type:r.type}));let I=Te(c,r.subject),b=Ve(r,t);if(b.isFailure)return b;let N=b.value;if(!N)return l.fail(new l.KMsgError(l.KMsgErrorCode.INVALID_REQUEST,"image is required for MMS; caller must provide options.media.image.blob or bytes",{providerId:t}));let d;try{d=await Fe(N)}catch(g){return l.fail(ue(g,t))}if(d.size>102400)return l.fail(new l.KMsgError(l.KMsgErrorCode.INVALID_REQUEST,"MMS image must be <= 100KB",{providerId:t,bytes:d.size}));let w=new FormData;if(w.append("version","1.0"),w.append("from",i),w.append("to",s),w.append("title",I),w.append("text",c),a&&o)w.append("date",Ie(o));w.append("image",d.blob,Le(d));let f={secret:Q(n)};if(typeof n.xForwardedFor==="string"&&n.xForwardedFor.length>0)f["X-Forwarded-For"]=n.xForwardedFor;let v={...f};if(n.extraHeaders&&typeof n.extraHeaders==="object")for(let[g,C]of Object.entries(n.extraHeaders)){if(g.toLowerCase()==="content-type")continue;v[g]=C}let A=`${z()}/api/v2/send/`;try{let g=await Y(m,A,{method:"POST",headers:v,body:w},t),C=await g.text(),h=_(C),S=x(h)?h:{resultCode:h},O=S.resultCode??S.code,D=Se(O),E=typeof S.message==="string"&&S.message.length>0?S.message:Ne(D,"MMS send failed");if(!(g.ok&&D==="0"))return l.fail(new l.KMsgError(we(D,g.ok),E,{providerId:t,originalCode:O}));let L=typeof S.requestNo==="string"&&S.requestNo.length>0?S.requestNo:typeof S.msgid==="string"&&S.msgid.length>0?S.msgid:void 0;return l.ok({messageId:r.messageId||crypto.randomUUID(),providerId:t,providerMessageId:L,status:a?"PENDING":"SENT",type:r.type,to:r.to,raw:S})}catch(g){return l.fail(B(g,m?.signal,t))}}async function qe(e){let{providerId:t,config:n,options:r,context:s}=e;if(!J(n))return l.fail(new l.KMsgError(l.KMsgErrorCode.INVALID_REQUEST,"SMS v2 configuration missing (smsApiKey/smsAuthKey)",{providerId:t}));let i=K(r.to);if(!i)return l.fail(new l.KMsgError(l.KMsgErrorCode.INVALID_REQUEST,"to is required",{providerId:t}));let c=r.text;if(!c||c.trim().length===0)return l.fail(new l.KMsgError(l.KMsgErrorCode.INVALID_REQUEST,"text is required for SMS/LMS/MMS",{providerId:t}));let a=(typeof r.from==="string"&&r.from.length>0?r.from:n.smsSenderNumber||n.senderNumber)||"",o=a?K(a):"";if(!o)return l.fail(new l.KMsgError(l.KMsgErrorCode.INVALID_REQUEST,"from is required for SMS/LMS/MMS (options.from or config.smsSenderNumber)",{providerId:t}));let m=r.options?.scheduledAt,I=m instanceof Date&&!Number.isNaN(m.getTime());if(r.type==="MMS")return await Ze({providerId:t,config:n,options:r,to:i,from:o,text:c,scheduledAtValid:I,scheduledAt:I?m:void 0,context:s});let b={version:"1.0",from:o,to:[i],text:c};if(r.type==="LMS")b.title=Te(c,r.subject);else{let f=typeof r.providerOptions?.msgType==="string"&&r.providerOptions.msgType.trim().length>0?r.providerOptions.msgType.trim():void 0;b.msgType=f||r.type}if(I)b.date=Ie(m);let d={"Content-Type":"application/json;charset=UTF-8",secret:Q(n)};if(typeof n.xForwardedFor==="string"&&n.xForwardedFor.length>0)d["X-Forwarded-For"]=n.xForwardedFor;let w=n.extraHeaders&&typeof n.extraHeaders==="object"?{...d,...n.extraHeaders}:d,T=`${z()}/api/v2/send/`;try{let f=await Y(s,T,{method:"POST",headers:w,body:JSON.stringify(b)},t),v=await f.text(),A=_(v),g=x(A)?A:{resultCode:A},C=g.resultCode??g.code,h=Se(C),S=typeof g.message==="string"&&g.message.length>0?g.message:Ne(h,"SMS send failed");if(!(f.ok&&h==="0"))return l.fail(new l.KMsgError(we(h,f.ok),S,{providerId:t,originalCode:C}));let D=typeof g.requestNo==="string"&&g.requestNo.length>0?g.requestNo:typeof g.msgid==="string"&&g.msgid.length>0?g.msgid:void 0;return l.ok({messageId:r.messageId||crypto.randomUUID(),providerId:t,providerMessageId:D,status:I?"PENDING":"SENT",type:r.type,to:r.to,raw:g})}catch(f){return l.fail(B(f,s?.signal,t))}}function et(e){return{...e,baseUrl:oe,sendEndpoint:e.sendEndpoint||"/api/v2/send/"}}function he(){return{apiKey:u.readRuntimeEnv("IWINV_API_KEY")||"",smsApiKey:u.readRuntimeEnv("IWINV_SMS_API_KEY"),smsAuthKey:u.readRuntimeEnv("IWINV_SMS_AUTH_KEY"),smsCompanyId:u.readRuntimeEnv("IWINV_SMS_COMPANY_ID"),senderNumber:u.readRuntimeEnv("IWINV_SENDER_NUMBER")||u.readRuntimeEnv("IWINV_SMS_SENDER_NUMBER"),smsSenderNumber:u.readRuntimeEnv("IWINV_SMS_SENDER_NUMBER"),sendEndpoint:u.readRuntimeEnv("IWINV_SEND_ENDPOINT")||"/api/v2/send/",xForwardedFor:u.readRuntimeEnv("IWINV_X_FORWARDED_FOR"),debug:u.readRuntimeEnv("NODE_ENV")==="development"}}class ce{id="iwinv";name="IWINV Messaging Provider";supportedTypes;transportCapabilities={abortSignal:"supported",injectableFetch:"supported"};config;getOnboardingSpec(){let e=Oe(this.id);if(!e)throw new u.KMsgError(u.KMsgErrorCode.INVALID_REQUEST,`Onboarding spec missing for provider: ${this.id}`,{providerId:this.id});return e}constructor(e){if(!e||typeof e!=="object")throw new u.KMsgError(u.KMsgErrorCode.INVALID_REQUEST,"IWINVProvider requires a config object",{providerId:this.id});if(!e.apiKey||e.apiKey.length===0)throw new u.KMsgError(u.KMsgErrorCode.INVALID_REQUEST,"IWINVProvider requires `apiKey` configuration",{providerId:this.id});this.config=et(e);let t=["ALIMTALK"];if(J(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(J(this.config))try{new URL(z())}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:z()}}}catch(n){return t.push(n instanceof Error?n.message:String(n)),{healthy:!1,issues:t,latencyMs:Date.now()-e}}}async send(e,t){let n=e.messageId||crypto.randomUUID(),r={...e,messageId:n};switch(r.type){case"ALIMTALK":return Ue({providerId:this.id,config:this.config,options:r,context:t});case"SMS":case"LMS":case"MMS":return qe({providerId:this.id,config:this.config,options:r,context:t});default:return u.fail(new u.KMsgError(u.KMsgErrorCode.INVALID_REQUEST,`IWINVProvider does not support type ${r.type}`,{providerId:this.id,type:r.type}))}}async getDeliveryStatus(e,t){switch(e.type){case"ALIMTALK":return _e({providerId:this.id,config:this.config,query:e,context:t});case"SMS":case"LMS":case"MMS":return Pe({providerId:this.id,config:this.config,query:e,context:t});default:return u.fail(new u.KMsgError(u.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 u.fail(new u.KMsgError(u.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:P(this.config),body:JSON.stringify({})}),r=await n.text(),s=_(r),i=$(s,{}),c=i.code,a=typeof c==="string"?Number(c):void 0,o=typeof c==="number"?c:typeof a==="number"&&Number.isFinite(a)?a:void 0,m=typeof i.message==="string"&&i.message.length>0?i.message:"IWINV AlimTalk charge query failed";if(!n.ok||o!==200)return u.fail(new u.KMsgError(M(o??n.status),m,{providerId:this.id,originalCode:c??n.status}));let I=i.charge,b=typeof I==="number"?I:typeof I==="string"?Number(I):NaN;if(!Number.isFinite(b))return u.fail(new u.KMsgError(u.KMsgErrorCode.PROVIDER_ERROR,"Invalid charge value from IWINV AlimTalk charge API",{providerId:this.id,raw:i}));return u.ok({providerId:this.id,channel:e,amount:b,currency:"KRW",raw:i})}catch(n){return u.fail(new u.KMsgError(u.KMsgErrorCode.NETWORK_ERROR,n instanceof Error?n.message:String(n),{providerId:this.id}))}}async getSmsBalance(e){if(!this.config.smsApiKey||!this.config.smsAuthKey)return u.fail(new u.KMsgError(u.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:Q(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=`${z()}/api/charge/`;try{let i=await fetch(s,{method:"POST",headers:r,body:JSON.stringify({version:"1.0"})}),c=await i.text(),a=_(c),o=$(a,{}),m=o.code??o.resultCode,I=typeof m==="string"?Number(m):void 0,b=typeof m==="number"?m:typeof I==="number"&&Number.isFinite(I)?I:NaN,N=typeof o.message==="string"&&o.message.length>0?o.message:"IWINV SMS charge query failed";if(!i.ok||b!==0)return u.fail(new u.KMsgError(u.KMsgErrorCode.PROVIDER_ERROR,N,{providerId:this.id,originalCode:m??i.status}));let d=o.charge,w=typeof d==="number"?d:typeof d==="string"?Number(d):NaN;if(!Number.isFinite(w))return u.fail(new u.KMsgError(u.KMsgErrorCode.PROVIDER_ERROR,"Invalid charge value from IWINV SMS charge API",{providerId:this.id,raw:o}));return u.ok({providerId:this.id,channel:e,amount:w,currency:"KRW",raw:o})}catch(i){return u.fail(new u.KMsgError(u.KMsgErrorCode.NETWORK_ERROR,i instanceof Error?i.message:String(i),{providerId:this.id}))}}}var Yt=(e)=>new ce(e),tt=()=>{let e=he();if(!e.apiKey)throw new u.KMsgError(u.KMsgErrorCode.INVALID_REQUEST,"IWINV_API_KEY environment variable is required",{providerId:"iwinv"});return new ce(e)};class nt{static create(e){return new ce(e)}static createDefault(){return tt()}}function rt(e){return{...e,baseUrl:oe,sendEndpoint:e.sendEndpoint||"/api/v2/send/"}}class se{id="iwinv";config;constructor(e){if(!e||typeof e!=="object")throw new ee.KMsgError(ee.KMsgErrorCode.INVALID_REQUEST,"IWINVTemplateProvider requires a config object",{providerId:this.id});if(!e.apiKey||e.apiKey.length===0)throw new ee.KMsgError(ee.KMsgErrorCode.INVALID_REQUEST,"IWINVTemplateProvider requires `apiKey` configuration",{providerId:this.id});this.config=rt(e)}async createTemplate(e){return ie({providerId:this.id,config:this.config,input:e})}async updateTemplate(e,t,n){return ae({providerId:this.id,config:this.config,code:e,patch:t,ctx:n})}async deleteTemplate(e){return de({providerId:this.id,config:this.config,code:e})}async getTemplate(e,t){return X({providerId:this.id,config:this.config,code:e,ctx:t})}async listTemplates(e,t){return pe({providerId:this.id,config:this.config,query:e,ctx:t})}}var st=(e)=>new se(e),Ke=()=>{let e=he();return new se(e)};class ze{static create(e){return new se(e)}static createDefault(){return Ke()}} //# debugId=5DC921DB352424C564756E2164756E21 //# sourceMappingURL=template.js.map