@k-msg/core 0.9.0 → 0.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/provider.d.ts +2 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/message.d.ts +1 -0
- package/dist/types/onboarding.d.ts +42 -0
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -42,5 +42,5 @@ ${r.error.stack}`;return n}colorizeLevel(r){if(!this.config.enableColors)return
|
|
|
42
42
|
${o.join(`
|
|
43
43
|
`)}`)}throw i}}static getDefaults(){return Sl.parse({})}}var NU={logger:{level:"DEBUG",enableColors:!0,enableJson:!1},server:{enableDocs:!0}},PU={logger:{level:"INFO",enableColors:!1,enableJson:!0},server:{enableDocs:!1},security:{apiKeyRequired:!0,rateLimitEnabled:!0,maxRequestsPerMinute:1000,enableCors:!0}};function EU(r,i){return Sl.parse({...r,...i,server:{...r.server,...i.server},logger:{...r.logger,...i.logger},providers:{...r.providers,...i.providers},features:{...r.features,...i.features},security:{...r.security,...i.security}})}function jU(r,i){switch(r){case"iwinv":return mc.parse(i);case"sms":return Nc.parse(i);default:throw Error(`Unknown provider: ${r}`)}}var nn;((b)=>{b.INVALID_REQUEST="INVALID_REQUEST";b.AUTHENTICATION_FAILED="AUTHENTICATION_FAILED";b.INSUFFICIENT_BALANCE="INSUFFICIENT_BALANCE";b.TEMPLATE_NOT_FOUND="TEMPLATE_NOT_FOUND";b.RATE_LIMIT_EXCEEDED="RATE_LIMIT_EXCEEDED";b.NETWORK_ERROR="NETWORK_ERROR";b.NETWORK_TIMEOUT="NETWORK_TIMEOUT";b.NETWORK_SERVICE_UNAVAILABLE="NETWORK_SERVICE_UNAVAILABLE";b.PROVIDER_ERROR="PROVIDER_ERROR";b.MESSAGE_SEND_FAILED="MESSAGE_SEND_FAILED";b.UNKNOWN_ERROR="UNKNOWN_ERROR"})(nn||={});class q extends Error{code;details;constructor(r,i,o){super(i);if(this.name="KMsgError",this.code=r,this.details=o,Error.captureStackTrace)Error.captureStackTrace(this,q)}toJSON(){return{name:this.name,code:this.code,message:this.message,details:this.details}}}var Pc={isRetryable:(r)=>{if(r instanceof q)return["NETWORK_ERROR","RATE_LIMIT_EXCEEDED","PROVIDER_ERROR"].includes(r.code);return!1}};class N4{config;startTime=Date.now();services=new Map;lastCheck=new Map;constructor(r={}){this.config=r}registerService(r,i){this.services.set(r,i)}unregisterService(r){return this.lastCheck.delete(r),this.services.delete(r)}clearServices(){this.services.clear(),this.lastCheck.clear()}async checkHealth(){let r=Date.now(),i={},o=!0;for(let[e,n]of this.services)try{let t=await Promise.race([n(),this.timeoutPromise(this.config.timeout||5000)]);if(i[e]={...t,lastCheck:new Date,latency:Date.now()-r},this.lastCheck.set(e,i[e]),!t.healthy)o=!1}catch(t){let v={healthy:!1,error:t instanceof Error?t.message:"Unknown error",lastCheck:new Date,latency:Date.now()-r};i[e]=v,this.lastCheck.set(e,v),o=!1}return{healthy:o,timestamp:new Date,uptime:Date.now()-this.startTime,services:i,...this.config.includeMetrics&&{metrics:{totalServices:this.services.size,healthyServices:Object.values(i).filter((e)=>e.healthy).length,averageLatency:this.calculateAverageLatency(i)}}}}getLastKnownStatus(){let r={},i=!0;for(let[o,e]of this.lastCheck)if(r[o]=e,!e.healthy)i=!1;return{healthy:i,timestamp:new Date,uptime:Date.now()-this.startTime,services:r}}async timeoutPromise(r){return new Promise((i,o)=>{setTimeout(()=>o(Error(`Health check timeout after ${r}ms`)),r)})}calculateAverageLatency(r){let i=Object.values(r).map((o)=>o.latency).filter((o)=>typeof o==="number");return i.length>0?i.reduce((o,e)=>o+e,0)/i.length:0}}class P4{static database(){return async()=>{return{healthy:!0}}}static external(r,i=5000){return async()=>{let o=Date.now();try{let e=await fetch(r,{signal:AbortSignal.timeout(i)});return{healthy:e.ok,latency:Date.now()-o,...e.ok?{}:{error:`HTTP ${e.status}`}}}catch(e){return{healthy:!1,latency:Date.now()-o,error:e instanceof Error?e.message:"Unknown error"}}}}static memory(r=500){return async()=>{let o=process.memoryUsage().heapUsed/1024/1024;return{healthy:o<r,...o>=r?{error:`Memory usage ${o.toFixed(1)}MB exceeds limit ${r}MB`}:{}}}}}class rr{static defaultOptions={maxAttempts:3,initialDelay:1000,maxDelay:30000,backoffMultiplier:2,jitter:!0,retryCondition:(r)=>Pc.isRetryable(r)};static async execute(r,i={}){let o={...rr.defaultOptions,...i},e,n=o.initialDelay;for(let t=1;t<=o.maxAttempts;t++)try{return await r()}catch(v){if(e=v,t===o.maxAttempts||!o.retryCondition(e,t))throw e;let u=o.jitter?n+Math.random()*n*0.1:n;o.onRetry?.(e,t),await new Promise((l)=>setTimeout(l,u)),n=Math.min(n*o.backoffMultiplier,o.maxDelay)}throw e}static createRetryableFunction(r,i={}){return async(...o)=>{return rr.execute(()=>r(...o),i)}}}class ml{static async execute(r,i,o={}){let e={concurrency:5,retryOptions:{maxAttempts:3,initialDelay:1000,maxDelay:1e4,backoffMultiplier:2,jitter:!0},failFast:!1,...o},n=Date.now(),t=[],v=[],u=0,l=rr.createRetryableFunction(i,e.retryOptions),$=ml.createBatches(r,e.concurrency);for(let b of $){let S=b.map(async(O)=>{try{let j=await l(O);t.push({item:O,result:j})}catch(j){if(v.push({item:O,error:j}),e.failFast)throw new q("MESSAGE_SEND_FAILED",`Bulk operation failed fast after ${v.length} failures`,{totalItems:r.length,failedCount:v.length})}finally{u++,e.onProgress?.(u,r.length,v.length)}});if(await Promise.allSettled(S),e.failFast&&v.length>0)break}let c=Date.now()-n;return{successful:t,failed:v,summary:{total:r.length,successful:t.length,failed:v.length,duration:c}}}static createBatches(r,i){let o=[];for(let e=0;e<r.length;e+=i)o.push(r.slice(e,e+i));return o}}class St{options;state="CLOSED";failureCount=0;lastFailureTime=0;nextAttemptTime=0;constructor(r){this.options=r}async execute(r){let i=Date.now();switch(this.state){case"OPEN":if(i<this.nextAttemptTime)throw new q("NETWORK_SERVICE_UNAVAILABLE","Circuit breaker is OPEN",{state:this.state,nextAttemptTime:this.nextAttemptTime});this.state="HALF_OPEN",this.options.onHalfOpen?.();break;case"HALF_OPEN":break;case"CLOSED":break}try{let o=await Promise.race([r(),new Promise((e,n)=>setTimeout(()=>n(new q("NETWORK_TIMEOUT","Circuit breaker timeout",{timeout:this.options.timeout})),this.options.timeout))]);if(this.state==="HALF_OPEN")this.state="CLOSED",this.failureCount=0,this.options.onClose?.();return o}catch(o){throw this.recordFailure(),o}}recordFailure(){if(this.failureCount++,this.lastFailureTime=Date.now(),this.failureCount>=this.options.failureThreshold)this.state="OPEN",this.nextAttemptTime=this.lastFailureTime+this.options.resetTimeout,this.options.onOpen?.()}getState(){return this.state}getFailureCount(){return this.failureCount}reset(){this.state="CLOSED",this.failureCount=0,this.lastFailureTime=0,this.nextAttemptTime=0}}class Ot{maxRequests;windowMs;requests=[];constructor(r,i){this.maxRequests=r;this.windowMs=i}async acquire(){let r=Date.now();if(this.requests=this.requests.filter((i)=>r-i<this.windowMs),this.requests.length>=this.maxRequests){let i=Math.min(...this.requests),o=this.windowMs-(r-i);if(o>0)return await new Promise((e)=>setTimeout(e,o)),this.acquire()}this.requests.push(r)}canMakeRequest(){let r=Date.now();return this.requests=this.requests.filter((i)=>r-i<this.windowMs),this.requests.length<this.maxRequests}getRemainingRequests(){let r=Date.now();return this.requests=this.requests.filter((i)=>r-i<this.windowMs),Math.max(0,this.maxRequests-this.requests.length)}}var E4={createResilientFunction(r,i={}){let o,e;if(i.circuitBreaker)o=new St(i.circuitBreaker);if(i.rateLimiter)e=new Ot(i.rateLimiter.maxRequests,i.rateLimiter.windowMs);return async(...n)=>{if(e)await e.acquire();let t=async()=>{let v=async()=>{if(i.timeout)return Promise.race([r(...n),new Promise((u,l)=>setTimeout(()=>l(new q("NETWORK_TIMEOUT","Operation timed out",{timeout:i.timeout})),i.timeout))]);return r(...n)};if(o)return o.execute(v);return v()};try{return await rr.execute(t,i.retryOptions)}catch(v){if(i.fallback)return console.warn("Primary operation failed, using fallback:",v),i.fallback(...n);throw v}}}};class Ec{fallbackStrategies=new Map;registerFallback(r,i){this.fallbackStrategies.set(r,i)}async executeWithFallback(r,i,o={}){let e=o.timeout||1e4;try{return await Promise.race([rr.execute(i,o.retryOptions),new Promise((t,v)=>setTimeout(()=>v(new q("NETWORK_TIMEOUT",`Operation ${r} timed out`,{operationName:r,timeout:e})),e))])}catch(n){console.warn(`Primary operation ${r} failed, attempting fallback:`,n);let t=this.fallbackStrategies.get(r);if(t)try{return await t()}catch(v){throw new q("UNKNOWN_ERROR",`Both primary and fallback operations failed for ${r}`,{operationName:r,primaryError:n.message,fallbackError:v.message,cause:n})}throw n}}}class jc{services;healthStatus=new Map;lastCheck=new Map;checkInterval;intervalId;constructor(r,i=30000){this.services=r;this.checkInterval=i}start(){this.intervalId=setInterval(()=>{this.checkAllServices()},this.checkInterval),this.checkAllServices()}stop(){if(this.intervalId)clearInterval(this.intervalId),this.intervalId=void 0}async checkAllServices(){let r=Array.from(this.services.entries()).map(async([i,o])=>{try{let e=await o(),n=this.healthStatus.get(i);if(this.healthStatus.set(i,e),this.lastCheck.set(i,Date.now()),n!==void 0&&n!==e)console.log(`Service ${i} status changed: ${n?"healthy":"unhealthy"} -> ${e?"healthy":"unhealthy"}`)}catch(e){this.healthStatus.set(i,!1),this.lastCheck.set(i,Date.now()),console.error(`Health check failed for ${i}:`,e)}});await Promise.allSettled(r)}getServiceHealth(r){return this.healthStatus.get(r)}getAllHealth(){return Object.fromEntries(this.healthStatus)}isServiceHealthy(r){return this.healthStatus.get(r)===!0}getLastCheckTime(r){return this.lastCheck.get(r)}}var mt=(r)=>({isSuccess:!0,isFailure:!1,value:r}),Nt=(r)=>({isSuccess:!1,isFailure:!0,error:r}),rk={map(r,i){if(r.isSuccess)return mt(i(r.value));return r},flatMap(r,i){if(r.isSuccess)return i(r.value);return r},mapError(r,i){if(r.isFailure)return Nt(i(r.error));return r},unwrap(r){if(r.isSuccess)return r.value;throw r.error},unwrapOr(r,i){if(r.isSuccess)return r.value;return i},unwrapOrElse(r,i){if(r.isSuccess)return r.value;return i(r.error)},match(r,i){if(r.isSuccess)return i.ok(r.value);return i.fail(r.error)},async fromPromise(r){try{let i=await r;return mt(i)}catch(i){return Nt(i)}},isOk(r){return r.isSuccess},isFail(r){return r.isFailure}};import{expect as Pt}from"bun:test";class j4{id;name;supportedTypes;constructor(r="mock",i="Mock Provider"){this.id=r,this.name=i,this.supportedTypes=["ALIMTALK","FRIENDTALK","SMS","LMS","MMS","NSA","VOICE","FAX","RCS_SMS","RCS_LMS","RCS_MMS","RCS_TPL","RCS_ITPL","RCS_LTPL"]}async healthCheck(){return{healthy:!0,issues:[]}}async send(r){if(r.to==="01000000000")return Nt(new q("INVALID_REQUEST","Invalid phone number"));return mt({messageId:r.messageId||`mock_${Date.now()}`,providerId:this.id,providerMessageId:`mock_${Date.now()}`,status:"SENT",type:r.type,to:r.to})}}var ok={assertKMsgError:(r,i)=>{Pt(r).toBeInstanceOf(q),Pt(r.code).toBe(i)},assertSuccess:(r)=>{if(Pt(r.isSuccess).toBe(!0),r.isSuccess)return r.value;throw Error("Expected success but got failure")},assertFailure:(r)=>{if(Pt(r.isFailure).toBe(!0),r.isFailure)return r.error;throw Error("Expected failure but got success")}};export{jU as validateProviderConfig,kU as setGlobalLogger,PU as productionConfig,mt as ok,EU as mergeConfigs,wU as loggerMiddleware,DU as logger,Pr as getLogger,Nt as fail,NU as developmentConfig,Oc as createLogger,ok as TestAssertions,P4 as SimpleHealthChecker,O4 as ServerConfigSchema,Nc as SMSConfigSchema,rr as RetryHandler,rk as Result,D4 as RedisConfigSchema,Ot as RateLimiter,m4 as QueueConfigSchema,j4 as MockProvider,w4 as LoggerConfigSchema,wl as Logger,Dl as LogLevel,nn as KMsgErrorCode,q as KMsgError,Sl as KMessageConfigSchema,mc as IWINVConfigSchema,jc as HealthMonitor,S4 as HealthConfigSchema,N4 as HealthChecker,Ec as GracefulDegradation,Pc as ErrorUtils,E4 as ErrorRecovery,k4 as DatabaseConfigSchema,Ol as ConfigLoader,St as CircuitBreaker,ml as BulkOperationHandler};
|
|
44
44
|
|
|
45
|
-
//# debugId=
|
|
45
|
+
//# debugId=3BB43D9ECEBA1A7F64756E2164756E21
|
|
46
46
|
//# sourceMappingURL=index.mjs.map
|